Spring Cloud Gateway

一 API 網(wǎng)關(guān)

API網(wǎng)關(guān)葫辐,就是指系統(tǒng)統(tǒng)一入口搜锰,它用來封裝應(yīng)用程序的內(nèi)部結(jié)構(gòu),為客戶端提供統(tǒng)一服務(wù)耿战。一些與業(yè)務(wù)本身功能無關(guān)的公共邏輯可以在這里實現(xiàn)蛋叼。比如:認(rèn)證、鑒權(quán)剂陡、監(jiān)控狈涮、路由轉(zhuǎn)發(fā) 等等。

二 業(yè)界流行的網(wǎng)關(guān)

  1. Nginx+lua: 使用nginx 的反向代理和負(fù)載均衡均可實現(xiàn)api服務(wù)器的負(fù)載均衡及高可用鸭栖。lua是一種腳本語言歌馍,可以編寫一些簡單的lua腳本來支持nginx。
  2. Kong:基于 nginx +lua 開發(fā)纤泵,性能高骆姐、穩(wěn)定,有多個可用的插件(鑒權(quán)捏题、限流)可以開箱即用玻褪。缺點:只支持http協(xié)議,二次開發(fā)公荧、自由拓展困難带射;提供管理API,缺乏更易用的管控循狰,配置方式窟社。
  3. Zuul :Netflix 開源網(wǎng)關(guān),功能豐富绪钥,使用java開發(fā)灿里,易于二次開發(fā)。缺點:缺乏管控程腹,無法動態(tài)配置匣吊;依賴組件較多;處理http請求依賴是web容器寸潦,性能不如nginx色鸳。
  4. Spring Cloud Gateway:Spring 公司為了替換zuul而開發(fā)的網(wǎng)關(guān)服務(wù)。

三SpringCloud Gateway 簡介

SpringCloud Gateway 是 Spring Cloud 的一個全新項目见转,該項目是基于 Spring 5.0命雀,Spring Boot 2.0 和 Project Reactor 等技術(shù)開發(fā)的網(wǎng)關(guān),它旨在為微服務(wù)架構(gòu)提供一種簡單有效的統(tǒng)一的 API 路由管理方式斩箫。

Spring Cloud Gateway 作為 Spring Cloud 生態(tài)系統(tǒng)中的網(wǎng)關(guān)吏砂,目標(biāo)是替代Netflix Zuul撵儿,其不僅提供統(tǒng)一的路由方式,而且基于Fliter鏈的方式提供了網(wǎng)關(guān)基本的功能赊抖,例如:安全统倒,監(jiān)控/指標(biāo)和限流。
(1)優(yōu)點:

性能強(qiáng)勁:是第一代網(wǎng)關(guān)Zuul的1.6倍

功能強(qiáng)大:內(nèi)置了很多使用的功能氛雪,例如轉(zhuǎn)發(fā),監(jiān)控耸成,限流等

設(shè)計優(yōu)雅报亩,容易擴(kuò)展

(2)缺點:

其實現(xiàn)依賴Netty與WebFlux,不是傳統(tǒng)的Servlet編程模型井氢,學(xué)習(xí)成本高

不能將其部署在tomcat弦追,jetty等Servlet容器里,只能打成jar包執(zhí)行

需要Spingboot2.0及以上的版本花竞,才支持劲件。
四 SpringCloud Gateway快速入門

  1. 創(chuàng)建新模塊,導(dǎo)入依賴
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
  1. 創(chuàng)建主類
@SpringBootApplication
public class RuoYiGatewayApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(RuoYiGatewayApplication.class, args);
       
    }
}
  1. 添加配置文件application.yml
server:
  port: 8080
 
