current position:Home>Spring Cloud Gateway integrates Nacos and Swagger to aggregate Api documents

Spring Cloud Gateway integrates Nacos and Swagger to aggregate Api documents

2022-08-06 17:26:59Integer_Double

一、Gateway服务网关

1.1 什么是网关

Also known as service gatewayAPI网关,是系统对外的唯一入口,It encapsulates the internal architecture of the system.All clients and consumers,All access microservices through gateways,Handle non-business logic at the gateway layer.APIGateways are not required components in microservice scenarios,There is no gateway as shown in the figure,Microservices can also provide external services
在这里插入图片描述
However, the number of corresponding microservices is large,systems with high complexity,Using a gateway can bring some benefits

  • 聚合接口,Make the service transparent to the researcher,Reduce the coupling between client and server
  • 聚合后台服务,节省流量,提升用户体验
  • 提供安全,流量控制、API监控、计费等功能

1.2 Spring Cloud Gateway

Spring Cloud Gateway做Spring Cloud生态系统中的网关,目标是替代Netflix Zuul,它不仅提供统一的路由方式,并且基于Filter链的方式提供了网关的基本功能.Aims to provide a simple and somewhat simple way to route toAPI.使用Spring Cloud Gateway有如下优点

  • The client only interacts with the gateway,Reduce client complexity
  • Resolved crossover issues for specific scenarios
  • 集成actuator,Perform monitoring and health checks
  • 集成Hystrix,Perform service fuse and current limiting

解决的问题:
在这里插入图片描述

1.3 其他

In addition to the above functions, the gateway,You can also do the following functions

  • 统一的安全认证(token验证),使用全局过滤器
  • Verification code generation and verification、短信验证码认证,Use custom endpoints(RouterFunctions)免校验
  • Swagger的Api文档聚合,集成Swagger,过滤Swaggerendpoint for processing
  • Configuration information that does not require authentication,Validation-free with custom endpoints

二、Gateway环境与配置

2.1 pom.xml

All versions of this block are defined in the parent project

  • SpringBoot 2.6.5
  • SpringCloud 2021.0.1
  • SpringCloudAlibaba 2021.0.1.0

2.1.1 gateway

gateway依赖了swagger和openfeign,These two are individually packaged into a common package for ease of use.Learning on your own can come together,先看gateway的pom.xml

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>
        <!--添加bootstrap的依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        <!--gateway 网关依赖,内置webflux 依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
        <!--swagger的依赖-->
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>mms-common-swagger</artifactId>
        </dependency>
         <!--openfeign的依赖-->
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>mms-common-openfeign</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

2.1.2 sawgger

swaggerThe use was mentioned earlierSpringBoot2.6.5集成Swagger3和Knife3,Just use the same dependencies,替换上面的mms-common-openfeign

2.1.3 openfeign

替换上面的mms-common-swagger

    <!--feign服务间调用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--注册中心客户端-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--配置中心客户端-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!--客户端负载均衡策略,替换原来的Ribbon-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>

2.2 bootstrap.yml

server:
  port: 8081

logging:
  level:
    com.alibaba.nacos.client.config.impl: ERROR

management:
  endpoints:
    web:
      exposure:
        include: "health,prometheus"
  endpoint:
    health:
      show-details: always
  metrics:
    tags:
      application: ${
    spring.application.name}

