一、maven依赖
1、网关依赖(此处注册中心采用nacos)
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.1.RELEASE</version>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
2、swagger2依赖
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>swagger-bootstrap-ui</artifactId> <version>1.9.6</version> </dependency>
二、网关配置文件
bootstrap.yml文件
spring: application: name: gateway profiles: active: local # 开启 Gateway 服务注册中心服务发现 cloud: gateway: discovery: locator: enabled: on #使用服务名称的小写(服务名称不能带下划线) lower-case-service-id: on nacos: config: #配置文件后缀名 file-extension: yaml refresh-enabled: true #允许覆盖已经存在的同名bean main: allow-bean-definition-overriding: true
bootstrap-local.yml文件
server: port: 8081 spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 config: server-addr: 127.0.0.1:8848 group: local log: level: INFO #日志保存时间(天) maxHistory: 2 #每个日志文件的大小 maxSize: 10MB
logback-spring.xml文件(logback文件)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <configuration> 3 <springProperty scope="context" name="loglevel" source="log.level"/> 4 <springProperty scope="context" name="maxHistory" source="log.maxHistory"/> 5 <springProperty scope="context" name="maxSize" source="log.maxSize"/> 6 <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 7 <encoder> 8 <pattern>%d{yyyy-MM-dd HH:mm:ss}[%level][%thread][%logger]-%msg%n</pattern> 9 <charset>UTF-8</charset> 10 </encoder> 11 </appender> 12 <!-- Perf4J logger Appender --> 13 <appender name="DailyAndSizeRollAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> 14 <file>logs/gateway.log</file> 15 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 16 <!-- rollover daily --> 17 <fileNamePattern>logs/lt_gateway.%i.%d{yyyy-MM-dd}.log.zip</fileNamePattern> 18 <timeBasedFileNamingAndTriggeringPolicy 19 class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> 20 <!-- or whenever the file size reaches 200MB --> 21 <maxFileSize>${maxSize}</maxFileSize> 22 </timeBasedFileNamingAndTriggeringPolicy> 23 <maxHistory>${maxHistory}</maxHistory> 24 </rollingPolicy> 25 <encoder> 26 <pattern>%d{yyyy-MM-dd HH:mm:ss}[%level][%thread][%logger]-%msg%n</pattern> 27 <charset>UTF-8</charset> 28 </encoder> 29 </appender> 30 <appender name="logApiAccess" class="ch.qos.logback.core.rolling.RollingFileAppender"> 31 <file>logs/api_access/access.log</file> 32 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 33 <!-- rollover daily --> 34 <fileNamePattern>logs/api_access/access.log.%i.%d{yyyy-MM-dd}.log.zip 35 </fileNamePattern> 36 <timeBasedFileNamingAndTriggeringPolicy 37 class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> 38 <!-- or whenever the file size reaches 200MB --> 39 <maxFileSize>200MB</maxFileSize> 40 </timeBasedFileNamingAndTriggeringPolicy> 41 <maxHistory>7</maxHistory> 42 </rollingPolicy> 43 <encoder> 44 <pattern>%msg%n</pattern> 45 </encoder> 46 </appender> 47 <!--监控指定的日志类 并输出到指定的文件中--> 48 <logger name="com.xx.xx.LogApiAccessUtil" level="${loglevel}"> 49 <appender-ref ref="logApiAccess"/> 50 </logger> 51 <root level="${loglevel}"> 52 <appender-ref ref="STDOUT"/> 53 <appender-ref ref="DailyAndSizeRollAppender"/> 54 </root> 55 </configuration>
三、swagger2配置类
1、获取不同微服务的提供者
1 public static final String SWAGGER2URL = "/v2/api-docs"; 2 private final RouteLocator routeLocator; 3
4 @Value("${spring.application.name}") 5 private String self; 6
7 public SwaggerConfig(RouteLocator routeLocator) { 8 this.routeLocator = routeLocator; 9 } 10
11 @Override 12 public List<SwaggerResource> get() { 13 List<SwaggerResource> resources = new ArrayList<>(); 14 List<String> routeHosts = new ArrayList<>(); 15 // 由于我的网关采用的是负载均衡的方式,因此我需要拿到所有应用的serviceId 16 // 获取所有可用的host:serviceId
17 routeLocator.getRoutes().filter(route -> route.getUri().getHost() != null) 18 .filter(route -> !self.equals(route.getUri().getHost())) 19 .subscribe(route -> routeHosts.add(route.getUri().getHost())); 20
21 // 记录已经添加过的server,存在同一个应用注册了多个服务在nacos上
22 Set<String> dealed = new HashSet<>(); 23 routeHosts.forEach(instance -> { 24 // 拼接url,样式为/serviceId/v2/api-info,当网关调用这个接口时,会自动通过负载均衡寻找对应的主机
25 String url = "/" + instance + SWAGGER2URL; 26 if (!dealed.contains(url)) { 27 dealed.add(url); 28 SwaggerResource swaggerResource = new SwaggerResource(); 29 swaggerResource.setUrl(url); 30 swaggerResource.setName(instance); 31 resources.add(swaggerResource); 32 } 33 }); 34 return resources; 35 }
2、聚合接口类

