網關服務Spring Cloud Gateway(二)

上一篇文章服務網關 Spring Cloud GateWay 初級篇,介紹了 Spring Cloud Gateway 的相關術語、技術原理,以及如何快速使用 Spring Cloud Gateway。這篇文章咱們繼續學習 Spring Cloud Gateway 的高級使用方式,好比如何配置服務中心來使用,如何使用熔斷、限流等高級功能。html

註冊中心

上篇主要講解了網關代理單個服務的使用語法,在實際的工做中,服務的相互調用都是依賴於服務中心提供的入口來使用,服務中心每每註冊了不少服務,若是每一個服務都須要單獨配置的話,這將是一份很枯燥的工做。Spring Cloud Gateway 提供了一種默認轉發的能力,只要將 Spring Cloud Gateway 註冊到服務中心,Spring Cloud Gateway 默認就會代理服務中心的全部服務,下面用代碼演示。spring

準備服務和註冊中心

在介紹服務網關 zuul 的使用時,提供了 spring-cloud-eureka 、spring-cloud-producer 項目示例,本次演示咱們將兩個項目版本升級到 Finchley.SR2 後繼續演示使用。後端

spring-cloud-eureka(Eureka Server) 的 pom 文件更改,其它依賴包不變。瀏覽器

升級前:app

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>

升級後:負載均衡

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

spring-cloud-producer(Eureka Client)的 pom 文件更改。由於配置中心須要做爲服務註冊到註冊中心,因此須要升級 Eureka Client,其餘依賴沒有變更。socket

升級前:微服務

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

升級後:post

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

兩個項目升級完依賴包後依次重啓,訪問註冊中心地址 http://localhost:8000/ 便可看到名爲 SPRING-CLOUD-PRODUCER的服務。學習

服務網關注冊到註冊中心

複製上一節的示例項目 cloud-gateway 從新命名爲 cloud-gateway-eureka,添加 eureka 的客戶端依賴包。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

修改 application.yml 配置文件內容以下

server:
  port: 8888
spring:
  application:
    name: cloud-gateway-eureka
  cloud:
    gateway:
     discovery:
        locator:
         enabled: true
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8000/eureka/
logging:
  level:
    org.springframework.cloud.gateway: debug

配置說明:

  • spring.cloud.gateway.discovery.locator.enabled:是否與服務註冊於發現組件進行結合,經過 serviceId 轉發到具體的服務實例。默認爲 false,設爲 true 便開啓經過服務中心的自動根據 serviceId 建立路由的功能。
  • eureka.client.service-url.defaultZone指定註冊中心的地址,以便使用服務發現功能
  • logging.level.org.springframework.cloud.gateway 調整相 gateway 包的 log 級別,以便排查問題

修改完成後啓動 cloud-gateway-eureka 項目,訪問註冊中心地址 http://localhost:8000/ 便可看到名爲 CLOUD-GATEWAY-EUREKA的服務。

測試

將 Spring Cloud Gateway 註冊到服務中心以後,網關會自動代理全部的在註冊中心的服務,訪問這些服務的語法爲:

http://網關地址:端口/服務中心註冊 serviceId/具體的url

好比咱們的 spring-cloud-producer 項目有一個 /hello 的服務,訪問此服務的時候會返回:hello world。

好比訪問地址:http://localhost:9000/hello,頁面返回:hello world!

按照上面的語法咱們經過網關來訪問,瀏覽器輸入:http://localhost:8888/SPRING-CLOUD-PRODUCER/hello 一樣返回:hello world!證實服務網關轉發成功。

咱們將項目 spring-cloud-producer 複製一份爲 spring-cloud-producer-1,將/hello服務的返回值修改成 hello world smile !,修改端口號爲 9001 ,修完完成後重啓,這時候訪問註冊中心後臺會發現有兩個名爲 SPRING-CLOUD-PRODUCER的服務。

在瀏覽器屢次訪問地址:http://localhost:8888/SPRING-CLOUD-PRODUCER/hello,頁面交替返回如下信息:

hello world!
hello world smile!

說明後端服務自動進行了均衡負載。

基於 Filter(過濾器) 實現的高級功能

服務網關Zuul高級篇中大概介紹過 Filter 的概念。

