在上一篇文章Spring Cloud GateWay 路由轉發規則介紹中咱們講解了SpringCloud Gateway
內部提供的斷言、謂語
,讓咱們能夠組合更精確的業務場景進行請求,既然SpringCloud GateWay
擔任了網關
的角色,在以前Zuul
能夠經過服務名進行自動轉發,SpringCloud Gateway
是否能夠實現自動轉發呢?html
Spring Cloud Gateway
能夠根據配置的斷言、謂語
進行知足條件轉發,也能夠自動同步服務註冊中心
的服務列表進行指定serviceId
前綴進行轉發,這裏的serviceId
是業務服務的spring.application.name
配置參數。java
把SpringCloud
的版本依賴添加到pom.xml
內,以下所示:git
//... <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.SR1</spring-cloud.version> </properties> <!--Spring Cloud 版本控制--> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> //...
咱們本章使用Eureka
做爲服務註冊中心來完成服務請求轉發講解,須要把Spring Cloud Gateway
網關項目做爲一個Client
註冊到Eureka Server
,先來看下添加的依賴,pom.xml
以下所示:web
//... <dependencies> <!--Spring Cloud Gateway--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!--Eureka Client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> //....
接下來咱們須要開啓Gateway
服務註冊中心的發現配置,開啓後才能自動同步服務註冊中心的服務列表
,application.yml
配置文件以下所示:spring
# 服務名稱 spring: application: name: spring-cloud-gateway # 開啓 Gateway 服務註冊中心服務發現 cloud: gateway: discovery: locator: enabled: true # Eureka Server 配置 eureka: client: service-url: defaultZone: http://localhost:10000/eureka/ # 配置Gateway日誌等級,輸出轉發細節信息 logging: level: org.springframework.cloud.gateway: debug
配置參數解釋以下所示:api
spring.application.name
:服務名spring.cloud.gateway.discovery.locator.enabled
:開啓SpringCloud Gateway
的註冊中心發現配置,開啓後可自動從服務註冊中心拉取服務列表,經過各個服務的spring.application.name
做爲前綴進行轉發,該配置默認爲false
。eureka.client.service-url.defaultZone
:配置Eureka Server
默認的空間地址logging.level.org.springframework.cloud.gateway
:設置SpringCloud Gateway
日誌等級爲debug
,用於輸出轉發的細節日誌,方便查看細節流程。在入口類添加對應的註解,開啓服務自動註冊,以下所示:app
@SpringBootApplication @EnableDiscoveryClient public class SpringCloudGatewayApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudGatewayApplication.class, args); } }
對應上面網關
配置的Eureka Server
的地址,咱們須要添加對應的配置,pom.xml
以下所示:負載均衡
//... <dependencies> <!--Eureka Server--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> //...
添加依賴後對Eureka Server
進行配置,配置文件application.yml
以下所示:curl
# 服務名 spring: application: name: sample-eureka-server # 端口號 server: port: 10000 # Eureka 配置信息 eureka: client: service-url: defaultZone: http://localhost:${server.port}/eureka/ fetch-registry: false register-with-eureka: false
這裏咱們修改默認的端口號爲10000
,爲了匹配在網關項目
的配置信息,至於fetch-registry
、register-with-eureka
能夠去我以前的文章查看,SpringCloud組件:將服務提供者註冊到Eureka集羣spring-boot
咱們經過@EnableEurekaServer
註解來開啓服務,以下所示:
@SpringBootApplication @EnableEurekaServer public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
網關
、服務註冊中心
咱們都已經準備好了,下面咱們能夠編寫業務邏輯服務,來驗證SpringCloud Gateway
具體是否能夠根據serviceId
進行轉發請求。
咱們簡單編寫一個GET
請求地址,輸出字符串信息,pom.xml
添加依賴以下所示:
<dependencies> <!--Web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--Eureka Client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
配置文件application.yml
以下所示:
# 服務名 spring: application: name: user-service # 註冊到Eureka eureka: client: service-url: defaultZone: http://localhost:10000/eureka/ # 服務端口號 server: port: 9090
配置該服務的服務名稱爲user-service
,這裏對應SpringCloud Gateway
的serviceId
。
@SpringBootApplication @EnableDiscoveryClient @RestController public class UserServiceApplication { /** * logger instance */ static Logger logger = LoggerFactory.getLogger(UserServiceApplication.class); public static void main(String[] args) { SpringApplication.run(UserServiceApplication.class, args); logger.info("「「「「「用戶服務啓動完成.」」」」」"); } @GetMapping(value = "/index") public String index() { return "this is user index"; } }
user-service
提供了/index
的請求地址,當訪問時,會對應輸出this is user index
。
接下來咱們進行驗證,測試順序以下所示:
第一步:啓動Eureka Server
第二步:啓動SpringCloud Gateway
啓動成功後控制檯會打印響應的註冊到Eureka
的日誌信息,以下所示:
DiscoveryClient_SPRING-CLOUD-GATEWAY/192.168.1.56:spring-cloud-gateway: registering service... Netty started on port(s): 8080
SpringCloud Gateway
內部經過Netty
完成WebServer
的請求轉發。
第三步:啓動user-service服務
啓動成功後控制檯打印相應註冊日誌,以下所示:
DiscoveryClient_USER-SERVICE/192.168.1.56:user-service:9090: registering service... Tomcat started on port(s): 9090 (http) with context path ''
第四步:測試訪問
SpringCloud Gateway
會每間隔30秒
進行從新拉取服務列表後路由重定義操做,日誌信息以下所示:
# Spring Cloud Gateway RouteDefinition CompositeDiscoveryClient_SPRING-CLOUD-GATEWAY applying {pattern=/SPRING-CLOUD-GATEWAY/**} to Path RouteDefinition CompositeDiscoveryClient_SPRING-CLOUD-GATEWAY applying filter {regexp=/SPRING-CLOUD-GATEWAY/(?<remaining>.*), replacement=/${remaining}} to RewritePath RouteDefinition matched: CompositeDiscoveryClient_SPRING-CLOUD-GATEWAY # User Service RouteDefinition CompositeDiscoveryClient_USER-SERVICE applying {pattern=/USER-SERVICE/**} to Path RouteDefinition CompositeDiscoveryClient_USER-SERVICE applying filter {regexp=/USER-SERVICE/(?<remaining>.*), replacement=/${remaining}} to RewritePath RouteDefinition matched: CompositeDiscoveryClient_USER-SERVICE
經過上面的日誌信息咱們已經能夠推斷出SpringCloud Gateway
映射spring.application.name
的值做爲服務路徑前綴,不過是大寫的,預計咱們能夠經過http://localhost:8080/USER-SERVICE/index
訪問到對應的信息。
訪問測試以下:
~ curl http://localhost:8080/USER-SERVICE/index this is user index
經過網關訪問具體服務的格式:http://網關IP:網關端口號/serviceId/**
若是Eureka Server
上有兩個相同serviceId
的服務時,SpringCloud Gateway
會自動完成負載均衡。
複製一個user-service
服務實例,修改服務端口號
,以下所示:
# 服務名稱 spring: application: name: user-service # Eureka Server eureka: client: service-url: defaultZone: http://localhost:10000/eureka/ # 服務端口號 server: port: 9091
在複製的項目內使用相同的spring.application.name
保持serviceId
一致,只作端口號的修改,爲了區分GateWay
完成了負載均衡,咱們修改/index
請求的返回內容以下所示:
@GetMapping(value = "/index") public String index() { return "this is user lb index"; }
訪問http://localhost:8080/USER-SERVICE/index
,輸出內容以下所示:
this is user lb index this is user index this is user lb index this is user index ...
經過本章的講解,咱們已經對SpringCloud Gateway
的轉發有一個簡單的理解,經過從服務註冊中心拉取服務列表後,自動根據serviceId
映射路徑前綴,同名服務多實例時會自動實現負載均衡。
Gitee
:https://gitee.com/hengboy/spr...
ApiBoot
:https://gitee.com/hengboy/api...