1 @RestController 2 public class SwaggerHandler { 3 4 @Autowired(required = false) 5 private SecurityConfiguration securityConfiguration; 6 7 @Autowired(required = false) 8 private UiConfiguration uiConfiguration; 9 10 private final SwaggerResourcesProvider swaggerResources; 11 12 @Autowired 13 public SwaggerHandler(SwaggerResourcesProvider swaggerResources) { 14 this.swaggerResources = swaggerResources; 15 } 16 17 @GetMapping("/swagger-resources/configuration/security") 18 public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() { 19 return Mono.just(new ResponseEntity<>( 20 Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK)); 21 } 22 23 @GetMapping("/swagger-resources/configuration/ui") 24 public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() { 25 return Mono.just(new ResponseEntity<>( 26 Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK)); 27 } 28 29 @GetMapping("/swagger-resources") 30 public Mono<ResponseEntity> swaggerResources() { 31 return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK))); 32 } 33 34 @GetMapping("/") 35 public Mono<ResponseEntity> swaggerResourcesN() { 36 return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK))); 37 } 38 39 @GetMapping("/csrf") 40 public Mono<ResponseEntity> swaggerResourcesCsrf() { 41 return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK))); 42 }
3、解决访问/v2/api/docs 404的问题
@Component public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory { @Override public GatewayFilter apply(Object config) { return (exchange, chain) -> { ServerHttpRequest request = exchange.getRequest(); String path = request.getURI().getPath(); if (!StringUtils.endsWithIgnoreCase(path, SwaggerConfig.SWAGGER2URL)) { return chain.filter(exchange); } ServerHttpRequest newRequest = request.mutate().build(); ServerWebExchange newExchange = exchange.mutate().request(newRequest).build(); return chain.filter(newExchange); }; } }
四、微服务的相关配置
1、maven依赖
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2.2.1.RELEASE</version> <exclusions> <exclusion> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>2.2.1.RELEASE</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.swagger</groupId> <artifactId>swagger-annotations</artifactId> <version>1.5.21</version> </dependency> <dependency> <groupId>io.swagger</groupId> <artifactId>swagger-models</artifactId> <version>1.5.21</version> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>swagger-bootstrap-ui</artifactId> <version>1.9.6</version> </dependency>
2、配置文件
bootstrap.yml文件
spring: application: name: dcjcgl profiles: active: local jackson: time-zone: GMT+8 date-format: yyyy-MM-dd HH:mm:ss servlet: multipart: #单文件大小 max-file-size: 512MB #总上传文件大小 max-request-size: 512MB enabled: true file-size-threshold: 0 cloud: nacos: config: #配置文件后缀名 file-extension: yaml refresh-enabled: true #允许覆盖已经存在的同名bean main: allow-bean-definition-overriding: true
bootstrap-local.yml文件
server: port: 8083 spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 config: server-addr: 127.0.0.1:8848 group: local #日志配置 log: level: INFO #日志保存时间(天) maxHistory: 2 #每个日志文件的大小 maxSize: 10MB
3、配置类
@Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket docket(){ return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.xx.xx.web")) .paths(PathSelectors.any()) .build(); } public ApiInfo apiInfo(){ return new ApiInfoBuilder() .title("xx模块相关接口") .description("用restful风格写接口") .termsOfServiceUrl("") .version("1.0") .build(); }
4、访问地址
http://127.0.0.1:8080/doc.html