SpringCloud組件: GateWay整合Eureka轉發服務請求

在上一篇文章Spring Cloud GateWay 路由轉發規則介紹中咱們講解了SpringCloud Gateway內部提供的斷言、謂語,讓咱們能夠組合更精確的業務場景進行請求,既然SpringCloud GateWay擔任了網關的角色,在以前Zuul能夠經過服務名進行自動轉發,SpringCloud Gateway是否能夠實現自動轉發呢?html

初始化Gateway服務

Spring Cloud Gateway能夠根據配置的斷言、謂語進行知足條件轉發,也能夠自動同步服務註冊中心的服務列表進行指定serviceId前綴進行轉發,這裏的serviceId是業務服務的spring.application.name配置參數。java

SpringCloud 版本控制依賴

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,用於輸出轉發的細節日誌,方便查看細節流程。

註冊網關到Eureka

在入口類添加對應的註解,開啓服務自動註冊,以下所示: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-registryregister-with-eureka能夠去我以前的文章查看,SpringCloud組件:將服務提供者註冊到Eureka集羣curl

開啓Eureka Server

咱們經過@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 GatewayserviceId

註冊服務到Eureka

@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映射路徑前綴,同名服務多實例時會自動實現負載均衡。

源碼位置

Giteegitee.com/hengboy/spr…

ApiBootgitee.com/hengboy/api…github.com/hengboy/api…

相關文章
相關標籤/搜索