一.Gateway核心概念
網關簡單的說就是提供一個對外統一的API入口和出口,統管企業對外的所有API出口。一般來說,網關對外暴露的URL或者接口信息,我們統稱之爲路由信息。如果研發過網關中間件,或者使用或瞭解過ZUUL的,網關的核心肯定是Filter以及Filter Chain(Filter責任鏈)。Spring Cloud Gateway也具有路由信息和Filter。
-
路由(route):
路由網關的基本構建塊。它由一個ID、一個目的URI、一組謂詞和一組過濾器定義。如果聚合謂詞爲真,則路由匹配。 -
斷言(predicate):
java 8中的斷言函數。Spring Cloud Gateway中的斷言函數輸入類型是Spring 5.0框架中的ServerWebExchange。Spring Cloud Gateway中的斷言函數允許開發者去定義匹配來自於http request中的任何信息,比如請求頭和參數等。 -
過濾器(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集成
- 依賴添加
<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>
- 路由配置
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: "*"
-
啓動對應配置微服務以及Gateway
可以通過Gateway正常訪問接口。 -
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具體的權限管理啥的,我目前還沒有負責這塊的開發,後面自己會研究把權限、限流啥的集成到項目做範例。
具體代碼參考:謙奕爸爸-微服務集成項目