最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Gateway動態(tài)路由的實現(xiàn)方案

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

前沿

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

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

何為路由

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

  • id:路由唯一標(biāo)識
  • uri:轉(zhuǎn)發(fā)的目標(biāo)地址
  • order:路由順序
  • predicate:謂詞集合,符合條件的請求才會被路由
  • gatewayFilters:過濾器集合,允許對請求轉(zhuǎn)發(fā)前后對請求和響應(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;
}

路由是怎么來的?

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

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

子類有三個:

CachingRouteLocator

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

CompositeRouteLocator

RouteLocator 的裝飾器,將一組 RouteLocator 合并成一個。

RouteDefinitionRouteLocator

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

RouteDefinition

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

RouteDefinition 是怎么來的?

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

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

常見的子類有:

PropertiesRouteDefinitionLocator

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

InMemoryRouteDefinitionRepository

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

DiscoveryClientRouteDefinitionLocator

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

CompositeRouteDefinitionLocator

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

RouteLocator工作流程

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

簡單來說,RouteDefinitionLocator 負(fù)責(zé)提供 RouteDefinition 路由定義對象,RouteLocator 再根據(jù) RouteDefinition 構(gòu)建路由對象。

項目引入spring-cloud-starter-gateway依賴后,Spring 啟動時會觸發(fā) Gateway 的自動裝配,

org.springframework.cloud.gateway.config.GatewayAutoConfiguration類。

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

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

默認(rèn)的 RouteDefinitionLocator 有兩個,分別是:PropertiesRouteDefinitionLocator 和 InMemoryRouteDefinitionRepository。前者讀取配置文件來生成 RouteDefinition,后者使用 Map 來維護(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 有了,接下來就是 RouteLocator。默認(rèn)會自動裝配 RouteDefinitionRouteLocator 和 CachingRouteLocator,前者根據(jù) RouteDefinition 來構(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)));
}

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

默認(rèn)情況下,Gateway 會通過 CachingRouteLocator 來優(yōu)化性能。因為根據(jù) RouteDefinition 來構(gòu)建路由還是有不小開銷的,CachingRouteLocator 會把構(gòu)建好的 List 緩存下來。

同時,它實現(xiàn)了 ApplicationListener,通過監(jiān)聽 RefreshRoutesEvent 事件來刷新路由。

動態(tài)路由實現(xiàn)

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

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

路由配置推薦 Nacos,因為它有變更通知。通過監(jiān)聽配置,即可在配置變更時,第一時間刷新路由,讓新的路由生效。

首先,引入依賴

<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>

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

@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()會重新觸發(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)啟動,訪問127.0.0.1:8080/tb的請求會被轉(zhuǎn)發(fā)到www.taobao.com。

修改路由配置如下,網(wǎng)關(guān)無需重啟,訪問127.0.0.1:8080/jd的請求會被轉(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 動態(tài)路由實現(xiàn)的核心思路,是通過自定義 RouteDefinitionLocator 從 Nacos 等配置中心動態(tài)加載路由定義,并在配置變更時發(fā)布 RefreshRoutesEvent 事件觸發(fā) CachingRouteLocator 刷新路由緩存。

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

相關(guān)文章

  • Springboot接口如何接收多個文件以及如何將其保存到服務(wù)器

    Springboot接口如何接收多個文件以及如何將其保存到服務(wù)器

    本文給大家介紹了Springboot接口如何接收多個文件以及如何將其保存到服務(wù)器,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2026-05-05
  • spring利用squertz實現(xiàn)定時任務(wù)

    spring利用squertz實現(xiàn)定時任務(wù)

    spring squertz是一個強(qiáng)大的定時任務(wù)處理方式。下面這篇文章主要介紹了spring利用squertz實現(xiàn)定時任務(wù)的相關(guān)資料,文中介紹的很詳細(xì),對大家具有一定的參考借鑒價值,需要的朋友們下面來一起看看吧。
    2017-01-01
  • Java源碼解析之object類

    Java源碼解析之object類

    前些天看到別人討論閱讀源碼有什么用這個問題,有一句話說的特別好:學(xué)習(xí)別人實現(xiàn)某個功能的設(shè)計思路,來提高自己的編程水平。本文主要介紹了Java源碼解析之object類,需要的朋友可以參考。
    2017-10-10
  • String字符串拼接方法concat和+的效率對比

    String字符串拼接方法concat和+的效率對比

    這篇文章主要介紹了String字符串拼接方法concat和+的效率對比,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • springBoot整合redis做緩存具體操作步驟

    springBoot整合redis做緩存具體操作步驟

    緩存主要是將數(shù)據(jù)存在計算機(jī)的內(nèi)存當(dāng)中,以便于在使用的時候是可以實現(xiàn)快速讀取使用,它的快也是相對于硬盤讀取而言,這篇文章主要給大家介紹了關(guān)于springBoot整合redis做緩存的具體操作步驟,需要的朋友可以參考下
    2024-04-04
  • 詳解如何在springcloud分布式系統(tǒng)中實現(xiàn)分布式鎖

    詳解如何在springcloud分布式系統(tǒng)中實現(xiàn)分布式鎖

    最近在看分布式鎖的資料,本文就介紹一下利用springcloud結(jié)合redis實現(xiàn)分布式鎖,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Java中值傳遞和引用傳遞的區(qū)別

    Java中值傳遞和引用傳遞的區(qū)別

    這篇文章主要介紹了Java中值傳遞和引用傳遞的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Java畢業(yè)設(shè)計實戰(zhàn)之圖片展覽館管理系統(tǒng)的實現(xiàn)

    Java畢業(yè)設(shè)計實戰(zhàn)之圖片展覽館管理系統(tǒng)的實現(xiàn)

    這是一個使用了java+Springboot+SpringMVC+JPA+Jsp+maven+mysql開發(fā)的圖片展覽館管理系統(tǒng),是一個畢業(yè)設(shè)計的實戰(zhàn)練習(xí),具有圖片展覽管理該有的所有功能,感興趣的朋友快來看看吧
    2022-01-01
  • Java中的對稱加密詳解

    Java中的對稱加密詳解

    大家好,本篇文章主要講的是Java中的對稱加密詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • java中的構(gòu)造函數(shù)什么時候被調(diào)用執(zhí)行

    java中的構(gòu)造函數(shù)什么時候被調(diào)用執(zhí)行

    這篇文章主要介紹了java中的構(gòu)造函數(shù)什么時候被調(diào)用執(zhí)行問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03

最新評論

彩票| 荥经县| 太仆寺旗| 雷州市| 阳信县| 松阳县| 许昌县| 渝中区| 青河县| 乳山市| 祁阳县| 阳春市| 资阳市| 江山市| 夏津县| 泗洪县| 峡江县| 天峨县| 东辽县| 天祝| 万盛区| 娄烦县| 临朐县| 定远县| 教育| 随州市| 峨眉山市| 澄城县| 右玉县| 普安县| 邻水| 绵阳市| 浦东新区| 竹北市| 东城区| 德江县| 华安县| 玛曲县| 山西省| 台东县| 兴义市|