spring:
  application:
    name: gateway-center
  #设置Web模式为reactive
  main:
    web-application-type: reactive
  cloud:
    nacos:
      discovery:
        namespace: 7d720891-624c-4677-90fe-9004a3f73888
        server-addr: http://192.168.136.133:8848
        file-extension: yml
        # Nacos Configuration is required when the service enables authentication
        # username: 
        # password: 
        # context-path: nacos
      config:
        namespace: 7d720891-624c-4677-90fe-9004a3f73888
        server-addr: http://192.168.136.133:8848
        file-extension: yml
        # 读取Nacos配置时间(默认3000,单位:毫秒)
        # timeout: 3000
        # Nacos Configuration is required when the service enables authentication
        # username: 
        # password: 
        # context-path: nacos
  gateway:
    authCenter: user-center
    authCenterUrl: /token/check
    routes:
      - id: user
        uri: lb://user-center
        auth: true
        predicates:
          - Path=/user/**
        filters:
          #使用StripPrefixGatewayFilterFactorysplit routing,1代表分割1截.作用是将/user去掉
          - StripPrefix=1
          #使用自定义的
          - ValidateCode=true
        urls:
          - pattern: /user/oauth/**
          - pattern: /user/token/logout
      - id: admin
        uri: lb://admin-service
        auth: true
        predicates:
          - Path=/admin/**
        filters:
          - StripPrefix=1

swagger:
  title: mms cloud API
  license:  Powered By yex
  licenseUrl: https://demo.com/
  terms-of-service-url: https://demo.com/
  contact:
   email: [email protected]
   url: https://demo.com/about.html
  authorization:
    name: auth-center
    auth-regex: ^.*$
    authorization-scope-list:
      - scope: server
        description: server all
    token-url-list:
      - http://${
    GATEWAY-HOST:gateway-center}:${
    GATEWAY-PORT:8081}/auth/oauth/token

三、Swagger聚合配置

聚合ApiDocumentation is where other microservices goapiDocument addresses combined,Forms a drop-down selection.Start the gateway and user center to see the effect
在这里插入图片描述

3.1 SwaggerProviderConfig

用于读取gatewayrouting configuration information,封装成SwaggerResource,这些信息会在/doc.html页面展示

@Slf4j
@Primary
@Component
public class SwaggerProviderConfig implements SwaggerResourcesProvider {
    

    public static final String API_URI = "/v3/api-docs";

    @Autowired
    private SwaggerProperties swaggerProperties;

    @Autowired
    private GatewayProperties gatewayProperties;

    @Override
    public List<SwaggerResource> get() {
    
        List<SwaggerResource> resources = new ArrayList<>();
        Set<String> strings = new HashSet<>();// 记录已经添加过的server
        gatewayProperties.getRoutes().stream()
                .filter(routeDefinition -> !swaggerProperties.getIgnoreProviders().contains(routeDefinition.getUri().getHost()))
                .forEach(routeDefinition -> {
    
                            String url = "/" + routeDefinition.getId() + API_URI;// 拼接url
                            if (!strings.contains(url)) {
    
                                strings.add(url);
                                SwaggerResource swaggerResource = new SwaggerResource();
                                swaggerResource.setUrl(url);///Set up service documentationuser-center/v3/api-docs
                                swaggerResource.setName(routeDefinition.getUri().getHost());//设置服务名user-center
                                swaggerResource.setSwaggerVersion("3.0");
                                resources.add(swaggerResource);
                            }
                        }
                );
        return resources;
    }
}

3.2 RouterFunctionConfiguration

gateway使用的webflux,不支持webmvc.对swaggerRoute add handler,to handle interface requests

@Slf4j
@Configuration
@AllArgsConstructor
public class RouterFunctionConfiguration {
    

    private final HystrixFallbackHandler hystrixFallbackHandler
    private final SwaggerSecurityHandler swaggerSecurityHandler;
    private final SwaggerUiHandler swaggerUiHandler;
    private final SwaggerResourceHandler swaggerResourceHandler;

    @Bean
    public RouterFunction routerFunction() {
    
        return RouterFunctions.route(
                RequestPredicates.path("/fallback")
                        .and(RequestPredicates.accept(MediaType.APPLICATION_JSON)), hystrixFallbackHandler)
                .andRoute(RequestPredicates.GET("/swagger-resources")
                        .and(RequestPredicates.accept(MediaType.ALL)), swaggerResourceHandler)
                .andRoute(RequestPredicates.GET("/swagger-resources/configuration/ui")
                        .and(RequestPredicates.accept(MediaType.ALL)), swaggerUiHandler)
                .andRoute(RequestPredicates.GET("/swagger-resources/configuration/security")
                        .and(RequestPredicates.accept(MediaType.ALL)), swaggerSecurityHandler);
    }

}

3.3 SwaggerResourceHandler

@Slf4j
@Component
@AllArgsConstructor
public class SwaggerResourceHandler implements HandlerFunction<ServerResponse> {
    
    private final SwaggerResourcesProvider swaggerResources;

    /** * Handle the given request. * * @param request the request to handler * @return the response */
    @Override
    public Mono<ServerResponse> handle(ServerRequest request) {
    
        return ServerResponse.status(HttpStatus.OK)
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(swaggerResources.get()));
    }
}

3.4 SwaggerSecurityHandler

@Slf4j
@Component
public class SwaggerSecurityHandler implements HandlerFunction<ServerResponse> {
    
    @Autowired(required = false)
    private SecurityConfiguration securityConfiguration;

    /** * Handle the given request. * * @param request the request to handler * @return the response */
    @Override
    public Mono<ServerResponse> handle(ServerRequest request) {
    
        return ServerResponse.status(HttpStatus.OK)
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(
                        Optional.ofNullable(securityConfiguration)
                                .orElse(SecurityConfigurationBuilder.builder().build())));
    }
}

3.5 SwaggerUiHandler

@Slf4j
@Component
public class SwaggerUiHandler implements HandlerFunction<ServerResponse> {
    

    @Autowired(required = false)
    private UiConfiguration uiConfiguration;

    /** * Handle the given request. * * @param request the request to handler * @return the response */
    @Override
    public Mono<ServerResponse> handle(ServerRequest request) {
    
        return ServerResponse.status(HttpStatus.OK)
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(
                        Optional.ofNullable(uiConfiguration)
                                .orElse(UiConfigurationBuilder.builder().build())));
    }
}

四、遇到的问题

4.1 webflux与mvc不兼容

webflux与mvcIncompatibility can cause various problems
解决方法一:
在依赖中排除MVC相关的jar包

<!--spring cloud gateway是基于webflux的,与web不兼容-->
<exclusions>
    <exclusion>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </exclusion>
</exclusions>

排除spring-boot-starter-webAfter that, it may cause some classes to not find an error,For example I use hereCommonResponseDataAdvice implements ResponseBodyAdviceDo global return value processing,就报ResponseBodyAdvice找不到.排除了CommonResponseDataAdvice 都不行
解决方法二:
Add the following configuration to the configuration file

spring: 
  #设置Web模式为reactive
  main:
    web-application-type: reactive

使用方案二,完美解决.

4.2 swagger异常

swaggerThe document can't come out,f12发现/v3/api-docs报错,检查SwaggerProviderConfig的配置,一般是url配错.It can be solved by repeated debugging

copyright notice
author[Integer_Double],Please bring the original link to reprint, thank you.
https://en.cdmana.com/2022/218/202208061703262653.html

Random recommended