欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring Gateway動(dòng)態(tài)路由的實(shí)現(xiàn)方案

 更新時(shí)間:2025年09月28日 08:52:28   作者:程序員小潘  
Spring Cloud Gateway (下文簡(jiǎn)稱(chēng) Gateway)作為微服務(wù)網(wǎng)關(guān),動(dòng)態(tài)配置路由是剛需,畢竟沒(méi)人想路由一改就要重啟網(wǎng)關(guān),本文結(jié)合源碼,提供一種動(dòng)態(tài)路由配置的思路,需要的朋友可以參考下

前沿

Spring Cloud Gateway (下文簡(jiǎn)稱(chēng) Gateway)作為微服務(wù)網(wǎng)關(guān),動(dòng)態(tài)配置路由是剛需,畢竟沒(méi)人想路由一改就要重啟網(wǎng)關(guān)。

本文結(jié)合源碼,提供一種動(dòng)態(tài)路由配置的思路。

何為路由

在 Gateway 中,路由對(duì)應(yīng)的類(lèi)是org.springframework.cloud.gateway.route.Route,各屬性含義:

  • id:路由唯一標(biāo)識(shí)
  • uri:轉(zhuǎn)發(fā)的目標(biāo)地址
  • order:路由順序
  • predicate:謂詞集合,符合條件的請(qǐng)求才會(huì)被路由
  • gatewayFilters:過(guò)濾器集合,允許對(duì)請(qǐng)求轉(zhuǎn)發(fā)前后對(duì)請(qǐng)求和響應(yīng)做修改
  • metadata:路由元數(shù)據(jù)
public class Route implements Ordered {

	private final String id;

	private final URI uri;

	private final int order;

	private final AsyncPredicate<ServerWebExchange> predicate;

	private final List<GatewayFilter> gatewayFilters;

	private final Map<String, Object> metadata;
}

路由是怎么來(lái)的?

Gateway 提供了org.springframework.cloud.gateway.route.RouteLocator接口用來(lái)構(gòu)建路由。

public interface RouteLocator {
	Flux<Route> getRoutes();
}

子類(lèi)有三個(gè):

CachingRouteLocator

通過(guò) ConcurrentHashMap 來(lái)緩存路由對(duì)象,避免路由對(duì)象反復(fù)構(gòu)建,通過(guò)監(jiān)聽(tīng) RefreshRoutesEvent 事件來(lái)刷新緩存,主要用于提升性能。

CompositeRouteLocator

RouteLocator 的裝飾器,將一組 RouteLocator 合并成一個(gè)。

RouteDefinitionRouteLocator

路由的實(shí)際構(gòu)建者,根據(jù)路由定義對(duì)象 RouteDefinition 來(lái)構(gòu)建路由,內(nèi)部會(huì)依賴(lài) RoutePredicateFactory,GatewayFilterFactory 工廠類(lèi)。

RouteDefinition

為了構(gòu)建路由,Gateway 提供了org.springframework.cloud.gateway.route.RouteDefinition路由定義類(lèi),根據(jù) RouteDefinition 來(lái)構(gòu)建 Route。

RouteDefinition 是怎么來(lái)的?

和構(gòu)建路由一樣,Gateway 也提供了 RouteDefinitionLocator 接口來(lái)發(fā)現(xiàn) RouteDefinition。

public interface RouteDefinitionLocator {
	Flux<RouteDefinition> getRouteDefinitions();
}

常見(jiàn)的子類(lèi)有:

PropertiesRouteDefinitionLocator

基于配置文件的實(shí)現(xiàn),它會(huì)從配置文件中讀取spring.cloud.gateway.routes來(lái)構(gòu)建 RouteDefinition,當(dāng)然也支持從配置中心讀取。

InMemoryRouteDefinitionRepository

基于內(nèi)存的實(shí)現(xiàn),內(nèi)部持有一個(gè) Map 對(duì)象來(lái)管理 RouteDefinition,默認(rèn)是空的。額外實(shí)現(xiàn)了 RouteDefinitionWriter 接口,允許新增和刪除 RouteDefinition。

DiscoveryClientRouteDefinitionLocator

基于服務(wù)發(fā)現(xiàn)的實(shí)現(xiàn),支持從服務(wù)注冊(cè)中心發(fā)現(xiàn)服務(wù),并將服務(wù)構(gòu)建成 RouteDefinition。