Spring Cloud Gateway 的 Filter 的生命週期不像 Zuul 的那麼豐富,它只有兩個:「pre」 和 「post」。

  • PRE: 這種過濾器在請求被路由以前調用。咱們可利用這種過濾器實現身份驗證、在集羣中選擇請求的微服務、記錄調試信息等。
  • POST:這種過濾器在路由到微服務之後執行。這種過濾器可用來爲響應添加標準的 HTTP Header、收集統計信息和指標、將響應從微服務發送給客戶端等。

Spring Cloud Gateway 的 Filter 分爲兩種:GatewayFilter 與 GlobalFilter。GlobalFilter 會應用到全部的路由上,而 GatewayFilter 將應用到單個路由或者一個分組的路由上。

Spring Cloud Gateway 內置了9種 GlobalFilter,好比 Netty Routing Filter、LoadBalancerClient Filter、Websocket Routing Filter 等,根據名字便可猜想出這些 Filter 的做者,具體你們能夠參考官網內容:Global Filters

利用 GatewayFilter 能夠修改請求的 Http 的請求或者響應,或者根據請求或者響應作一些特殊的限制。 更多時候咱們會利用 GatewayFilter 作一些具體的路由配置,下面咱們作一些簡單的介紹。

快速上手 Filter 使用

咱們以 AddRequestParameter GatewayFilter 來演示一下,如何在項目中使用 GatewayFilter,AddRequestParameter GatewayFilter 能夠在請求中添加指定參數。

application.yml配置示例

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: http://example.org
        filters:
        - AddRequestParameter=foo, bar

這樣就會給匹配的每一個請求添加上foo=bar的參數和值。

咱們將以上配置融入到 cloud-gateway-eureka 項目中,完整的 application.yml 文件配置信息以下:

server:
  port: 8888
spring:
  application:
    name: cloud-gateway-eureka
  cloud:
    gateway:
     discovery:
        locator:
         enabled: true
     routes:
     - id: add_request_parameter_route
       uri: http://localhost:9000
       filters:
       - AddRequestParameter=foo, bar
       predicates:
         - Method=GET
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8000/eureka/
logging:
  level:
    org.springframework.cloud.gateway: debug

這裏的 routes 手動指定了服務的轉發地址,設置全部的 GET 方法都會自動添加foo=barhttp://localhost:9000 是 spring-cloud-producer 項目,咱們在此項目中添加一個 foo() 方法,用來接收轉發中添加的參數 foo。

@RequestMapping("/foo")
public String foo(String foo) {
    return "hello "+foo+"!";
}

修改完成後重啓 cloud-gateway-eureka、spring-cloud-producer 項目。訪問地址http://localhost:9000/foo頁面返回:hello null!,說明並無接受到參數 foo;經過網關來調用此服務,瀏覽器訪問地址http://localhost:8888/foo頁面返回:hello bar!,說明成功接收到參數 foo 參數的值 bar ,證實網關在轉發的過程當中已經經過 filter 添加了設置的參數和值。

服務化路由轉發

上面咱們使用 uri 指定了一個服務轉發地址,單個服務這樣使用問題不大,可是咱們在註冊中心每每會使用多個服務來共同支撐整個服務的使用,這個時候咱們就指望能夠將 Filter 做用到每一個應用的實例上,spring cloud gateway 工了這樣的功能,只須要簡單配置便可。

爲了測試兩個服務提供者是否都被調用,咱們在 spring-cloud-producer-1 項目中也一樣添加 foo() 方法。

@RequestMapping("/foo")
public String foo(String foo) {
    return "hello "+foo+"!!";
}

爲了和 spring-cloud-producer 中 foo() 方法有所區別,這裏使用了兩個感嘆號。同時將 cloud-gateway-eureka 項目配置文件中的 uri 內容修改以下:

#格式爲:lb://應用註冊服務名
uri: lb://spring-cloud-producer

修改完以後,從新啓動項目 cloud-gateway-eureka、spring-cloud-producer-1,瀏覽器訪問地址:http://localhost:8888/foo頁面交替出現:

hello bar!
hello bar!!

證實請求依據均勻轉發到後端服務,而且後端服務均接收到了 filter 增長的參數 foo 值。

這裏其實默認使用了全局過濾器 LoadBalancerClient ,當路由配置中 uri 所用的協議爲 lb 時(以uri: lb://spring-cloud-producer爲例),gateway 將使用 LoadBalancerClient 把 spring-cloud-producer 經過 eureka 解析爲實際的主機和端口,並進行負載均衡。

相關文章
相關標籤/搜索