Gateway網(wǎng)關

代碼參考:

Gitee:[https://gitee.com/xn2001/cloudcode/tree/master/07-cloud-gateway](https://gitee.com/xn2001/cloudcode/tree/master/07-cloud-gateway)

GitHub:[https://github.com/lexinhu/cloudcode/tree/master/07-cloud-gateway](https://github.com/lexinhu/cloudcode/tree/master/07-cloud-gateway)

Spring Cloud Gateway 是 Spring Cloud 的一個全新項目流妻,該項目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等響應式編程和事件流技術開發(fā)的網(wǎng)關序愚,它旨在為微服務架構提供一種簡單有效的統(tǒng)一的 API 路由管理方式。

Gateway 網(wǎng)關是我們服務的守門神蛇耀,所有微服務的統(tǒng)一入口框喳。

網(wǎng)關的核心功能特性

  • 請求路由
  • 權限控制
  • 限流


權限控制:網(wǎng)關作為微服務入口,需要校驗用戶是是否有請求資格锨并,如果沒有則進行攔截露该。

路由和負載均衡:一切請求都必須先經(jīng)過 gateway,但網(wǎng)關不處理業(yè)務第煮,而是根據(jù)某種規(guī)則解幼,把請求轉發(fā)到某個微服務,這個過程叫做路由包警。當然路由的目標服務有多個時撵摆,還需要做負載均衡。

限流:當請求流量過高時害晦,在網(wǎng)關中按照下流的微服務能夠接受的速度來放行請求特铝,避免服務壓力過大。

在 SpringCloud 中網(wǎng)關的實現(xiàn)包括兩種:

  • gateway
  • zuul

Zuul 是基于 Servlet 實現(xiàn)壹瘟,屬于阻塞式編程鲫剿。而 Spring Cloud Gateway 則是基于 Spring5 中提供的WebFlux,屬于響應式編程的實現(xiàn)稻轨,具備更好的性能灵莲。

入門使用

1、創(chuàng)建 SpringBoot 工程 gateway殴俱,引入網(wǎng)關依賴
2政冻、編寫啟動類
3、編寫基礎配置和路由規(guī)則
4线欲、啟動網(wǎng)關服務進行測試

<!--網(wǎng)關-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos服務發(fā)現(xiàn)依賴-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

創(chuàng)建 application.yml 文件赠幕,內(nèi)容如下:

server:
  port: 10010 # 網(wǎng)關端口
spring:
  application:
    name: gateway # 服務名稱
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 網(wǎng)關路由配置
        - id: user-service # 路由id,自定義询筏,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目標地址 http就是固定地址
          uri: lb://userservice # 路由的目標地址 lb就是負載均衡榕堰,后面跟服務名稱
          predicates: # 路由斷言,也就是判斷請求是否符合路由規(guī)則的條件
            - Path=/user/** # 這個是按照路徑匹配,只要以/user/開頭就符合要求

我們將符合Path 規(guī)則的一切請求逆屡,都代理到 uri參數(shù)指定的地址圾旨。

上面的例子中,我們將 /user/** 開頭的請求魏蔗,代理到 lb://userservice砍的,其中 lb 是負載均衡(LoadBalance),根據(jù)服務名拉取服務列表莺治,實現(xiàn)負載均衡廓鞠。

重啟網(wǎng)關,訪問 http://localhost:10010/user/1 時谣旁,符合 /user/** 規(guī)則床佳,請求轉發(fā)到 uri:http://userservice/user/1

多個 predicates 的話,要同時滿足規(guī)則榄审,下文有例子砌们。

流程圖


路由配置包括:

1、路由id:路由的唯一標示
2搁进、路由目標(uri):路由的目標地址浪感,http代表固定地址,lb代表根據(jù)服務名負載均衡
3饼问、路由斷言(predicates):判斷路由的規(guī)則
4影兽、路由過濾器(filters):對請求或響應做處理

斷言工廠

我們在配置文件中寫的斷言規(guī)則只是字符串,這些字符串會被 Predicate Factory 讀取并處理莱革,轉變?yōu)槁酚膳袛嗟臈l件赢笨。

例如Path=/user/** 是按照路徑匹配,這個規(guī)則是由

org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory類來處理的驮吱,像這樣的斷言工廠在 Spring Cloud Gateway 還有十幾個


官方文檔:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories
一般的茧妒,我們只需要掌握 Path,加上官方文檔的例子左冬,就可以應對各種工作場景了桐筏。

predicates:
  - Path=/order/**
  - After=2031-04-13T15:14:47.433+08:00[Asia/Shanghai] #2031年之后才能訪問

過濾器工廠

GatewayFilter 是網(wǎng)關中提供的一種過濾器,可以對進入網(wǎng)關的請求和微服務返回的響應做處理拇砰。

Spring提供了31種不同的路由過濾器工廠梅忌。
官方文檔:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories


下面我們以 AddRequestHeader 為例:

需求:給所有進入 userservice 的請求添加一個請求頭:sign=xn2001.com is eternal

只需要修改 gateway 服務的 application.yml文件,添加路由過濾即可除破。

spring:
  cloud:
    gateway:
      routes: # 網(wǎng)關路由配置
        - id: user-service # 路由id牧氮,自定義,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目標地址 http就是固定地址
          uri: lb://userservice # 路由的目標地址 lb就是負載均衡瑰枫,后面跟服務名稱
          predicates: # 路由斷言踱葛,也就是判斷請求是否符合路由規(guī)則的條件
            - Path=/user/** # 這個是按照路徑匹配丹莲,只要以/user/開頭就符合要求
          filters:
            - AddRequestHeader=sign, xn2001.com is eternal # 添加請求頭

如何驗證,我們修改 userservice 中的一個接口

@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id, @RequestHeader(value = "sign", required = false) String sign) {
    log.warn(sign);
    return userService.queryById(id);
}

重啟兩個服務尸诽,訪問:http://localhost:10010/user/1

可以看到控制臺打印出了這個請求頭


當然甥材,Gateway 也是有全局過濾器的,如果要對所有的路由都生效性含,則可以將過濾器工廠寫到 default-filters 下:

spring:
  cloud:
    gateway:
      default-filters:
        - AddRequestHeader=sign, xn2001.com is eternal # 添加請求頭

全局過濾器

上面介紹的過濾器工廠洲赵,網(wǎng)關提供了 31 種,但每一種過濾器的作用都是固定的商蕴。如果我們希望攔截請求叠萍,做自己的業(yè)務邏輯則沒辦法實現(xiàn)

全局過濾器的作用也是處理一切進入網(wǎng)關的請求和微服務響應绪商,與 GatewayFilter 的作用一樣苛谷。區(qū)別在于 GlobalFilter 的邏輯可以寫代碼來自定義規(guī)則;而 GatewayFilter 通過配置定義部宿,處理邏輯是固定的。

需求:定義全局過濾器瓢湃,攔截請求理张,判斷請求的參數(shù)是否滿足下面條件

  • 參數(shù)中是否有 authorization

  • authorization 參數(shù)值是否為 admin

如果同時滿足則放行,否則攔截绵患。

@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {

    // 測試:http://localhost:10010/order/101?authorization=admin
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 獲取第一個 authorization 參數(shù)
        String authorization = exchange.getRequest().getQueryParams().getFirst("authorization");
        if ("admin".equals(authorization)){
            // 放行
            return chain.filter(exchange);
        }
        // 設置攔截狀態(tài)碼信息
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        // 設置攔截
        return exchange.getResponse().setComplete();
    }

    // 設置過濾器優(yōu)先級雾叭,值越低優(yōu)先級越高
    // 也可以使用 @Order 注解
    @Override
    public int getOrder() {
        return 0;
    }
}

過濾器順序

請求進入網(wǎng)關會碰到三類過濾器:DefaultFilter、當前路由的過濾器落蝙、GlobalFilter织狐;

請求路由后,會將三者合并到一個過濾器鏈(集合)中筏勒,排序后依次執(zhí)行每個過濾器.


排序的規(guī)則是什么呢移迫?

  • 每一個過濾器都必須指定一個 int 類型的 order 值,order 值越小管行,優(yōu)先級越高厨埋,執(zhí)行順序越靠前。
  • GlobalFilter 通過實現(xiàn) Ordered 接口捐顷,或者使用 @Order 注解來指定 order 值荡陷,由我們自己指定。
  • 路由過濾器和 defaultFilter 的 order 由 Spring 指定迅涮,默認是按照聲明順序從1遞增废赞。
  • 當過濾器的 order 值一樣時,會按照 defaultFilter > 路由過濾器 > GlobalFilter 的順序執(zhí)行叮姑。

跨域問題

不了解跨域問題的同學可以百度了解一下唉地;在 Gateway 網(wǎng)關中解決跨域問題還是比較方便的。

spring:
  cloud:
    gateway:
      globalcors: # 全局的跨域處理
        add-to-simple-url-handler-mapping: true # 解決options請求被攔截問題
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允許哪些網(wǎng)站的跨域請求 allowedOrigins: “*” 允許所有網(wǎng)站
              - "http://localhost:8090"
            allowedMethods: # 允許的跨域ajax的請求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允許在請求中攜帶的頭信息
            allowCredentials: true # 是否允許攜帶cookie
            maxAge: 360000 # 這次跨域檢測的有效期
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市渣蜗,隨后出現(xiàn)的幾起案子屠尊,更是在濱河造成了極大的恐慌,老刑警劉巖耕拷,帶你破解...
    沈念sama閱讀 221,331評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讼昆,死亡現(xiàn)場離奇詭異,居然都是意外死亡骚烧,警方通過查閱死者的電腦和手機浸赫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赃绊,“玉大人既峡,你說我怎么就攤上這事”滩椋” “怎么了运敢?”我有些...
    開封第一講書人閱讀 167,755評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長忠售。 經(jīng)常有香客問我传惠,道長,這世上最難降的妖魔是什么稻扬? 我笑而不...
    開封第一講書人閱讀 59,528評論 1 296
  • 正文 為了忘掉前任卦方,我火速辦了婚禮,結果婚禮上泰佳,老公的妹妹穿的比我還像新娘盼砍。我一直安慰自己,他們只是感情好逝她,可當我...
    茶點故事閱讀 68,526評論 6 397
  • 文/花漫 我一把揭開白布浇坐。 她就那樣靜靜地躺著,像睡著了一般黔宛。 火紅的嫁衣襯著肌膚如雪吗跋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,166評論 1 308
  • 那天宁昭,我揣著相機與錄音跌宛,去河邊找鬼。 笑死积仗,一個胖子當著我的面吹牛疆拘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播寂曹,決...
    沈念sama閱讀 40,768評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼哎迄,長吁一口氣:“原來是場噩夢啊……” “哼回右!你這毒婦竟也來了?” 一聲冷哼從身側響起漱挚,我...
    開封第一講書人閱讀 39,664評論 0 276
  • 序言:老撾萬榮一對情侶失蹤翔烁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后旨涝,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蹬屹,經(jīng)...
    沈念sama閱讀 46,205評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,290評論 3 340
  • 正文 我和宋清朗相戀三年白华,在試婚紗的時候發(fā)現(xiàn)自己被綠了慨默。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,435評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡弧腥,死狀恐怖厦取,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情管搪,我是刑警寧澤虾攻,帶...
    沈念sama閱讀 36,126評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站更鲁,受9級特大地震影響霎箍,放射性物質發(fā)生泄漏。R本人自食惡果不足惜岁经,卻給世界環(huán)境...
    茶點故事閱讀 41,804評論 3 333
  • 文/蒙蒙 一朋沮、第九天 我趴在偏房一處隱蔽的房頂上張望蛇券。 院中可真熱鬧缀壤,春花似錦、人聲如沸纠亚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒂胞。三九已至图呢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間骗随,已是汗流浹背蛤织。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鸿染,地道東北人指蚜。 一個月前我還...
    沈念sama閱讀 48,818評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像涨椒,于是被迫代替她去往敵國和親摊鸡。 傳聞我的和親對象是個殘疾皇子绽媒,可洞房花燭夜當晚...
    茶點故事閱讀 45,442評論 2 359

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