CompositeRouteDefinitionLocator

裝飾器實(shí)現(xiàn),用于將多個(gè) RouteDefinitionLocator 合并成一個(gè)。

RouteLocator工作流程

路由的構(gòu)建依賴(lài)兩個(gè)核心組件:RouteLocator 和 RouteDefinitionLocator。

簡(jiǎn)單來(lái)說(shuō),RouteDefinitionLocator 負(fù)責(zé)提供 RouteDefinition 路由定義對(duì)象,RouteLocator 再根據(jù) RouteDefinition 構(gòu)建路由對(duì)象。

項(xiàng)目引入spring-cloud-starter-gateway依賴(lài)后,Spring 啟動(dòng)時(shí)會(huì)觸發(fā) Gateway 的自動(dòng)裝配,

org.springframework.cloud.gateway.config.GatewayAutoConfiguration類(lèi)。

Gateway 路由定義發(fā)現(xiàn)依賴(lài)一組 RouteDefinitionLocator,再把他們包裝成 CompositeRouteDefinitionLocator

@Bean
@Primary
public RouteDefinitionLocator routeDefinitionLocator(List<RouteDefinitionLocator> routeDefinitionLocators) {
    return new CompositeRouteDefinitionLocator(Flux.fromIterable(routeDefinitionLocators));
}

默認(rèn)的 RouteDefinitionLocator 有兩個(gè),分別是:PropertiesRouteDefinitionLocator 和 InMemoryRouteDefinitionRepository。前者讀取配置文件來(lái)生成 RouteDefinition,后者使用 Map 來(lái)維護(hù),默認(rèn)是空的。

@Bean
@ConditionalOnMissingBean
public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(GatewayProperties properties) {
    return new PropertiesRouteDefinitionLocator(properties);
}

@Bean
@ConditionalOnMissingBean(RouteDefinitionRepository.class)
public InMemoryRouteDefinitionRepository inMemoryRouteDefinitionRepository() {
    return new InMemoryRouteDefinitionRepository();
}

RouteDefinitionLocator 有了,接下來(lái)就是 RouteLocator。默認(rèn)會(huì)自動(dòng)裝配 RouteDefinitionRouteLocator 和 CachingRouteLocator,前者根據(jù) RouteDefinition 來(lái)構(gòu)建路由,后者提供緩存優(yōu)化性能。

@Bean
public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties,
        List<GatewayFilterFactory> gatewayFilters, List<RoutePredicateFactory> predicates,
        RouteDefinitionLocator routeDefinitionLocator, ConfigurationService configurationService) {
    return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates, gatewayFilters, properties,
            configurationService);
}

@Bean
@Primary
@ConditionalOnMissingBean(name = "cachedCompositeRouteLocator")
public RouteLocator cachedCompositeRouteLocator(List<RouteLocator> routeLocators) {
    return new CachingRouteLocator(new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
}

實(shí)現(xiàn)動(dòng)態(tài)路由,CachingRouteLocator 是關(guān)鍵。

默認(rèn)情況下,Gateway 會(huì)通過(guò) CachingRouteLocator 來(lái)優(yōu)化性能。因?yàn)楦鶕?jù) RouteDefinition 來(lái)構(gòu)建路由還是有不小開(kāi)銷(xiāo)的,CachingRouteLocator 會(huì)把構(gòu)建好的 List 緩存下來(lái)。

同時(shí),它實(shí)現(xiàn)了 ApplicationListener,通過(guò)監(jiān)聽(tīng) RefreshRoutesEvent 事件來(lái)刷新路由。

動(dòng)態(tài)路由實(shí)現(xiàn)

綜上所述,實(shí)現(xiàn)動(dòng)態(tài)路由的思路就是:

實(shí)現(xiàn)一個(gè)自定義的 RouteDefinitionLocator 從遠(yuǎn)程加載配置并構(gòu)建 RouteDefinition,路由一旦有變更,就發(fā)送一個(gè) RefreshRoutesEvent 事件通知 CachingRouteLocator 刷新路由,即可生效。

路由配置推薦 Nacos,因?yàn)樗凶兏ㄖ?。通過(guò)監(jiān)聽(tīng)配置,即可在配置變更時(shí),第一時(shí)間刷新路由,讓新的路由生效。

