1. 程式人生 > >閘道器我選 Spring Cloud Gateway

閘道器我選 Spring Cloud Gateway

閘道器可提供請求路由與組合、協議轉換、安全認證、服務鑑權、流量控制與日誌監控等服務。可選的閘道器有不少,比如 Nginx、高效能閘道器 OpenResty、Linkerd 以及 Spring Cloud Gateway。

如果是真的追求高效能,那肯定是選擇 Nginx 或者 OpenResty 無疑了, 但是對效能要求不是很高的話,並且又在用 Spring Cloud 系列,那當然就要選擇 Spring Cloud Gateway 了。

閘道器的基礎就是路由功能,通俗解釋就是地址轉發,將一個請求地址轉發到實際的服務地址。比如請求的是 http://xxx.com/api 的路由地址,實際上會被轉發到 http://xxx.com:8888 上來,這就是個最簡單的路由方式。

我們可以理解為 Spring Cloud Gateway 就是針對進來的請求做各種判斷和處理,比如說判斷請求的合法性、許可權驗證,請求地址改寫,請求引數、頭資訊、cookie 資訊的分析和改寫,請求速率控制,日誌留存等。而這些都可以方便的通過 Predicate 和 GatewayFilter 來組合實現。

建立 Spring Cloud Gateway 專案

Spring Cloud 版本是 Greenwich.SR2,Spring Boot 版本 2.1.6.RELEASE,JDK 1.8。

接下來正式建立一個 Gateway 專案。

首先做兩個微服務,當做路由轉發的目標服務

兩個微服務是以 consul 作為服務註冊中心的,可以看這篇文章服務註冊發現、配置中心集一體的 Spring Cloud Consul