spring: 
  application:
    name: ruoyi-gateway
  cloud:
    gateway:
      routes: #路由數(shù)組[路由就是指定當(dāng)請求滿足什么條件的時候轉(zhuǎn)到哪個微服務(wù)]
        # 系統(tǒng)模塊
        - id: ruoyi-system #當(dāng)前路有的標(biāo)示约急,要求唯一
          uri: http://localhost:9201/ #請求要轉(zhuǎn)發(fā)到的地址
          predicates: #斷言(就是路由轉(zhuǎn)發(fā)要滿足的條件)
            - Path=/system/** #當(dāng)前請求路徑滿足Path指定的規(guī)則時零远,才進(jìn)行路有轉(zhuǎn)發(fā)
          filters: #過濾器,請求在傳遞過程中可以通過過濾器對其進(jìn)行一定的修改
            - StripPrefix=1  #轉(zhuǎn)發(fā)之前去掉1層路徑
  1. 運行效果

在地址欄輸入 localhost:8080/system/user/1就會自動跳轉(zhuǎn)到 localhost:9201/user/1

其中路徑中的system被過濾掉厌蔽,8080變成9201

  1. 使用nacos注冊中心配置方式進(jìn)行優(yōu)化

(1)現(xiàn)在在配置文件中寫死了轉(zhuǎn)發(fā)路徑的地址牵辣,我們需要使用nacos獲取此地址,

(2)并使用 uri: lb://ruoyi-system #請求要轉(zhuǎn)發(fā)到的地址 自動實現(xiàn)負(fù)載均衡

第1步,加入nacos依賴

  <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

第2部:應(yīng)用加上注解@EnableDiscoveryClient

@SpringBootApplication
@EnableDiscoveryClient
public class RuoYiGatewayApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(RuoYiGatewayApplication.class, args);
       
    }
}

第3部:修改配置文件

server:
  port: 8080
 
spring: 
  application:
    name: ruoyi-gateway
  cloud:
    nacos:
      discovery:
      server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
        lowerCaseServiceId: true
        enabled: true   #讓gateway可以發(fā)現(xiàn)nacos的微服務(wù)
      routes: #路由數(shù)組[路由就是指定當(dāng)請求滿足什么條件的時候轉(zhuǎn)到哪個微服務(wù)]
        # 系統(tǒng)模塊
        - id: ruoyi-system #當(dāng)前路有的標(biāo)示奴饮,要求唯一
          uri: lb://ruoyi-system #請求要轉(zhuǎn)發(fā)到的地址
          predicates: #斷言(就是路由轉(zhuǎn)發(fā)要滿足的條件)
            - Path=/system/** #當(dāng)前請求路徑滿足Path指定的規(guī)則時纬向,才進(jìn)行路有轉(zhuǎn)發(fā)
          filters: #過濾器,請求在傳遞過程中可以通過過濾器對其進(jìn)行一定的修改
            - StripPrefix=1  #轉(zhuǎn)發(fā)之前去掉1層路徑

五 若依平臺—ruoyi-gateway網(wǎng)關(guān)
(1)若依平臺單獨建立ruoyi-gateway網(wǎng)關(guān)模塊戴卜,代碼里有4個過濾器:

AuthFilter(全局過濾器)逾条,
BlackListUrlFilter(黑名單過濾器)
CacheRequestFilter
ValidateCodeFilter (驗證碼過濾器)
(2)在nacos里配置了路由信息 和白名單

spring:
  redis:
    host: localhost
    port: 6379
    password: 
  cloud:
    gateway:
      discovery:
        locator:
          lowerCaseServiceId: true
          enabled: true
      routes:
        # 認(rèn)證中心
        - id: ruoyi-auth
          uri: lb://ruoyi-auth
          predicates:
            - Path=/auth/**
          filters:
            # 驗證碼處理
            - CacheRequestFilter
            - ValidateCodeFilter
            - StripPrefix=1
        # 代碼生成
        - id: ruoyi-gen
          uri: lb://ruoyi-gen
          predicates:
            - Path=/code/**
          filters:
            - StripPrefix=1
        # 定時任務(wù)
        - id: ruoyi-job
          uri: lb://ruoyi-job
          predicates:
            - Path=/schedule/**
          filters:
            - StripPrefix=1
        # 系統(tǒng)模塊
        - id: ruoyi-system
          uri: lb://ruoyi-system
          predicates:
            - Path=/system/**
          filters:
            - StripPrefix=1
        # 文件服務(wù)
        - id: ruoyi-file
          uri: lb://ruoyi-file
          predicates:
            - Path=/file/**
          filters:
            - StripPrefix=1
         # whaletest模塊
        - id: ruoyi-whaletest
          uri: lb://ruoyi-whaletest
          predicates:
            - Path=/whaletest/**
          filters:
            - StripPrefix=1
 
# 不校驗白名單
ignore:
  whites:
    - /auth/logout
    - /auth/login
    - /*/v2/api-docs
    - /csrf
    - /whaletest/test