首先,引入依賴(lài)

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

然后,實(shí)現(xiàn)自定義的 RouteDefinitionLocator,目的是從 Nacos 讀取路由配置,構(gòu)建 RouteDefinition。這里以 JSON 格式配置,routesJson啟動(dòng)時(shí)由 Nacos 負(fù)責(zé)初始化配置,routesListener()方法在配置變更時(shí)觸發(fā),關(guān)鍵是變更后發(fā)送 RefreshRoutesEvent 事件,否則緩存不會(huì)刷新。

@Component
public class DynamicRouteDefinitionLocator implements RouteDefinitionLocator {

    @NacosConfig(dataId = "gateway-routes.json", group = "DEFAULT_GROUP")
    private String routesJson;
    private final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @Autowired
    private ApplicationEventPublisher eventPublisher;
    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;

    @NacosConfigListener(dataId = "gateway-routes.json", group = "DEFAULT_GROUP")
    public void routesListener(String data) {
        this.routesJson = data;
        // 發(fā)送路由刷新事件,getRouteDefinitions()會(huì)重新觸發(fā)
        eventPublisher.publishEvent(new RefreshRoutesEvent(this));
    }

    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        try {
            return Flux.fromIterable(OBJECT_MAPPER.readerForListOf(RouteDefinition.class).readValue(routesJson));
        } catch (JsonProcessingException e) {
            return Flux.empty();
        }
    }
}

在 Nacos 中配置,Data ID=gateway-routes.json,Group=DEFAULT_GROUP,內(nèi)容如下:

[
    {
        "id": "tb_route",
        "uri": "https://www.taobao.com",
        "predicates": [
            {
                "name": "Path",
                "args": {
                    "pattern": "/tb/**"
                }
            }
        ],
        "filters": [
            {
                "name": "StripPrefix",
                "args": {
                    "parts": "1"
                }
            }
        ]
    }
]

網(wǎng)關(guān)啟動(dòng),訪問(wèn)127.0.0.1:8080/tb的請(qǐng)求會(huì)被轉(zhuǎn)發(fā)到www.taobao.com。

修改路由配置如下,網(wǎng)關(guān)無(wú)需重啟,訪問(wèn)127.0.0.1:8080/jd的請(qǐng)求會(huì)被轉(zhuǎn)發(fā)到www.jd.com。

[
     {
        "id": "jd_route",
        "uri": "https://www.jd.com/",
        "predicates": [
            {
                "name": "Path",
                "args": {
                    "pattern": "/jd/**"
                }
            }
        ],
        "filters": [
            {
                "name": "StripPrefix",
                "args": {
                    "parts": "1"
                }
            }
        ]
    }
]

總結(jié)

Spring Cloud Gateway 動(dòng)態(tài)路由實(shí)現(xiàn)的核心思路,是通過(guò)自定義 RouteDefinitionLocator 從 Nacos 等配置中心動(dòng)態(tài)加載路由定義,并在配置變更時(shí)發(fā)布 RefreshRoutesEvent 事件觸發(fā) CachingRouteLocator 刷新路由緩存。

