【SpringCloud】6.0 網(wǎng)關(guān)控制Gateway

微服務(wù)架構(gòu)

  • SpringCloud
    服務(wù)注冊發(fā)現(xiàn):Nacos
    服務(wù)限流降級:Sentinel
    分布配置中?:Nacos
    分布式事務(wù)保證數(shù)據(jù)一致性:Seata
    分布式定時任務(wù):Spring Scheduling Tasks
    服務(wù)?關(guān):SpringCloud Gateway
    異步消息削峰填谷:RocketMQ
    服務(wù)之間調(diào)?:OpenFeign、Ribbon
    鏈路追蹤:Sleuth+Zipkin

技術(shù)棧版本控制

序號 名稱 版本 用途 備注
1 openJDK 21 Java JDK
2 postgresSQL 17.4 基礎(chǔ)數(shù)據(jù)庫
3 Maven 3.9.9 Java第三方依賴包管理工具
4 springboot 3.4.3 Java MVC框架
5 springcloud 2024.0.1 微服務(wù)框架
6 springcloud Alibaba 2023.0.3.2 阿里巴巴微服務(wù)框架擴(kuò)展

組件版本控制

序號 名稱 版本 用途 備注
1 Nacos 2.5.1 服務(wù)注冊發(fā)現(xiàn)、分布配置中?
2 Sentinel 1.8.8 服務(wù)限流降級 面向云原生微服務(wù)的高可用流控防護(hù)組件
3 Seata 2.3.0 分布式事務(wù)保證數(shù)據(jù)一致性

什么是?關(guān)

  • API Gateway,是系統(tǒng)的唯?對外的??,介于客戶端和服務(wù)器端之間的中間層,處理?業(yè)務(wù)功能 提供路由請求、鑒權(quán)、監(jiān)控、緩存、限流等功能
  • 統(tǒng)?接?
    智能路由
    AB測試、灰度測試
    負(fù)載均衡、容災(zāi)處理
    ?志埋點(類似Nignx?志)
  • 流量監(jiān)控
    限流處理
    服務(wù)降級
  • 安全防護(hù)
    鑒權(quán)處理
    監(jiān)控
    機(jī)器?絡(luò)隔離

主流的?關(guān)

  • zuul:是Netflix開源的微服務(wù)?關(guān),和
    Eureka,Ribbon,Hystrix等組件配合使?,依賴組件?
    較多,性能教差
  • kong: 由Mashape公司開源的,基于Nginx的API
    gateway
  • nginx+lua:是?個?性能的HTTP和反向代理服務(wù)器,lua
    是腳本語?,讓Nginx執(zhí)?Lua腳本,并且?并發(fā)、?阻塞
    的處理各種請求
  • springcloud gateway: Spring公司專?開發(fā)的?關(guān),替代
    zuul
    注意:AlibabaCloud對應(yīng)的?關(guān),?
    SpringCloud官?推薦的Gateway

什么是 SpringCloud Gateway

Spring官?出品,基于Spring5+Reactor技術(shù)開發(fā)的?關(guān)
性能強(qiáng)勁基于Reactor+WebFlux、功能多樣基于springboot2.x, 直接可以jar包?式運(yùn)?

官??檔
https://spring.io/projects/spring-cloud-gateway

項目使用

注:這里僅helloworld一下,下一小章節(jié)會按實際使用結(jié)合nginx使用。

新建微服務(wù)online-edu-gateway

image.png

image.png

建好之后刪掉Main.java
image.png

配置online-edu-api-gateway/pom.xml,增加網(wǎng)關(guān)依賴。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.online_edu</groupId>
        <artifactId>online-edu</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>online-edu-api-gateway</artifactId>

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

</project>

新增并配置online-edu-api-gateway/src/main/java/org/online_edu/GatewayApplication.java

package org.online_edu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

}

新增并配置online-edu-api-gateway/src/main/resources/application.yml.

server:
  port: 8888