六 重要功能配置——路由斷言和過濾器
我們看到每個路由主要對predicates 和filter進(jìn)行了配置。這兩個一個是斷言投剥,一個是過濾器师脂。接下來我們對這兩個重要功能進(jìn)行說明

打開nacos中的ruoyi-gateway-dev.yml ,顯示有路由的配置信息如下

系統(tǒng)模塊

    - id: ruoyi-system #當(dāng)前路有的標(biāo)示,要求唯一
      uri: lb://ruoyi-system #請求要轉(zhuǎn)發(fā)到的地址
      predicates: #斷言(就是路由轉(zhuǎn)發(fā)要滿足的條件)
        - Path=/system/** #當(dāng)前請求路徑滿足Path指定的規(guī)則時薇缅,才進(jìn)行路有轉(zhuǎn)發(fā)
      filters: #過濾器危彩,請求在傳遞過程中可以通過過濾器對其進(jìn)行一定的修改
        - StripPrefix=1  #轉(zhuǎn)發(fā)之前去掉1層路徑

一.predicates 斷言:路有需要滿足什么條件才能路由,是路由轉(zhuǎn)發(fā)的判斷條件泳桦,目前SpringCloud Gateway支持多種方式汤徽,常見如:Path、Query灸撰、Method谒府、Header等拼坎,寫法必須遵循 key=vlue的形式

Predicate 接受一個輸入?yún)?shù),返回一個布爾值結(jié)果完疫。

(1)系統(tǒng)內(nèi)置的斷言

規(guī)則 實例 說明
Path - Path=/gate/,/rule/ ## 當(dāng)請求的路徑為gate泰鸡、rule開頭的時,轉(zhuǎn)發(fā)到http://localhost:9023服務(wù)器上
Before - Before=2017-01-20T17:42:47.789-07:00[America/Denver] 在某個時間之前的請求才會被轉(zhuǎn)發(fā)到 http://localhost:9023服務(wù)器上
After - After=2017-01-20T17:42:47.789-07:00[America/Denver] 在某個時間之后的請求才會被轉(zhuǎn)發(fā)
Between - Between=2017-01-20T17:42:47.789-07:00[America/Denver],2017-01-21T17:42:47.789-07:00[America/Denver] 在某個時間段之間的才會被轉(zhuǎn)發(fā)
Cookie - Cookie=chocolate, ch.p 名為chocolate的表單或者滿足正則ch.p的表單才會被匹配到進(jìn)行請求轉(zhuǎn)發(fā)
Header - Header=X-Request-Id, \d+ 攜帶參數(shù)X-Request-Id或者滿足\d+的請求頭才會匹配
Host - Host=www.hd123.com 當(dāng)主機(jī)名為www.hd123.com的時候直接轉(zhuǎn)發(fā)到http://localhost:9023服務(wù)器上
Method - Method=GET 只有GET方法才會匹配轉(zhuǎn)發(fā)請求壳鹤,還可以限定POST盛龄、PUT等請求方式
(2)自定義斷言

二.filters過濾

  1. 局部過濾,是針對單個路有的過濾器

(1)內(nèi)置過濾規(guī)則

過濾規(guī)則 實例 說明
PrefixPath - PrefixPath=/app 在請求路徑前加上app
RewritePath - RewritePath=/test, /app/test 訪問localhost:9022/test,請求會轉(zhuǎn)發(fā)到localhost:8001/app/test
SetPath - SetPath=/{segment} 設(shè)置請求路徑芳誓,與RewritePath類似余舶。如/red/blue的請求被轉(zhuǎn)發(fā)到/blue。
SetStatus - SetStatus=401 設(shè)置回執(zhí)狀態(tài)碼锹淌。
StripPrefix - StripPrefix=2 跳過指定路徑匿值。請求/name/blue/red會轉(zhuǎn)發(fā)到/red。
(2)自定義過濾規(guī)則

若依平臺中nacos中ruoyi-gateway-dev.yml赂摆,有添加自定義過濾規(guī)則

      filters:
        # 驗證碼處理
        - CacheRequestFilter
        - ValidateCodeFilter
        - StripPrefix=1

同時需要實現(xiàn)AbstractGatewayFilterFactory<>方法

  1. 全局過濾:全局過濾器作用于所有的路由挟憔,不需要單獨配置,我們可以用它來實現(xiàn)很多統(tǒng)一化處理的業(yè)務(wù)需求烟号,比如權(quán)限認(rèn)證绊谭,IP訪問限制等等。目前網(wǎng)關(guān)統(tǒng)一鑒權(quán)AuthFilter.java就是采用的全局過濾器褥符。

自定義全局過濾規(guī)則龙誊,只需要實現(xiàn)GlobalFilter, Ordered這兩個接口就可以了。



/**
 * 網(wǎng)關(guān)鑒權(quán)
 * 
 * @author ruoyi
 */
