spring cloud gateway介紹
前段時間剛剛發布了spring boot 2正式版,spring cloud gateway基于spring boot 2,是spring cloud的全新項目,該項目提供了一個構建在spring 生態之上的api網關,包括:spring 5,spring boot 2和project reactor。 spring cloud gateway旨在提供一種簡單而有效的途徑來發送api,并為他們提供橫切關注點,例如:安全性,監控/指標和彈性。當前最新的版本是v2.0.0.m8,正式版最近也會到來。
spring cloud gateway的特征:
- java 8
- spring framework 5
- spring boot 2
- 動態路由
- 內置到spring handler映射中的路由匹配
- 基于http請求的路由匹配 (path, method, header, host, etc…?)
- 過濾器作用于匹配的路由
- 過濾器可以修改下游http請求和http響應 (add/remove headers, add/remove parameters, rewrite path, set path, hystrix, etc…?)
- 通過api或配置驅動
- 支持spring cloud discoveryclient配置路由,與服務發現與注冊配合使用
vs netflix zuul
zuul基于servlet 2.5(使用3.x),使用阻塞api。 它不支持任何長連接,如websockets。而gateway建立在spring framework 5,project reactor和spring boot 2之上,使用非阻塞api。 websockets得到支持,并且由于它與spring緊密集成,所以將會是一個更好的開發體驗。
spring cloud gateway入門實踐
筆者最近研讀了spring cloud gateway的源碼,大部分功能的實現也寫了源碼分析的文章,但畢竟正式版沒有發布,本文算是一篇入門實踐,展示常用的幾個功能,期待最近的正式版本發布。
示例啟動兩個服務:gateway-server和user-server。模擬的場景是,客戶端請求后端服務,網關提供后端服務的統一入口。后端的服務都注冊到服務發現consul(搭建zk,eureka都可以,筆者比較習慣使用consul)。網關通過負載均衡轉發到具體的后端服務。
用戶服務
用戶服務注冊到consul上,并提供一個接口/test。
依賴
需要的依賴如下:
1
2
3
4
5
6
7
8
|
<dependency> <groupid>org.springframework.cloud</groupid> <artifactid>spring-cloud-starter-consul-discovery</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency> |
配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
spring: application: name: user-service cloud: consul: host: 192.168 . 1.204 port: 8500 discovery: ip-address: ${host_address:localhost} port: ${server_port:${server.port}} healthcheckpath: /health healthcheckinterval: 15s instance-id: user-${server.port} service-name: user server: port: 8005 management: security: enabled: false |
暴露接口
1
2
3
4
5
6
7
8
9
10
11
12
|
@springbootapplication @restcontroller @enablediscoveryclient public class gatewayuserapplication { public static void main(string[] args) { springapplication.run(gatewayuserapplication. class , args); } @getmapping ( "/test" ) public string test() { return "ok" ; } } |
暴露/test接口,返回ok即可。
網關服務
網關服務提供多種路由配置、路由斷言工廠和過濾器工廠等功能。
依賴
需要引入的依賴:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-actuator</artifactid> </dependency> //依賴于webflux,必須引入 <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-webflux</artifactid> </dependency> <dependency> <groupid>org.springframework.cloud</groupid> <artifactid>spring-cloud-gateway-core</artifactid> </dependency> //服務發現組件,排除web依賴 <dependency> <groupid>org.springframework.cloud</groupid> <artifactid>spring-cloud-starter-consul-discovery</artifactid> <version> 2.0 . 0 .m6</version> <exclusions> <exclusion> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </exclusion> </exclusions> </dependency> //kotlin依賴 <dependency> <groupid>org.jetbrains.kotlin</groupid> <artifactid>kotlin-stdlib</artifactid> <version>${kotlin.version}</version> <optional> true </optional> </dependency> <dependency> <groupid>org.jetbrains.kotlin</groupid> <artifactid>kotlin-reflect</artifactid> <version>${kotlin.version}</version> <optional> true </optional> </dependency> |
如上引入了kotlin相關的依賴,這里需要支持kotlin的路由配置。spring cloud gateway的使用需要排除web相關的配置,引入的是webflux的引用,應用啟動時會檢查,必須引入。
路由斷言工廠
路由斷言工廠有多種類型,根據請求的時間、host、路徑、方法等等。如下定義的是一個基于路徑的路由斷言匹配。
1
2
3
4
5
6
7
|
@bean public routerfunction<serverresponse> testfunrouterfunction() { routerfunction<serverresponse> route = routerfunctions.route( requestpredicates.path( "/testfun" ), request -> serverresponse.ok().body(bodyinserters.fromobject( "hello" ))); return route; } |
當請求的路徑為/testfun時,直接返回ok的狀態碼,且響應體為hello字符串。
過濾器工廠
網關經常需要對路由請求進行過濾,進行一些操作,如鑒權之后構造頭部之類的,過濾的種類很多,如增加請求頭、增加請求參數、增加響應頭和斷路器等等功能。
1
2
3
4
5
6
7
8
9
10
11
12
|
@bean public routelocator customroutelocator(routelocatorbuilder builder, throttlegatewayfilterfactory throttle) { //@formatter:off return builder.routes() .route(r -> r.path( "/image/webp" ) .filters(f -> f.addresponseheader( "x-anotherheader" , "baz" )) .uri( "http://httpbin.org:80" ) ) .build(); //@formatter:on } |
如上實現了當請求路徑為/image/webp時,將請求轉發到http://httpbin.org:80,并對響應進行過濾處理,增加響應的頭部x-anotherheader: baz。
自定義路由
上面兩小節屬于api自定義路由,還可以通過配置進行定義:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
spring: cloud: gateway: locator: enabled: true default -filters: - addresponseheader=x-response- default -foo, default -bar routes: # ===================================== - id: default_path_to_http uri: blueskykong.com order: 10000 predicates: - path=/** |
如上的配置定義了路由與過濾器。全局過濾器將所有的響應加上頭部x-response-default-foo: default-bar。定義了id為default_path_to_http的路由,只是優先級比較低,當該請求都不能匹配時,將會轉發到blueskykong.com。
kotlin自定義路由
spring cloud gateway可以使用kotlin自定義路由:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@configuration class additionalroutes { @bean fun additionalroutelocator(builder: routelocatorbuilder): routelocator = builder.routes { route(id = "test-kotlin" ) { path( "/image/png" ) filters { addresponseheader( "x-testheader" , "foobar" ) } uri( "http://httpbin.org:80" ) } } } |
當請求的路徑是/image/png,將會轉發到http://httpbin.org:80,并設置了過濾器,在其響應頭中加上了x-testheader: foobar頭部。
服務發現組件
與服務注冊于發現組件進行結合,通過serviceid轉發到具體的服務實例。在前面的配置已經引入了相應的依賴。
1
2
3
4
|
@bean public routedefinitionlocator discoveryclientroutedefinitionlocator(discoveryclient discoveryclient) { return new discoveryclientroutedefinitionlocator(discoveryclient); } |
將discoveryclient注入到discoveryclientroutedefinitionlocator的構造函數中,關于該路由定義定位器,后面的源碼分析會講解,此處不展開。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
spring: cloud: gateway: locator: enabled: true default -filters: - addresponseheader=x-response- default -foo, default -bar routes: # ===================================== - id: service_to_user uri: lb: //user order: 8000 predicates: - path=/user/** filters: - stripprefix= 1 |
上面的配置開啟了discoveryclient定位器的實現。路由定義了,所有請求路徑以/user開頭的請求,都將會轉發到user服務,并應用路徑的過濾器,截取掉路徑的第一部分前綴。即訪問/user/test的實際請求轉換成了lb://user/test。
websocket
還可以配置websocket的網關路由:
1
2
3
4
5
6
7
8
9
10
11
|
spring: cloud: gateway: default -filters: - addresponseheader=x-response- default -foo, default -bar routes: - id: websocket_test uri: ws: //localhost:9000 order: 9000 predicates: - path=/echo |
啟動一個ws服務端wscat --listen 9000,將網關啟動(網關端口為9090),進行客戶端連接即可wscat --connect ws://localhost:9090/echo。
客戶端的訪問
上述實現的功能,讀者可以自行下載源碼進行嘗試。筆者這里只展示訪問用戶服務的結果:
網關成功負載均衡到user-server,并返回了ok。響應的頭部中包含了全局過濾器設置的頭部x-response-default-foo: default-bar
總結
在本文中,我們探討了屬于spring cloud gateway的一些功能和組件。 這個新的api提供了用于網關和代理支持的開箱即用工具。期待spring cloud gateway 2.0正式版。
源碼地址
https://github.com/keets2012/spring-cloud_samples
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://blueskykong.com/2018/03/10/cloud-Gateway-1/