Spring Cloud Alibaba(12)---Gatway概述、簡單示例

雨點的名字發表於2021-05-24

Gatway概述、專案搭建

前言

有關閘道器的概念之前這裡不在概述,因為之前在寫zuul閘道器的時候有詳細陳述過,地址如下:

SpringCloud(7)---閘道器概念、Zuul專案搭建

SpringCloud(8)---zuul許可權校驗、介面限流

一、Gatway概念

1.Gatway是什麼?

Gatway是在Spring生態系統之上構建的API閘道器服務,基於Spring 5,Spring Boot2和Project Reactor等技術。Gateway旨在提供一種簡單而有效的方式來對API進行路由,

以及提供一些強大的過濾器功能,例如:反向代理熔斷限流重試等。

微服務架構中閘道器所處位置(盜圖):

Spring Cloud Alibaba(12)---Gatway概述、簡單示例

2、Gatway有哪些特性?

1)、為了提升閘道器的效能,Spring Cloud Gateway是基於WebFlux框架實現的,而WebFlux框架底層則使用了高效能的Reactor模式通訊框架Netty。
2)、基於SpringFramework5,ProjectReactor和SpringBoot2.0進行構建
3)、能夠匹配任何任何請求屬性
4)、可以對路由指定Predicates和Filters,易於編寫的Predicates和Filters
5)、整合斷路器
6)、整合Spring Cloud服務發現
7)、支援請求限流
8)、支援路徑重寫

3、Gatway三大重要概念

Gatway有著很重要的3個概念 路由斷言過濾

路由路由是構建閘道器的基本模組,它由ID,目標URI,一系列的斷言Predicates和過濾器Filters組成,如果斷言為true,則匹配該路由。

斷言參考Java8的java.util.function.Predicate,開發人員可以匹配HTTP請求中的所有內容,例如請求頭或請求引數,如果請求與斷言相匹配則進行路由。

之前有寫過Predicate的文章 java程式碼之美(13)--- Predicate詳解

過濾Spring框架中GatewayFilter的例項,使用過濾器,可以載請求被路由前或者後對請求進行修改。

總結下就是: 一個web請求,通過一些匹配條件,定位到真正的服務節點,在這個轉發的過程中,進行一些精細化的控制。predicate就是匹配條件,filter就是攔截器。

predicate + filter + 目標uri實現路由route,所以一般都是組合使用,一個請求可以經過多個predicate或者多個filter

4、Gatway工作流程

下面是官網給的一張圖,它總體上描述了Spring Cloud Gateway的工作流程

Spring Cloud Alibaba(12)---Gatway概述、簡單示例

1)客戶端向Spring Cloud Gateway發出請求。

2)如果Gateway Handler Mapping確定請求與路由匹配,則將其傳送到Gateway Web Handler。

3)Handler通過指定的過濾器鏈將請求傳送到我們實際的服務執行業務邏輯,然後返回。

4)過濾器由虛線分隔的原因是,過濾器可以在傳送代理請求之前或之後執行邏輯。

核心路由轉發 + 過濾器鏈


二、Gatway與Zuul區別

Zuul有兩個大版本分別為: Zuul1和Zuul2。所以要比較的話有個跟這兩個版本進行比較。

1、Gatway與Zuul1比較

1)Zuul1.x是一個基於阻塞I/O的API 閘道器

2)Zuul1.x基於Servlet2.5使用阻塞架構,它不支援任何長連線(如WebSocket)Zuul的設計模式和Nginx比較相似,每次I/O操作都是從工作執行緒中選擇一個執行,請求執行緒

被阻塞到工作執行緒完成,但是差別是Nginx用C++實現,Zuul用Java實現。

3) Spring Cloud Gateway建立在Spring Framewor5、Project Reactor和Spring Boot2之上,使用非阻塞API

2、Gatway與Zuul2比較

1)首先Zuul2從產品角度來看 因為Zuul2的升級一直跳票,一下開源一下閉源。所以SpringCloud目前還沒有整合Zuul2。這就帶來很大的不方便。也是因此SpringCloud最後自己

研發了一個閘道器代替Zuul,就是SpringCloud Gateway。它才是Spring的親兒子。

2)跟Zuul1相比Zuul2.x理念更加先進,想基於Netty非阻塞和支援長連線。Zuul2.x的效能較Zuul1.x有很大提升。在效能方面,根據官網提供的基準測試,

SpringCloud Gateway 的RPS(每秒請求數)是Zuul的1.6倍。