@Component
public class AuthFilter implements GlobalFilter, Ordered
{
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
    {
        
    }
 
   
    @Override
    public int getOrder()
    {
        return -200;
    }
}

七喷楣,高級配置——網(wǎng)關(guān)限流
網(wǎng)關(guān)是所有請求的公共入口趟大,所以可以在網(wǎng)關(guān)進(jìn)行限流,而且限流方式也很多铣焊。Sentinel支持對SpringCloud Gateway逊朽,Zuul等主流網(wǎng)關(guān)進(jìn)行限流。

Sentinel可以提供兩種資源的限流

  1. 路由route限流:即在Spring配置文件中配置的路由條目曲伊,資源名為對應(yīng)的ruoteId

2.自定義API維度:用戶可以利用sentinel提供的API來自定義一些API分組

需要添加如下依賴

  <!-- SpringCloud Alibaba Sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
 
        <!-- SpringCloud Alibaba Sentinel Gateway -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
        </dependency>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末叽讳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子坟募,更是在濱河造成了極大的恐慌岛蚤,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件懈糯,死亡現(xiàn)場離奇詭異涤妒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)赚哗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進(jìn)店門她紫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來硅堆,“玉大人,你說我怎么就攤上這事贿讹〗ヌ樱” “怎么了?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵民褂,是天一觀的道長茄菊。 經(jīng)常有香客問我,道長赊堪,這世上最難降的妖魔是什么买羞? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮雹食,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘期丰。我一直安慰自己群叶,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布钝荡。 她就那樣靜靜地躺著街立,像睡著了一般。 火紅的嫁衣襯著肌膚如雪埠通。 梳的紋絲不亂的頭發(fā)上赎离,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天,我揣著相機(jī)與錄音端辱,去河邊找鬼梁剔。 笑死,一個胖子當(dāng)著我的面吹牛舞蔽,可吹牛的內(nèi)容都是我干的荣病。 我是一名探鬼主播,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼渗柿,長吁一口氣:“原來是場噩夢啊……” “哼个盆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起朵栖,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤颊亮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后陨溅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體终惑,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年声登,在試婚紗的時候發(fā)現(xiàn)自己被綠了狠鸳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片揣苏。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖件舵,靈堂內(nèi)的尸體忽然破棺而出卸察,到底是詐尸還是另有隱情,我是刑警寧澤铅祸,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布坑质,位于F島的核電站,受9級特大地震影響临梗,放射性物質(zhì)發(fā)生泄漏涡扼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一盟庞、第九天 我趴在偏房一處隱蔽的房頂上張望吃沪。 院中可真熱鬧,春花似錦什猖、人聲如沸票彪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽降铸。三九已至,卻和暖如春摇零,著一層夾襖步出監(jiān)牢的瞬間推掸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工驻仅, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留谅畅,地道東北人。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓雾家,卻偏偏與公主長得像铃彰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子芯咧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內(nèi)容