1、建立 consul-order 服務,具體可以去 github 上看程式碼(https://github.com/huzhicheng/spring-cloud-study/tree/master/consul/consul-order),很簡單的一個服務。建立的 RESTful Controller 如下:

@RestController
@RequestMapping(value = "order")
public class OrderController {

    @Value("${spring.application.name}")
    private String applicationName;


    @GetMapping(value = "get")
    public CustomerOrder getOrder(){
        CustomerOrder customerOrder = new CustomerOrder();
        customerOrder.setOrderId("9999");
        customerOrder.setProductName("MacBook Pro");
        customerOrder.setClient(applicationName);
        return customerOrder;
    }
}

總之,最後直接訪問這個介面的地址為 http://localhost:5006/order/get

2、建立 consul-user 服務,具體程式碼可以到 github 上檢視(https://github.com/huzhicheng/spring-cloud-study/tree/master/consul/consul-user)。建立的 RESTful Controller 內容如下:

@RestController
@RequestMapping(value = "user")
public class UserController {

    @GetMapping(value = "get")
    public User getUserInfo(){
        User user = new User();
        user.setName("古時的風箏");
        user.setAge(8);
        user.setLocation("北京");
        return user;
    }
}

和上面的微服務有點區別的就是設定了 context-path

server:
  port: 5005
  servlet:
    context-path: /user-service

之所以這樣不同的設定,是因為下面要驗證一個 filter。總之,最後上述介面的訪問地址為:http://localhost:5005/user-service/user/get

建立一個專案,並引入 maven 包

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

配置簡單的路由轉發

路由配置有兩種方式。一種是配置檔案,另外一種是程式碼方式配置,WebFlux 的反應式程式設計方式。所以我們 pom 檔案中要引入 WebFlux 的包。這是 Spring 5 的新特性。

1、先看第一種配置檔案方式配置:

server:
  port: 10000
spring:
  application:
    name: gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: false # 是否將服務id轉換為小寫
      routes:
      - id: userServiceRouter
        uri: lb://consul-user
        predicates:
        - Path=/user-service/**
      - id: orderServiceRouter
        uri: lb://consul-order
        predicates:
        - Path=/order-service/**
        filters:
        - StripPrefix=1
    consul:
      host: localhost #註冊gateway閘道器到consul
      port: 8500
      discovery:
        service-name: service-gateway

其中包括 Spring Boot 專案的基本配置,name、port ,還有關於 consul 的配置,要將閘道器服務註冊到註冊中心。

上面配置中建立了兩條路由規則,路由規則名稱通過 id 設定,分別是 userServiceRouter 和 orderServiceRouter,通過 predicates.Path 設定待轉發的 url,通過 uri 設定轉發後的目標地址。上面配置將以/user-service/開頭的地址轉發到 lb://consul-user,固定格式 lb + 服務id,在有註冊中心的情況下要這樣寫,如過沒有註冊中心,可以直接寫目標 url。

下面的路由規則中多了一個 StripPrefix 的 filter ,這個是 Gateway 的內建 filter,作用就是去掉 Path 中的指定部分,StripPrefix=1,就是以 / 分隔,去掉第一部分,比如 /a/b/c 這個地址,在 StripPrefix=1 的作用下,就會轉發到 /b/c/,當 StripPrefix=2 的時候,就會轉發到 /c/。

配置好上述介面,然後啟動閘道器服務。訪問規則就會有如下對應關係:

http://localhost:10000/user-service/user/get->http://localhost:5005/user-service/user/get

http://localhost:10000/order-service/order/get->http://localhost:5006/order/get

當然這只是針對每一個目標服務只有一個例項的情況,如果有多個例項,就會按照負載策略落到對應的例項中。

2、程式碼方式的路由配置

@Bean
public RouteLocator kiteRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("userRouter", r -> r.path("/user-service/**")
            .filters(f ->
                f.addResponseHeader("X-CustomerHeader", "kite"))
            .uri("lb://consul-user")
        )
        .route("orderRouter", r -> r.path("/order-service/**")
            .filters(f -> f.stripPrefix(1)).uri("lb://consul-order")
        )
        .build();
}

上面的這段程式碼和前面的配置檔案的內容是同樣的作用。只要實現一個返回型別為 RouteLocator,引數為 RouteLocatorBuilder型別的 Bean。

你看後面那一連串的 r.path().filters().uri() 了嗎,用它們就可以簡單的配置出路由規則,而且可讀性也比較強。另外,Gateway 還套用了 Predicate 的規則來構建更加靈活、複雜的路由規則。Predicate 是 Java 8 增加的邏輯計算庫,有 negate()、and()、or()、isEqual()幾個方法。具體的程式碼在 PredicateSpec 和 UriSpec 這兩個類裡,一目瞭然。

PredicateSpec 裡有這麼多方法,都可以結合 and、or 組合起來使用。

接下來就說到 filter,Gateway 內建了很多的 filter,可以在 GatewayFilterSpec 類下找到方法封裝,每一個 filter 都由一個 factory 的 apply 實現,都在 org.springframework.cloud.gateway.filter.factory包下,有必要的話可以直接看原始碼。 比如上面用到的 StripPrefix。還有 addResponseHeader,它的作用是在 Response 物件的 header 中新增請求頭。

啟動閘道器服務

啟動閘道器,並訪問兩個介面測試,介面分別為 http://localhost:10000/user-service/user/get和http://localhost:10000/order-service/order/get,正常返回資料,則說明閘道器服務配置正常。

巧用 StripPrefix filter

微服務多了之後,路由的轉發規則也就多了,比方說訂單相關請求要轉發到訂單微服務叢集,使用者相關請求要轉發到使用者微服務叢集,最終開放給終端的介面也要能表明是哪個微服務的,除了介面文件裡說明之外,介面本身最好也能明確標識。

一種方式是在微服務的配置檔案中配置上server.servlet.context-path

還有一種方式就是在路由規則的 path 中配置,然後加上 StripPrefix 配置,選擇性的去掉請求 url 中的某些部分。比如我們請求 Gateway的地址為 order-service/order/get,則經過 StripPrefix(1) 之後,會把請求地址變為 order/get,然後根據路由規則定向到具體的微服務地址或者特定的 url。

本篇就介紹 Spring Cloud Gateway 的基本用法,後續還會有關於整合安全認證、鑑權、限流、日誌等相關內容,敬請關注。

不要吝惜你的「推薦」呦

歡迎關注,不定期更新本系列和其他文章
古時的風箏 ,進入公眾號可以加入交流群

相關推薦

Spring Cloud Gateway

閘道器可提供請求路由與組合、協議轉換、安全認證、服務鑑權、流量控制與日誌監控等服務。可選的閘道器有不少,比如 Nginx、高效能閘道器 OpenResty、Linkerd 以及 Spring Cloud Gateway。 如果是真的追求高效能,那肯定是選擇 Nginx 或者 OpenResty 無疑了, 但是

Spring Cloud入門:API服務(Spring Cloud Gateway

文章例項使用的Spring Cloud版本為Finchley.SR1,Spring Boot版本為2.0.4。 1 Spring Cloud Gateway 在微服務架構中,閘道器作為服務的一個統一入口,所有的外部客戶端訪問都需要經過它來排程和過濾,可以實現的功能包括動

SpringCloud 配置:spring-cloud-gateway

微服務閘道器微服務閘道器的功能:    路由轉發,接收一切外界請求,轉發到後端的微服務上去;    請求過濾,在服務閘道器中可以完成一系列的橫切功能,例如許可權校驗、限流以及監控等,這些都可以通過過濾器完成(其實路由轉發也是通過過濾器實現的)微服務閘道器種類    Zuul,

第七章 API服務:Spring Cloud Zuul

  API閘道器是一個更為智慧的應用伺服器, 它的定義類似於面向物件設計模式中的Facade模式, 它的存在就像是整個微服務架構系統的門面一樣,所有的外部客戶端訪問都需要經過它來進行排程和過濾。它除了要實現請求路由、 負載均衡、 校驗過濾等功能之外, 還需要更多能力, 比如與服務治理框架的結合、 請求轉發時的

微服務api使用Zuul構建API Gateway

對於 API Gateway,常見的選型有基於 Openresty 的 Kong、基於 Go 的 Tyk 和基於 Java 的 Zuul。什麼是Zuul?Zuul是裝置和網站到Netflix流媒體應用程

Spring CloudGateway(二):過濾器

版本:2.0.2.RELEASE 連結:http://spring.io/projects/spring-cloud-gateway#overview   本章主要目錄如下: Spring Cloud Gateway閘道器過濾器工廠是什麼?   本章主

API效能比較:NGINX vs. ZUUL vs. Spring Cloud Gateway vs. Linkerd

前幾天拜讀了 OpsGenie 公司(一家致力於 Dev & Ops 的公司)的資深工程師 Turgay Çelik 博士寫的一篇文章(連結在文末),文中介紹了他們最初也是採用 Nginx 作為單體應用的閘道器,後來接觸到微服務架構後開始逐漸採用了其他元件。 我對於

springcloud(十五):Spring Cloud 終於按捺不住推出了自己的服務 Gateway

Spring 官方最終還是按捺不住推出了自己的閘道器元件:Spring Cloud Gateway ,相比之前我們使用的 Zuul(1.x) 它有哪些優勢呢?Zuul(1.x) 基於 Servlet,使用阻塞 API,它不支援任何長連線,如 WebSockets,Spring Cloud Gateway 使用

Spring Cloud Gateway替代zuul作為API

本文非常簡要介紹如何使用Spring Cloud Gateway最API 閘道器(不是使用zuul作為閘道器),關於Spring Cloud Gateway和zuul的效能比較本文不再贅述,基本可以肯定Spring Cloud Finchley版本的gateway比zuul 1.x系列的效能和功能整

Spring Cloud 終於按捺不住推出了自己的服務 Gateway

Spring 官方最終還是按捺不住推出了自己的閘道器元件:Spring Cloud Gateway ,相比之前我們使用的 Zuul(1.x) 它有哪些優勢呢?Zuul(1.x) 基於 Servlet,使用阻塞 API,它不支援任何長連線,如 WebSockets,Spring Cloud Ga

Spring Cloud zuul配置api-gateway

zuul閘道器,主要功能用於 限流,驗證 zuul可以通過載入動態過濾機制,從而實現以下各項功能: 驗證與安全保障: 識別面向各類資源的驗證要求並拒絕那些與要求不符的請求。 審查與監控: 在邊緣位置追蹤有意義資料及統計結果,從而為我們帶來準確的生產狀態結論。 動態路由:

Hystrix斷路器在微服務中的應用(Spring Cloud Gateway

前文回顧 在之前的一篇文章:微服務閘道器Zuul遷移到Spring Cloud Gateway,我們講解了如何從Zuul遷移到新的元件:Spring Cloud Gateway,以及擴充套件了微服務閘道器的功能,包括限流過濾器、斷路器過濾器等。然而很多讀者在使用的時候反饋,使用POS

spring cloud-構建微服務架構的(API GateWay)

在我們前面的部落格中講到,當服務A需要呼叫服務B的時候,只需要從Eureka中獲取B服務的註冊例項,然後使用Feign來呼叫B的服務,使用Ribbon來實現負載均衡,但是,當我們同時向客戶端暴漏多個服務的時候,客戶端怎麼呼叫我們暴漏的服務了,如果我們還想加入安全認證,許可

spring cloud---------- gateway

一提閘道器的時候,可能大家第一個想到的就是我們網路中的閘道器,其實在微服務體系中閘道器的作用是什麼的明顯的,閘道器負責統一接收所有請求,然後根據不同的規則進行轉發到不同的服務。使用閘道器能夠統一的管理請求日誌、進行許可權控制、過濾等,這樣就能避免在每個單體應用中

微服務Zuul遷移到Spring Cloud Gateway

Spring Cloud Netflix Zuul是由Netflix開源的API閘道器,在微服務架構下,閘道器作為對外的門戶,實現動態路由、監控、授權、安全、排程等功能。 Zuul基於servlet 2.5(使用3.x),使用阻塞API。 它不支援任何長連線,如

微服務實戰——Spring Cloud Gateway

導讀 作為Netflix Zuul的替代者,Spring Cloud Gateway是一款非常實用的微服務閘道器,在Spring Cloud微服務架構體系中發揮非常大的作用。本文對Spring Cloud Gateway常見使用場景進行了梳理,希望對微服務開發人員提供一些幫助。   微服務閘道器Sp

spring cloud gateway

先記錄一個錯誤再說,在啟動的時候報錯 Description: Parameter 0 of method modifyReq

微服務 Spring Cloud Gateway

1.  為什麼是Spring Cloud Gateway 一句話,Spring Cloud已經放棄Netflix Zuul了。現在Spring Cloud中引用的還是Zuul 1.x版本,而這個版本是基於過濾器的,是阻塞IO,不支援長連線。Zuul 2.x版本跟1.x的架構大一樣,效能也有所提升。

最全面的改造ZuulSpring Cloud Gateway(包含Zuul核心實現和Spring Cloud Gateway核心實現)

前言: 最近開發了Zuul閘道器的實現和Spring Cloud Gateway實現,對比Spring Cloud Gateway發現後者效能好支援場景也豐富。在高併發或者複雜的分散式下,後者限流和自定義攔截也很棒。   提示: 本文主要列出本人開發的Zuul閘道器核心程式碼以及Spring

Spring Cloud gateway 服務二 斷言、過濾器

微服務當前這麼火爆的程度,如果不能學會一種微服務框架技術。怎麼能升職加薪,增加簡歷的籌碼?spring cloud 和 Dubbo 需要單獨學習。說沒有時間?沒有精力?要學倆個框架?而Spring Cloud alibaba只需要你學會一個就會擁有倆種微服務治理框架技術。何樂而不為呢?加油吧!騷猿年 上一篇我