簡介
-
SpringCloudGateway和SpringCloudZuul一樣是微服務網關,不過Gateway是SpringCloud官方推出的,而Zuul是Netflix推出的。
看其他人的一些文章說是Gateway是用於取代Zuul的第二代網關,這個我在官方找不到資料說明。 -
主要術語
- Route: 路由。
- Predicate: 斷言,即匹配規則。
- Filter: 過濾器,用於修改請求。
Route: Route the basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates and a collection of filters. A route is matched if aggregate predicate is true.
Predicate: This is a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange. This allows developers to match on anything from the HTTP request, such as headers or parameters.
Filter: These are instances Spring Framework GatewayFilter constructed in with a specific factory. Here, requests and responses can be modified before or after sending the downstream request.
- 功能實現流程
以下示例均基於SpringCloud的Greenwich.SR1版本,且需要依賴到之前介紹SpringCloud相關的文章
基礎依賴
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>*</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
這裏有一點要說明一下,因爲父模塊中有spring-boot-starter-web
的依賴,而SpringCloudGateway還不支持spring-boot-starter-web
,所以需要先把依賴排除。
否則啓動會出現以下錯誤:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method modifyRequestBodyGatewayFilterFactory in org.springframework.cloud.gateway.config.GatewayAutoConfiguration required a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' in your configuration.
GatewayServer
啓動Gateway很簡單,只需要一個啓動簡單的SpringBoot應用就可以。
@SpringBootApplication
class GatewayServerStarter
fun main(args: Array<String>) {
runApplication<GatewayServerStarter>(*args)
}
配置Gateway可以使用application.yml
來配置,也可以從代碼層面去配置。
如果是用配置文件的方式去配置的話,即用一下的方式去配置路由。
server:
port: 6609
spring:
application:
name: gateway-server
cloud:
gateway:
routes:
- id: # 路由的標識
- uri: # 轉發的地址
- predicates: # 指定斷句
- filters: # 指定過濾器
用過是代碼的方式,則以新建一個RouteLocator的Bean來實現。
@Configuration
class GatewayConfiguration {
@Bean
fun routes(builder: RouteLocatorBuilder): RouteLocator {
return builder.routes()
.route {
it.predicate { p -> p.request.queryParams["name"]?.get(0) == "czb1n" }
.filters { f -> f.addRequestHeader("Name", "czb1n") }
.uri("http://httpbin.org:80")
}
.route {
it.path("/get")
.uri("http://httpbin.org:80")
}
.build()
}
}
啓動之後,訪問http://localhost:6609/get
就會根據第二條轉發規則,轉發至http://httpbin.org:80
,頁面會顯示以下結果。
{
"args": {},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cache-Control": "max-age=0",
"Cookie": "Hm_lvt_a14b0dbc71bff63c2370f65118b12426=1552964642,1553068348,1553132391,1554186102; Hm_lpvt_a14b0dbc71bff63c2370f65118b12426=1554278774",
"Forwarded": "proto=http;host=\"localhost:6609\";for=\"0:0:0:0:0:0:0:1:53856\"",
"Host": "httpbin.org",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36",
"X-Forwarded-Host": "localhost:6609"
},
"origin": "0:0:0:0:0:0:0:1, ::1",
"url": "https://localhost:6609/get"
}
訪問http://localhost:6609/get?name=czb1n
會匹配第一條規則,也會轉發至http://httpbin.org:80
,但是不會匹配到第二條規則。
原因是因爲規則是從上往下匹配的,只會匹配到符合的第一條規則。
頁面會顯示結果。
{
"args": {
"name": "czb1n"
},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Cookie": "Hm_lvt_a14b0dbc71bff63c2370f65118b12426=1552964642,1553068348,1553132391,1554186102; Hm_lpvt_a14b0dbc71bff63c2370f65118b12426=1554278774",
"Forwarded": "proto=http;host=\"localhost:6609\";for=\"0:0:0:0:0:0:0:1:53856\"",
"Host": "httpbin.org",
"Name": "czb1n",
"Purpose": "prefetch",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36",
"X-Forwarded-Host": "localhost:6609"
},
"origin": "0:0:0:0:0:0:0:1, ::1",
"url": "https://localhost:6609/get?name=czb1n"
}
Filter會在轉發請求的headers上添加上"Name": "czb1n"
。
其他
示例代碼地址: https://github.com/czb1n/learn-spring-cloud-with-kotlin