三、編碼實現

這裡先附上一張圖,到目前為止,Nacos註冊中心Nacos配置中心Feign服務呼叫Sentinel流量控制 在之前的部落格都有寫,專案中都有實現,這裡也在之前

專案的基礎上開始實現Gateway功能。

Spring Cloud Alibaba(12)---Gatway概述、簡單示例

1、pom.xml

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

2、application.yml

server:
  port: 8001

spring:
  application:
    name: api-gateway

  cloud:
    gateway:
      routes: #陣列形式
        - id: mall-goods  #路由唯一標識
          uri: http://127.0.0.1:6001  #想要轉發到的地址
          order: 1 #優先順序,數字越小優先順序越高
          predicates: #斷言 配置哪個路徑才轉發
            - Path=/mall-goods/**
            #- Before=2020-09-11T01:01:01.000+08:00  # 在這個時間點之後不能訪問
            #- Query=source  #一定攜帶這個引數
          filters: #過濾器,請求在傳遞過程中通過過濾器修改
            - StripPrefix=1  #去掉第一層字首

3、啟動類

@SpringBootApplication
public class GatWayApplication {

    public static void main(String [] args){
        SpringApplication.run(GatWayApplication.class,args);
    }

}

注意 pom檔案中不能有 spring-boot-starter-web jar包。否則啟動會直接報錯。

4、測試

1)直接訪問mall-goods地址

http://localhost:6001/api/v1/sentinel/test-sentinel
Spring Cloud Alibaba(12)---Gatway概述、簡單示例

2)通過閘道器服務上面這個介面

http://localhost:8001/mall-goods/api/v1/sentinel/test-sentinel
Spring Cloud Alibaba(12)---Gatway概述、簡單示例

發現通過服務閘道器地址後成功轉發到商品微服務的介面。


四、配置詳解

上面有講過Gatway有著很重的3個概念 路由斷言過濾

id:路由的ID
uri:匹配路由的轉發地址
predicates:配置該路由的斷言,通過PredicateDefinition類進行接收配置。
order:路由的優先順序,數字越小,優先順序越高。
filters: 過濾器

一個routes下可以有多個上面的配置,上面一個配置可以理解成一個微服務節點。如果有多個微服務需要轉發那麼就在routes下多配置幾個,示例

Spring Cloud Alibaba(12)---Gatway概述、簡單示例

id

路由的ID。可以任意字串。但如果有幾十個微服務都隨意取名,到時候不好找。這裡用微服務的名稱當成路由的ID,這樣一看就知道對於那個微服務做路由轉發。

uri

匹配路由的轉發地址。這裡好理解就是將請求閘道器的地址,轉到具體微服務節點的地址。

predicates

配置該路由的斷言。主要請求滿足該斷言(true)才會進入該路由。這個可以同時配置多個。多個的情況下代表需要 同時滿足

order

路由的優先順序,數字越小,優先順序越高。可能我們一個請求經來,同時滿足匹配多個路由。那這裡order誰小就進那個路由。

filters

過濾器。跟predicates一樣。同時可以配置多個。多個的意思就是一個一個過濾。

上面這樣解釋或許有點枯燥,所以這裡根據上面的實際例子來做解釋。

#為什麼通過配置後請求第一個url會轉發到第二個url
http://localhost:8001/mall-goods/api/v1/sentinel/test-sentinel
http://localhost:6001/api/v1/sentinel/test-sentinel

步驟如下

1)首先是斷言predicates 上面只配置了一個  - Path=/mall-goods/**。上面的請求中是有 /mall-goods/ 所以命中當前路由。
2)那麼根據 uri: http://127.0.0.1:6001 屬性,那麼請求的IP+埠號 由 localhost:8001 轉為 127.0.0.1:6001。
3)同時上面配置了一個過濾器   - StripPrefix=1  去掉第一層字首,也就是去掉 /mall-goods/ 這一層。所以最終的路由轉發就變成了http://127.0.0.1:6001/api/v1/sentinel/test-sentinel。 也就是商品微服務對應的請求介面。

總結:有關 predicatesfilters 官方都提供了很多種規則實現類,我們要根據特定的需求去使用他們,如果不滿足那就需要我們自定義predicates 或 filters。

github地址 nacos-feign-sentinel-gatway


參考

Gateway--概述

如何評價 spring cloud gateway? 對比 zuul2.0 主要的優勢是什麼?



少說多做,句句都會得到別人的重視;多說少做,句句都會受到別人的忽視。(12)

相關文章