微服務系列之-Gateway集成

一.Gateway核心概念

網關簡單的說就是提供一個對外統一的API入口和出口,統管企業對外的所有API出口。一般來說,網關對外暴露的URL或者接口信息,我們統稱之爲路由信息。如果研發過網關中間件,或者使用或瞭解過ZUUL的,網關的核心肯定是Filter以及Filter Chain(Filter責任鏈)。Spring Cloud Gateway也具有路由信息和Filter。

  1. 路由(route):
    路由網關的基本構建塊。它由一個ID、一個目的URI、一組謂詞和一組過濾器定義。如果聚合謂詞爲真,則路由匹配。

  2. 斷言(predicate):
    java 8中的斷言函數。Spring Cloud Gateway中的斷言函數輸入類型是Spring 5.0框架中的ServerWebExchange。Spring Cloud Gateway中的斷言函數允許開發者去定義匹配來自於http request中的任何信息,比如請求頭和參數等。

  3. 過濾器(filter):
    一個標準的Spring webFilter。Spring Cloud Gateway中的Filter分爲兩種類型的Filter,分別是Gateway Filter和Global Filter.網關 Filter實例是由Spring 框架中的網關Filter的特殊工廠構造。request在轉發到目前服務之前,response在返回到調用端之前都可以被修改或者自定義。

二.Gateway如何工作

客戶端向雲網關發出請求。如果網關處理程序映射確定請求與路由匹配,則將其發送到網關Web處理程序。該處理程序運行通過特定於請求的篩選器鏈發送請求。篩選器被虛線分隔的原因是,篩選器在代理請求發送之前或之後執行邏輯。執行所有預過濾器(pre)邏輯,然後進行代理請求。代理請求完成後,執行“郵政”器(post)邏輯。

在這裏插入圖片描述即在最前端,啓動一個netty server(默認端口爲8080)接受請求,然後通過Routes(每個Route由Predicate(等同於HandlerMapping)和Filter(等同於HandlerAdapter))處理後通過Netty Client發給響應的微服務。

三.Gateway集成

  1. 依賴添加
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
  1. 路由配置
spring:
  application:
    name: qygatewayserver
  cloud:
      gateway:
        locator:
          enabled: true
        routes:
        - id: qymybatisplusclient
          uri: lb://qymybatisplusclient
          predicates:
          - Path=/v1/**
          filters:
          - StripPrefix=1
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
logging:
  level:
    org.springframework.cloud.gateway: debug
    com.windmt.filter: debug
management:
  endpoints:
    web:
      exposure:
        include: "*"
  1. 啓動對應配置微服務以及Gateway
    在這裏插入圖片描述可以通過Gateway正常訪問接口。

  2. Gateway 集成Swagger
    4.1 依賴添加

       <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>guava</artifactId>
                    <groupId>com.google.guava</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>guava</artifactId>
                    <groupId>com.google.guava</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>HdrHistogram</artifactId>
                    <groupId>org.hdrhistogram</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>jsr305</artifactId>
                    <groupId>com.google.code.findbugs</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
            <exclusions>
                <exclusion>
                    <artifactId>guava</artifactId>
                    <groupId>com.google.guava</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
            <exclusions>
                <exclusion>
                    <artifactId>guava</artifactId>
                    <groupId>com.google.guava</groupId>
                </exclusion>
            </exclusions>
        </dependency>

4.2 關鍵代碼

@Override
    public List<SwaggerResource> get()
    {
        List<SwaggerResource> resources = new ArrayList<>();
        List<String> routes = new ArrayList<>();
        // 取出Spring Cloud Gateway中的route
        routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
        // 結合application.yml中的路由配置,只獲取有效的route節點
        gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId()))
                .forEach(routeDefinition -> routeDefinition.getPredicates().stream()
                        .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
                        .forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(),
                                predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX.concat("0"))
                                        .replace("/**", API_URI)))));
        return resources;
    }

具體代碼參考:謙奕爸爸-微服務集成項目

4.3 重新啓動Gateway
在這裏插入圖片描述成功獲取mybatisplus客戶端接口,並且可以 正常訪問接口。
在這裏插入圖片描述至於Gateway具體的權限管理啥的,我目前還沒有負責這塊的開發,後面自己會研究把權限、限流啥的集成到項目做範例。

具體代碼參考:謙奕爸爸-微服務集成項目

參考資源:
Spring Cloud Gateway網關實戰及原理解析

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章