在上一篇文章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
以下所示:github
//...
<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
配置文件以下所示:web
# 服務名稱
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
複製代碼
配置參數解釋以下所示:spring
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
,用於輸出轉發的細節日誌,方便查看細節流程。在入口類添加對應的註解,開啓服務自動註冊,以下所示:api
@SpringBootApplication
@EnableDiscoveryClient
public class SpringCloudGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudGatewayApplication.class, args);
}
}
複製代碼
對應上面網關
配置的Eureka Server
的地址,咱們須要添加對應的配置,pom.xml
以下所示:app
//...
<dependencies>
<!--Eureka Server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
//...
複製代碼
添加依賴後對Eureka Server
進行配置,配置文件application.yml
以下所示:負載均衡
# 服務名
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集羣curl
咱們經過@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
:gitee.com/hengboy/spr…