之前做的项目中前后端完全分离,前端为嵌在手机app中的H5,后端需求限定了语言为Java,而且所给的时间非常少。
于是能够快速搭建配置部署的Spring Boot项目就成了不二之选,加上Swagger2能够方便的帮助我们构建出功能强大的在线接口文档,方便测试人员对接口的测试和前端的对接。所以直接选用了Spring Boot + Swagger2的方案。
简单介绍下项目吧
需求中需要每日解析百万级的历史数据和百万级的实时数据接收+计算,因此也面临着很大的性能压力。
最后总体后端的技术方案和架构为
技术选型为
Spring Boot +Swagger + mybaties + Jwt + RabbitMQ + haproxy + redis(这个最后没用上)
架构为
1.3台接口服务器(其中1台负责历史数据解析(.vm文件),这个一般每天会有100M-200M左右的数据量,几百万条数据,正常是在十几分钟内能解析持久化完毕)。
2.1台负责负载均衡3台接口服务器的haproxy服务器。
3.3台RabbitMQ服务器,构建了一个镜像集群 这个之间有写过
3.3台MQ消费者(也是Spring Boot项目)服务器,分别部署了一个消费者项目,虽然实际测试在日均50-100W条数据时一台消费者也能完成实时数据的解析计算入库。考虑到节假日可能会出现的波峰还是预设了多台。
4.1台负责负载均衡3台MQ服务器的haproxy服务器。
5.1台redis缓存服务器,不过最后由于没啥压力就没有真的投入使用,作为之后压力增大后的预备吧。
6.2台my sql数据库服务器,虽然超过百万级的数据my sql跑起来会比不上sql server和oracle,不过上头要用这个,我才不会说是因为免费呢。_(:з」∠*)_
虽然最后只用了一台就成功承受住了压力就是了(笑)
7.1台文件服务器,用来存放每天的历史数据,每天会从数据提供者那边自动获取数据文件(.vm)然后上面提到的1台接口服务器会进行解析入库。
中间还因为奇葩要求用到了一堆东西,比如JavaMail,sftp,ssh,shell脚本等等
好像有点偏题了,嘛,先来看下完成时的在线文档说明界面吧
然后开始搭建一个Spring Boot + Swagger2的例子吧
1.新建一个Spring Boot项目。
pom.xml
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.5.0</version>
</dependency>
整体项目目录结构
整体搭建非常简单易懂
Swagger2TestApplication.java
package com.my.swagger2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.Api;
@SpringBootApplication
@Api(value = "springboot服务",description="简单的计算服务API")
@RestController
public class Swagger2TestApplication {
public static void main(String[] args) {
SpringApplication.run(Swagger2TestApplication.class, args);
}
}
Swagger2.java
SWAGGER_SCAN_BASE_PACKAGE 就是swagger2会扫描到的目录。
package com.my.swagger2.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class Swagger2 {
public static final String SWAGGER_SCAN_BASE_PACKAGE = "com.my.swagger2.controller";
public static final String VERSION = "1.0.0";
@Bean
public Docket CreateRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage(SWAGGER_SCAN_BASE_PACKAGE))
.paths(PathSelectors.any())
.build();
}
ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Api")
.description("my api test")
.termsOfServiceUrl("https://blog.csdn.net/yeyinglingfeng")
.contact("yeyinglingfeng")
.version(VERSION)
.build();
}
}
myTestController.java
接口
可以看到ApiImplicitParam
为接口参数
多个时以,
分隔,最后一个后面不加,
如果加上required = true
就表示该参数为必填项
package com.my.swagger2.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
@RestController
@RequestMapping(value="/api")
public class myTestController {
@ApiOperation(value="测试数据", notes="获取字符串1+字符串2")
@ApiImplicitParams({
@ApiImplicitParam(name = "s1", value = "字符串1", paramType = "form", dataType = "String"),
@ApiImplicitParam(name = "s2", value = "字符串2", paramType = "form",required = true, dataType = "String")
})
@RequestMapping(value="/get/info", method=RequestMethod.POST)
public String getInfo(HttpServletResponse response,HttpServletRequest request) {
String s1 = request.getParameter("s1");
String s2 = request.getParameter("s2");
String result = s1+s2;
return result;
}
}
这样就配置好了,来试下,启动项目
访问http://localhost:8080/swagger-ui.html#!/
可以看到添加了required = true
的样子
测试下
结果