Spring Cloud Gateway入門解讀
Spring Cloud Gateway介紹
前段時(shí)間剛剛發(fā)布了Spring Boot 2正式版,Spring Cloud Gateway基于Spring Boot 2,是Spring Cloud的全新項(xiàng)目,該項(xiàng)目提供了一個(gè)構(gòu)建在Spring 生態(tài)之上的API網(wǎng)關(guān),包括:Spring 5,Spring Boot 2和Project Reactor。 Spring Cloud Gateway旨在提供一種簡(jiǎn)單而有效的途徑來(lái)發(fā)送API,并為他們提供橫切關(guān)注點(diǎn),例如:安全性,監(jiān)控/指標(biāo)和彈性。當(dāng)前最新的版本是v2.0.0.M8,正式版最近也會(huì)到來(lái)。
Spring Cloud Gateway的特征:
- Java 8
- Spring Framework 5
- Spring Boot 2
- 動(dòng)態(tài)路由
- 內(nèi)置到Spring Handler映射中的路由匹配
- 基于HTTP請(qǐng)求的路由匹配 (Path, Method, Header, Host, etc…)
- 過(guò)濾器作用于匹配的路由
- 過(guò)濾器可以修改下游HTTP請(qǐng)求和HTTP響應(yīng) (Add/Remove Headers, Add/Remove Parameters, Rewrite Path, Set Path, Hystrix, etc…)
- 通過(guò)API或配置驅(qū)動(dòng)
- 支持Spring Cloud DiscoveryClient配置路由,與服務(wù)發(fā)現(xiàn)與注冊(cè)配合使用
vs Netflix Zuul
Zuul基于servlet 2.5(使用3.x),使用阻塞API。 它不支持任何長(zhǎng)連接,如websockets。而Gateway建立在Spring Framework 5,Project Reactor和Spring Boot 2之上,使用非阻塞API。 Websockets得到支持,并且由于它與Spring緊密集成,所以將會(huì)是一個(gè)更好的開(kāi)發(fā)體驗(yàn)。
Spring Cloud Gateway入門實(shí)踐
筆者最近研讀了Spring Cloud Gateway的源碼,大部分功能的實(shí)現(xiàn)也寫(xiě)了源碼分析的文章,但畢竟正式版沒(méi)有發(fā)布,本文算是一篇入門實(shí)踐,展示常用的幾個(gè)功能,期待最近的正式版本發(fā)布。
示例啟動(dòng)兩個(gè)服務(wù):Gateway-Server和user-Server。模擬的場(chǎng)景是,客戶端請(qǐng)求后端服務(wù),網(wǎng)關(guān)提供后端服務(wù)的統(tǒng)一入口。后端的服務(wù)都注冊(cè)到服務(wù)發(fā)現(xiàn)Consul(搭建zk,Eureka都可以,筆者比較習(xí)慣使用consul)。網(wǎng)關(guān)通過(guò)負(fù)載均衡轉(zhuǎn)發(fā)到具體的后端服務(wù)。
用戶服務(wù)
用戶服務(wù)注冊(cè)到Consul上,并提供一個(gè)接口/test。
依賴
需要的依賴如下:
<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>
配置文件
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
暴露接口
@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即可。
網(wǎng)關(guān)服務(wù)
網(wǎng)關(guān)服務(wù)提供多種路由配置、路由斷言工廠和過(guò)濾器工廠等功能。
依賴
需要引入的依賴:
<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> //服務(wù)發(fā)現(xiàn)組件,排除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相關(guān)的依賴,這里需要支持kotlin的路由配置。Spring Cloud Gateway的使用需要排除web相關(guān)的配置,引入的是webflux的引用,應(yīng)用啟動(dòng)時(shí)會(huì)檢查,必須引入。
路由斷言工廠
路由斷言工廠有多種類型,根據(jù)請(qǐng)求的時(shí)間、host、路徑、方法等等。如下定義的是一個(gè)基于路徑的路由斷言匹配。
@Bean public RouterFunction<ServerResponse> testFunRouterFunction() { RouterFunction<ServerResponse> route = RouterFunctions.route( RequestPredicates.path("/testfun"), request -> ServerResponse.ok().body(BodyInserters.fromObject("hello"))); return route; }
當(dāng)請(qǐng)求的路徑為/testfun時(shí),直接返回ok的狀態(tài)碼,且響應(yīng)體為hello字符串。
過(guò)濾器工廠
網(wǎng)關(guān)經(jīng)常需要對(duì)路由請(qǐng)求進(jìn)行過(guò)濾,進(jìn)行一些操作,如鑒權(quán)之后構(gòu)造頭部之類的,過(guò)濾的種類很多,如增加請(qǐng)求頭、增加請(qǐng)求參數(shù)、增加響應(yīng)頭和斷路器等等功能。
@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 }
如上實(shí)現(xiàn)了當(dāng)請(qǐng)求路徑為/image/webp時(shí),將請(qǐng)求轉(zhuǎn)發(fā)到http://httpbin.org:80,并對(duì)響應(yīng)進(jìn)行過(guò)濾處理,增加響應(yīng)的頭部X-AnotherHeader: baz。
自定義路由
上面兩小節(jié)屬于API自定義路由,還可以通過(guò)配置進(jìn)行定義:
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=/**
如上的配置定義了路由與過(guò)濾器。全局過(guò)濾器將所有的響應(yīng)加上頭部X-Response-Default-Foo: Default-Bar。定義了id為default_path_to_http的路由,只是優(yōu)先級(jí)比較低,當(dāng)該請(qǐng)求都不能匹配時(shí),將會(huì)轉(zhuǎn)發(fā)到blueskykong.com。
kotlin自定義路由
Spring Cloud Gateway可以使用kotlin自定義路由:
@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") } } }
當(dāng)請(qǐng)求的路徑是/image/png,將會(huì)轉(zhuǎn)發(fā)到http://httpbin.org:80,并設(shè)置了過(guò)濾器,在其響應(yīng)頭中加上了X-TestHeader: foobar頭部。
服務(wù)發(fā)現(xiàn)組件
與服務(wù)注冊(cè)于發(fā)現(xiàn)組件進(jìn)行結(jié)合,通過(guò)serviceId轉(zhuǎn)發(fā)到具體的服務(wù)實(shí)例。在前面的配置已經(jīng)引入了相應(yīng)的依賴。
@Bean public RouteDefinitionLocator discoveryClientRouteDefinitionLocator(DiscoveryClient discoveryClient) { return new DiscoveryClientRouteDefinitionLocator(discoveryClient); }
將DiscoveryClient注入到DiscoveryClientRouteDefinitionLocator的構(gòu)造函數(shù)中,關(guān)于該路由定義定位器,后面的源碼分析會(huì)講解,此處不展開(kāi)。
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
上面的配置開(kāi)啟了DiscoveryClient定位器的實(shí)現(xiàn)。路由定義了,所有請(qǐng)求路徑以/user開(kāi)頭的請(qǐng)求,都將會(huì)轉(zhuǎn)發(fā)到user服務(wù),并應(yīng)用路徑的過(guò)濾器,截取掉路徑的第一部分前綴。即訪問(wèn)/user/test的實(shí)際請(qǐng)求轉(zhuǎn)換成了lb://user/test。
websocket
還可以配置websocket的網(wǎng)關(guān)路由:
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
啟動(dòng)一個(gè)ws服務(wù)端wscat --listen 9000,將網(wǎng)關(guān)啟動(dòng)(網(wǎng)關(guān)端口為9090),進(jìn)行客戶端連接即可wscat --connect ws://localhost:9090/echo。
客戶端的訪問(wèn)
上述實(shí)現(xiàn)的功能,讀者可以自行下載源碼進(jìn)行嘗試。筆者這里只展示訪問(wèn)用戶服務(wù)的結(jié)果:
網(wǎng)關(guān)成功負(fù)載均衡到user-server,并返回了ok。響應(yīng)的頭部中包含了全局過(guò)濾器設(shè)置的頭部X-Response-Default-Foo: Default-Bar
總結(jié)
在本文中,我們探討了屬于Spring Cloud Gateway的一些功能和組件。 這個(gè)新的API提供了用于網(wǎng)關(guān)和代理支持的開(kāi)箱即用工具。期待Spring Cloud Gateway 2.0正式版。
源碼地址
https://github.com/keets2012/Spring-Cloud_Samples
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
jvm之java類加載機(jī)制和類加載器(ClassLoader)的用法
這篇文章主要介紹了jvm之java類加載機(jī)制和類加載器(ClassLoader)的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09Java封裝的實(shí)現(xiàn)訪問(wèn)限定符、包
封裝就是將數(shù)據(jù)和操作數(shù)據(jù)的方法進(jìn)行有機(jī)結(jié)合,隱藏對(duì)象的屬性(成員變量)和實(shí)現(xiàn)細(xì)節(jié),僅對(duì)外公開(kāi)接口來(lái)和對(duì)象進(jìn)行交互,下面這篇文章主要給大家介紹了關(guān)于Java封裝實(shí)現(xiàn)訪問(wèn)限定符、包的相關(guān)資料2022-08-08SpringBoot+Spring Security無(wú)法實(shí)現(xiàn)跨域的解決方案
這篇文章主要介紹了SpringBoot+Spring Security無(wú)法實(shí)現(xiàn)跨域的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Java線程創(chuàng)建(賣票),線程同步(賣包子)的實(shí)現(xiàn)示例
這篇文章主要介紹了Java線程創(chuàng)建(賣票),線程同步(賣包子)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05Kotlin基礎(chǔ)教程之dataclass,objectclass,use函數(shù),類擴(kuò)展,socket
這篇文章主要介紹了Kotlin基礎(chǔ)教程之dataclass,objectclass,use函數(shù),類擴(kuò)展,socket的相關(guān)資料,需要的朋友可以參考下2017-05-05