spring:
  application:
    name: online-edu-api-gateway
  cloud:
    gateway:
      routes: #數(shù)組形式
        - id: order-service #路由唯?標(biāo)識
          uri: http://127.0.0.1:8000 #想要轉(zhuǎn)發(fā)到的地址
          order: 1 #優(yōu)先級,數(shù)字越?優(yōu)先級越?
          predicates: #斷? 配置哪個路徑才轉(zhuǎn)發(fā)
            - Path=/order-server/**
          filters: #過濾器,請求在傳遞過程中通過過濾器修改
            - StripPrefix=1 #去掉第?層前綴
            #訪問路徑 http://localhost:8888/order-server/api/v1/video_order/list
            #轉(zhuǎn)發(fā)路徑 http://localhost:8000/order-server/api/v1/video_order/list
            #需要過濾器去掉前?第?層

啟動網(wǎng)關(guān)服務(wù)online-edu-api-gateway和訂單服務(wù)online-edu-order-service.

瀏覽器打開http://localhost:8888/order-server/api/v1/video_order/list

image.png

gateway整合nacos

  • 原先存在的問題
    微服務(wù)地址寫死
    負(fù)載均衡沒做到

實際使用中,我們不可能將微服務(wù)的地址和ip寫死,而是通過nacos作為注冊中心,進(jìn)行自動的服務(wù)發(fā)現(xiàn)。

配置online-edu-api-gateway/pom.xml,增加naocs依賴。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.online_edu</groupId>
        <artifactId>online-edu</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>online-edu-api-gateway</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--添加nacos客戶端-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- Spring Cloud 2020 版本后默認(rèn)移除了 Ribbon,需手動添加 spring-cloud-loadbalancer 依賴以實現(xiàn) lb:// 負(fù)載均衡路由。-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
        </dependency>
    </dependencies>

</project>

配置online-edu-api-gateway/src/main/resources/application.yml,增加nacos配置。

server:
  port: 8888

spring:
  application:
    name: online-edu-api-gateway
  cloud:
    nacos:
      discovery:
        server-addr: xxx.xxx.xxx.xxx:8848
        username: nacos
        password: password
    gateway:
      routes: #數(shù)組形式
        - id: order-service #路由唯?標(biāo)識
#          uri: http://127.0.0.1:8000 #想要轉(zhuǎn)發(fā)到的地址
          uri: lb://online-edu-order-service # 從nacos獲取名稱轉(zhuǎn)發(fā),lb是負(fù)載均衡輪訓(xùn)策略
          order: 1 #優(yōu)先級,數(shù)字越?優(yōu)先級越?
          predicates: #斷? 配置哪個路徑才轉(zhuǎn)發(fā)
            - Path=/order-server/**
          filters: #過濾器,請求在傳遞過程中通過過濾器修改
            - StripPrefix=1 #去掉第?層前綴
            #訪問路徑 http://localhost:8888/order-server/api/v1/video_order/list
            #轉(zhuǎn)發(fā)路徑 http://localhost:8000/order-server/api/v1/video_order/list
            #需要過濾器去掉前?第?層
      discovery:
        locator:
          enabled: true #開啟?關(guān)拉取nacos的服務(wù)

訂單服務(wù)online-edu-order-service開啟多實例啟動。

image.png

image.png

修改端口再啟動一個:
image.png

瀏覽器打開http://localhost:8888/order-server/api/v1/video_order/list
image.png

再次刷新


image.png

Gateway?關(guān)的配置項

以下僅作為網(wǎng)關(guān)功能演示。實際使用網(wǎng)關(guān)過程中,注意:

?關(guān)不要加太多業(yè)務(wù)邏輯,否則會影響性能,務(wù)必記住



image.png

路由:是?關(guān)的基本單元,由ID、URI、?組
Predicate、?組Filter組成,根據(jù)Predicate進(jìn)?匹配轉(zhuǎn)發(fā)

route組成部分

id:路由的ID
uri:匹配路由的轉(zhuǎn)發(fā)地址
predicates:配置該路由的斷?,通過PredicateDefinition類進(jìn)?接收配置。
order:路由的優(yōu)先級,數(shù)字越?,優(yōu)先級越?

交互流程

  • 客戶端向Spring Cloud Gateway發(fā)出請求
  • 如果?關(guān)處理程序映射確定請求與路由匹配
  • 則將其發(fā)送到?關(guān)Web處理程序
  • 通過特定過濾器鏈運(yùn)?,前置處理-后置處理
image.png

Gateway內(nèi)置的路由斷?

什么是Gateway路由斷?

  • Predicate 來源于Java8,接受輸?參數(shù),返回?個布爾值結(jié)果
  • Spring Cloud Gateway 中 Spring 利? Predicate 的特性實現(xiàn)了各種路由匹配規(guī)則
  • 轉(zhuǎn)發(fā)的判斷條件,SpringCloud Gateway?持多種?式,常?如:Path、Query、Method、Header等
  • ?持多個Predicate請求的轉(zhuǎn)發(fā)是必須滿?所有的Predicate后才可以進(jìn)?路由轉(zhuǎn)發(fā)

內(nèi)置路由斷?—— RoutePredicateFactory 接?實現(xiàn)類

進(jìn)入idea項目中,ctrl+N,搜索RoutePredicateFactory 類。


image.png

按住ctrl+Alt,點擊接?實現(xiàn)類RoutePredicateFactory 名稱,可以查詢到下游的實現(xiàn)類:


image.png

參數(shù)編寫規(guī)則 XXXRoutePredicateFactory,使?XXX作為
參數(shù)配置, 例如下?

predicates:
 - Host=
 - Path=
 - Method=
 - Header=
 - Query=
 - Cookie=

斷言使用舉例

比如,某個接口,要求在指定時間定時下線。過后不可以在被訪問。

使?Before ,只要當(dāng)前時間?于設(shè)定時間,路由才會匹配請求
東8區(qū)的2025-03-28T01:01:01.000+08:00后,請求不可訪問

配置online-edu-api-gateway/src/main/resources/application.yml

server:
  port: 8888

spring:
  application:
    name: online-edu-api-gateway
  cloud:
    nacos:
      discovery:
        server-addr: xxx.xxx.xxx.xxx:8848
        username: nacos
        password: password
    gateway:
      routes: #數(shù)組形式
        - id: order-service #路由唯?標(biāo)識
#          uri: http://127.0.0.1:8000 #想要轉(zhuǎn)發(fā)到的地址
          uri: lb://online-edu-order-service # 從nacos獲取名稱轉(zhuǎn)發(fā),lb是負(fù)載均衡輪訓(xùn)策略
          order: 1 #優(yōu)先級,數(shù)字越?優(yōu)先級越?
          predicates: #斷? 配置哪個路徑才轉(zhuǎn)發(fā)
            - Path=/order-server/**
            - Before=2025-03-28T01:01:01.000+08:00
#            - RewritePath=/order-server/(?<remaining>.*), /$\{remaining}
          filters: #過濾器,請求在傳遞過程中通過過濾器修改
            - StripPrefix=1 #去掉第?層前綴

      discovery:
        locator:
          enabled: true  #開啟網(wǎng)關(guān)拉取nacos的服務(wù)

重新運(yùn)行網(wǎng)關(guān)服務(wù),瀏覽器運(yùn)行,沒問題(運(yùn)行時,當(dāng)前北京時間2025年3月27日)


image.png

改為Before=2025-03-26T01:01:01.000+08:00

瀏覽器運(yùn)行:


image.png

例如增加必須傳的參數(shù)

          predicates: #斷? 配置哪個路徑才轉(zhuǎn)發(fā)
            - Path=/order-server/**
            - Before=2025-03-28T01:01:01.000+08:00
            - Query=token

瀏覽器運(yùn)行:

image.png
image.png

Gateway?關(guān)的過濾器

過濾器?命周期

  • PRE: 這種過濾器在請求被路由之前調(diào)?,?般?于鑒權(quán)、限流等
  • POST:這種過濾器在路由到微服務(wù)以后執(zhí)?,?般?于修改響應(yīng)結(jié)果,?如增加header信息、打點結(jié)果?志

?關(guān)過濾器分類

  • 局部過濾器GatewayFilter:應(yīng)?在某個路由上,每個過濾器??都對應(yīng)?個實現(xiàn)類,并且這些類的名稱必須以GatewayFilterFactory 結(jié)尾.內(nèi)置很多全局過濾器,頂級接? GlobalFilter
  • 全局過濾器:作?全部路由上,內(nèi)置很多局部過濾器,頂級接? GatewayFilterFactory

?定義全局過濾器實現(xiàn)鑒權(quán)

自定義實現(xiàn),本質(zhì)上就是模仿官方的過濾器,寫一個自己的java類。
新建online-edu-api-gateway/src/main/java/org/online_edu/filter/UserGlobalFilter.java

package org.online_edu.filter;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class UserGlobalFilter implements GlobalFilter, Ordered {
    /**
     * 處理Web請求并(可選地)委托給下一個{@code GatewayFilter}
     * 通過給定的{@link GatewayFilterChain}。
     *
     * @param chain 鏈提供了一種委托給下一個過濾器的方式
     * @param exchange 交換當(dāng)前服務(wù)器交換
     * @return {@code Mono<Void>} 表示請求處理完成
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 寫業(yè)務(wù)邏輯

        return null;
    }

    /**
     * 獲取該對象的順序值。
     * 值越高優(yōu)先級越低。因此,
     * 具有最低值的對象具有最高優(yōu)先級(在某種程度上)
     * 類似于Servlet {@code load-on-startup}值)。
     * 相同的順序值將導(dǎo)致任意的排序位置受影響的對象。
     *
     * @return 返回排序闕值
     * @see #HIGHEST_PRECEDENCE
     * @see #LOWEST_PRECEDENCE
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

模擬寫登錄鑒權(quán)邏輯,這里引入一個工具包apache-commons-lang3。

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.17.0</version>
</dependency>

如果拉不下來就手動下載一下。

DremoteRepositories=https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -DgroupId=org.apache.commons -DartifactId=commons-lang3 -Dversion=3.17.0
image.png
   @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 寫業(yè)務(wù)邏輯
        String token = exchange.getRequest().getHeaders().getFirst("token");

        //TODO 根據(jù)業(yè)務(wù)開發(fā)對應(yīng)的鑒權(quán)規(guī)則,比如JWT
        if (StringUtils.isBlank(token)) {
            // 返回401
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        //繼續(xù)往下執(zhí)?
        return chain.filter(exchange);
    }

online-edu-api-gateway/src/main/resources/application.yml記得注釋掉多余的斷言。

server:
  port: 8888

spring:
  application:
    name: online-edu-api-gateway
  cloud:
    nacos:
      discovery:
        server-addr: xxx.xxx.xxx.xxx:8848
        username: nacos
        password: password
    gateway:
      routes: #數(shù)組形式
        - id: order-service #路由唯?標(biāo)識
#          uri: http://127.0.0.1:8000 #想要轉(zhuǎn)發(fā)到的地址
          uri: lb://online-edu-order-service # 從nacos獲取名稱轉(zhuǎn)發(fā),lb是負(fù)載均衡輪訓(xùn)策略
          order: 1 #優(yōu)先級,數(shù)字越?優(yōu)先級越?
          predicates: #斷? 配置哪個路徑才轉(zhuǎn)發(fā)
            - Path=/order-server/**
#            - Before=2025-03-28T01:01:01.000+08:00
#            - Query=token
          filters: #過濾器,請求在傳遞過程中通過過濾器修改
            - StripPrefix=1 #去掉第?層前綴

      discovery:
        locator:
          enabled: true  #開啟網(wǎng)關(guān)拉取nacos的服務(wù)

運(yùn)行:


image.png

配置請求,并發(fā)送:


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容