以上就是Spring Gateway動(dòng)態(tài)路由的實(shí)現(xiàn)方案的詳細(xì)內(nèi)容,更多關(guān)于Spring Gateway動(dòng)態(tài)路由的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring實(shí)現(xiàn)IoC和DI的方法詳解

    Spring實(shí)現(xiàn)IoC和DI的方法詳解

    IoC全稱(chēng)Inversion of Control (控制反轉(zhuǎn)) ,這里的控制其實(shí)是控制權(quán)的意思,可以理解為對(duì)象的獲取權(quán)力和方式發(fā)生了發(fā)轉(zhuǎn),DI依賴(lài)注?是?個(gè)過(guò)程,是指IoC容器在創(chuàng)建Bean時(shí), 去提供運(yùn)?時(shí)所依賴(lài)的資源,?資源指的就是對(duì)象,本文介紹了Spring實(shí)現(xiàn)IoC和DI的方法
    2024-08-08
  • Springboot優(yōu)化內(nèi)置服務(wù)器Tomcat優(yōu)化方式(underTow)

    Springboot優(yōu)化內(nèi)置服務(wù)器Tomcat優(yōu)化方式(underTow)

    本文詳細(xì)介紹了Spring Boot中Tomcat和Undertow服務(wù)器的配置和優(yōu)化,包括初始線程數(shù)、最大線程數(shù)、最小備用線程數(shù)、最大請(qǐng)求數(shù)等參數(shù)的優(yōu)化建議,以及在高并發(fā)場(chǎng)景下Undertow相對(duì)于Tomcat的優(yōu)勢(shì)
    2024-12-12
  • Gradle生成Jar的兩種方式小結(jié)

    Gradle生成Jar的兩種方式小結(jié)

    本文介紹使用Gradle創(chuàng)建不可執(zhí)行及可執(zhí)行的Jar包,包括將依賴(lài)Jar放入lib文件夾的方法,以及如何生成包含所有依賴(lài)的單一Jar文件,適用于SpringBoot和其他非SpringBoot項(xiàng)目,感興趣的可以了解一下
    2025-09-09
  • Java?API操作Hdfs的示例詳解

    Java?API操作Hdfs的示例詳解

    這篇文章主要介紹了Java?API操作Hdfs詳細(xì)示例,遍歷當(dāng)前目錄下所有文件與文件夾,可以使用listStatus方法實(shí)現(xiàn)上述需求,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • Java實(shí)現(xiàn)轉(zhuǎn)跳不同系統(tǒng)使用枚舉加switch的方式示例

    Java實(shí)現(xiàn)轉(zhuǎn)跳不同系統(tǒng)使用枚舉加switch的方式示例

    今天小編就為大家分享一篇關(guān)于Java實(shí)現(xiàn)轉(zhuǎn)跳不同系統(tǒng)使用枚舉加switch的方式示例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • Nacos配置中心設(shè)計(jì)原理分析

    Nacos配置中心設(shè)計(jì)原理分析

    今天分享一下Nacos配置變更的相關(guān)知識(shí)點(diǎn),現(xiàn)在使用Java生態(tài)如果使用微服務(wù),如果部署在K8s上,那么可能會(huì)使用ConfigMap來(lái)存儲(chǔ)配置文件,如果沒(méi)有使用K8s,那么基本上都使用Nacos來(lái)做配置中心,所以有必要了解一下Nacos的配置的知識(shí)點(diǎn),本文只是對(duì)其中的部分實(shí)現(xiàn)原理進(jìn)行分析
    2023-10-10
  • SpringBoot整合POI實(shí)現(xiàn)Excel文件讀寫(xiě)操作

    SpringBoot整合POI實(shí)現(xiàn)Excel文件讀寫(xiě)操作

    EasyExcel是一個(gè)基于Java的、快速、簡(jiǎn)潔、解決大文件內(nèi)存溢出的Excel處理工具,這篇文章主要介紹了SpringBoot整合POI實(shí)現(xiàn)Excel文件讀寫(xiě)操作,首先準(zhǔn)備環(huán)境進(jìn)行一系列操作,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2023-10-10
  • spring boot 使用@Async實(shí)現(xiàn)異步調(diào)用方法

    spring boot 使用@Async實(shí)現(xiàn)異步調(diào)用方法

    本篇文章主要介紹了spring boot 使用@Async實(shí)現(xiàn)異步調(diào)用方法,具有一定的參考價(jià)值,有興趣的可以了解一下。
    2017-04-04
  • Java項(xiàng)目開(kāi)啟遠(yuǎn)程調(diào)試的方法步驟(tomcat、springboot)

    Java項(xiàng)目開(kāi)啟遠(yuǎn)程調(diào)試的方法步驟(tomcat、springboot)

    這篇文章主要介紹了Java項(xiàng)目開(kāi)啟遠(yuǎn)程調(diào)試的方法步驟(tomcat、springboot),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 十五道tomcat面試題,為數(shù)不多的機(jī)會(huì)!

    十五道tomcat面試題,為數(shù)不多的機(jī)會(huì)!

    這篇文章主要介紹了十五道tomcat面試題,Tomcat的本質(zhì)是一個(gè)Servlet容器。一個(gè)Servlet能做的事情是:處理請(qǐng)求資源,并為客戶(hù)端填充response對(duì)象,需要的朋友可以參考下
    2021-08-08

最新評(píng)論