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

Spring?Cloud?Gateway動(dòng)態(tài)路由Apollo實(shí)現(xiàn)詳解

 更新時(shí)間:2022年10月29日 17:17:02   作者:weihubeats  
這篇文章主要為大家介紹了Spring?Cloud?Gateway動(dòng)態(tài)路由通過Apollo實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

背景

在之前我們了解的Spring Cloud Gateway配置路由方式有兩種方式

  • 通過配置文件
spring:
  cloud:
    gateway:
      routes:
        - id: test
          predicates:
            - Path=/ms/test/*
          filters:
            - StripPrefix=2
          uri: http://localhost:9000
  • 通過JavaBean
    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r.path("/ms/test/**")
                .filters(f -> f.stripPrefix(2))
                .uri("http://localhost:9000"))
                .build();
    }

但是遺憾的是這兩種方式都不支持動(dòng)態(tài)路由,都需要重啟服務(wù)。 所以我們需要對(duì)Spring Cloud Gateway進(jìn)行改造,在改造的時(shí)候我們就需要看看源碼了解下Spring Cloud Gateway的路由加載

路由的加載

我們之前分析了路由的加載主要在GatewayAutoConfigurationrouteDefinitionRouteLocator方法加載的

實(shí)際上最終獲取的路由信息都是在GatewayProperties這個(gè)配置類中

所以我們?cè)趧?dòng)態(tài)路由的時(shí)候修改GatewayProperties中的屬性即可,即

List<RouteDefinition> routes

List<FilterDefinition> defaultFilters

恰巧Spring Cloud Gateway也提供了相應(yīng)的get、set方法

實(shí)際如果我們修改了該屬性我們會(huì)發(fā)現(xiàn)并不會(huì)立即生效,因?yàn)槲覀儠?huì)發(fā)現(xiàn)還有一個(gè)RouteLocator就是CachingRouteLocator,并且在配置Bean的時(shí)候加了注解@Primary,說明最后使用額RouteLocator實(shí)際是CachingRouteLocator

CachingRouteLocator最后還是使用RouteDefinitionRouteLocator類加載的,也是就我們上面分析的,看CachingRouteLocator就知道是緩存作用

這里引用網(wǎng)上一張加載圖片

參考http://www.fzitv.net/article/219238.htm

所以看到這里我們知道我們還需要解決的一個(gè)問題就是更新緩存,如何刷新緩存呢,這里Spring Cloud Gateway利用spring的事件機(jī)制給我提供了擴(kuò)展

所以我們要做的事情就是這兩件事:

  • GatewayProperties
  • 刷新緩存

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

這里代碼參考 github.com/apolloconfi…

@Component
@Slf4j
public class GatewayPropertiesRefresher implements ApplicationContextAware, ApplicationEventPublisherAware {
	private static final String ID_PATTERN = "spring\\.cloud\\.gateway\\.routes\\[\\d+\\]\\.id";
	private static final String DEFAULT_FILTER_PATTERN = "spring\\.cloud\\.gateway\\.default-filters\\[\\d+\\]\\.name";
	private ApplicationContext applicationContext;
	private ApplicationEventPublisher publisher;
	@Autowired
	private GatewayProperties gatewayProperties;
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}
	@Override
	public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
		this.publisher = applicationEventPublisher;
	}
	@ApolloConfigChangeListener(value = "route.yml",interestedKeyPrefixes = "spring.cloud.gateway.")
	public void onChange(ConfigChangeEvent changeEvent) {
		refreshGatewayProperties(changeEvent);
	}
	/***
	 * 刷新org.springframework.cloud.gateway.config.PropertiesRouteDefinitionLocator中定義的routes
	 *
	 * @param changeEvent
	 * @return void
	 * @author ksewen
	 * @date 2019/5/21 2:13 PM
	 */
	private void refreshGatewayProperties(ConfigChangeEvent changeEvent) {
		log.info("Refreshing GatewayProperties!");
		preDestroyGatewayProperties(changeEvent);
		this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
		refreshGatewayRouteDefinition();
		log.info("GatewayProperties refreshed!");
	}
	/***
	 * GatewayProperties沒有@PreDestroy和destroy方法
	 * org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder#rebind(java.lang.String)中destroyBean時(shí)不會(huì)銷毀當(dāng)前對(duì)象
	 * 如果把spring.cloud.gateway.前綴的配置項(xiàng)全部刪除(例如需要?jiǎng)討B(tài)刪除最后一個(gè)路由的場(chǎng)景),initializeBean時(shí)也無法創(chuàng)建新的bean,則return當(dāng)前bean
	 * 若仍保留有spring.cloud.gateway.routes[n]或spring.cloud.gateway.default-filters[n]等配置,initializeBean時(shí)會(huì)注入新的屬性替換已有的bean
	 * 這個(gè)方法提供了類似@PreDestroy的操作,根據(jù)配置文件的實(shí)際情況把org.springframework.cloud.gateway.config.GatewayProperties#routes
	 * 和org.springframework.cloud.gateway.config.GatewayProperties#defaultFilters兩個(gè)集合清空
	 *
	 * @param
	 * @return void
	 * @author ksewen
	 * @date 2019/5/21 2:13 PM
	 */
	private synchronized void preDestroyGatewayProperties(ConfigChangeEvent changeEvent) {
		log.info("Pre Destroy GatewayProperties!");
		final boolean needClearRoutes = this.checkNeedClear(changeEvent, ID_PATTERN, this.gatewayProperties.getRoutes()
				.size());
		if (needClearRoutes) {
			this.gatewayProperties.setRoutes(new ArrayList<>());
		}
		final boolean needClearDefaultFilters = this.checkNeedClear(changeEvent, DEFAULT_FILTER_PATTERN, this.gatewayProperties.getDefaultFilters()
				.size());
		if (needClearDefaultFilters) {
			this.gatewayProperties.setDefaultFilters(new ArrayList<>());
		}
		log.info("Pre Destroy GatewayProperties finished!");
	}
	private void refreshGatewayRouteDefinition() {
		log.info("Refreshing Gateway RouteDefinition!");
		this.publisher.publishEvent(new RefreshRoutesEvent(this));
		log.info("Gateway RouteDefinition refreshed!");
	}
	/***
	 * 根據(jù)changeEvent和定義的pattern匹配key,如果所有對(duì)應(yīng)PropertyChangeType為DELETED則需要清空GatewayProperties里相關(guān)集合
	 *
	 * @param changeEvent
	 * @param pattern
	 * @param existSize
	 * @return boolean
	 * @author ksewen
	 * @date 2019/5/23 2:18 PM
	 */
	private boolean checkNeedClear(ConfigChangeEvent changeEvent, String pattern, int existSize) {
		return changeEvent.changedKeys().stream().filter(key -> key.matches(pattern))
				.filter(key -> {
					ConfigChange change = changeEvent.getChange(key);
					return PropertyChangeType.DELETED.equals(change.getChangeType());
				}).count() == existSize;
	}
}

然后我們?cè)赼pollo添加namespace:route.yml

配置內(nèi)容如下:

spring:
  cloud:
    gateway:
      routes:
        - id: test
          predicates:
            - Path=/ms/test/*
          filters:
            - StripPrefix=2
          uri: http://localhost:9000

然后我們可以通過訪問地址: http:localhost:8080/ms/test/health

看刪除后是否是404,加上后是否可以正常動(dòng)態(tài)路由

值得注意的是上面@ApolloConfigChangeListener中如果沒有添加新的namespacevalue可以不用填寫,如果配置文件是yml配置文件,在監(jiān)聽的時(shí)候需要指定文件后綴

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

相關(guān)文章

  • java 獲取字節(jié)碼文件的幾種方法總結(jié)

    java 獲取字節(jié)碼文件的幾種方法總結(jié)

    這篇文章主要介紹了java 獲取字節(jié)碼文件的幾種方法總結(jié)的相關(guān)資料,這里總結(jié)了三種方法幫助大家實(shí)現(xiàn)該功能,需要的朋友可以參考下
    2017-08-08
  • SpringBoot自動(dòng)配置原理,你真的懂嗎?(簡(jiǎn)單易懂)

    SpringBoot自動(dòng)配置原理,你真的懂嗎?(簡(jiǎn)單易懂)

    這篇文章主要介紹了SpringBoot自動(dòng)配置原理,你真的懂嗎?本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-05-05
  • Netty解碼器LengthFieldBasedFrameDecoder詳解

    Netty解碼器LengthFieldBasedFrameDecoder詳解

    這篇文章主要介紹了Netty解碼器LengthFieldBasedFrameDecoder的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • Java連接sftp服務(wù)器實(shí)現(xiàn)上傳下載功能

    Java連接sftp服務(wù)器實(shí)現(xiàn)上傳下載功能

    這篇文章主要介紹了java連接sftp服務(wù)器實(shí)現(xiàn)上傳下載,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • 解決IDEA占用C盤空間過大的問題

    解決IDEA占用C盤空間過大的問題

    這篇文章主要介紹了解決IDEA占用C盤空間過大的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Java?數(shù)據(jù)庫(kù)連接池Druid?的介紹

    Java?數(shù)據(jù)庫(kù)連接池Druid?的介紹

    這篇文章主要給大家分享的是?Java?數(shù)據(jù)庫(kù)連接池Druid?的介紹,Druid是一個(gè)JDBC組件,它包括三部分:?DruidDriver?代理Driver,能夠提供基于Filter-Chain模式的插件體系。?DruidDataSource?高效可管理的數(shù)據(jù)庫(kù)連接池,下面來看看文中的詳細(xì)內(nèi)容,需要的朋友也可以參考一下
    2021-11-11
  • SpringBoot項(xiàng)目啟動(dòng)報(bào)錯(cuò)"找不到或無法加載主類"的解決方法

    SpringBoot項(xiàng)目啟動(dòng)報(bào)錯(cuò)"找不到或無法加載主類"的解決方法

    在使用 IntelliJ IDEA 開發(fā)基于 Spring Boot 框架的 Java 程序時(shí),可能會(huì)出現(xiàn)找不到或無法加載主類 com.example.springboot.SpringbootApplication的錯(cuò)誤提示,下面我們來看看如何解決吧
    2025-03-03
  • 用Java打印九九除法表代碼分析

    用Java打印九九除法表代碼分析

    這篇文章主要介紹了如何用Java語言打印九九除法表,包括其使用的源代碼,需要的朋友可以參考下。
    2017-08-08
  • Java遍歷HashMap的6種常見方式

    Java遍歷HashMap的6種常見方式

    這篇文章主要給大家介紹了關(guān)于Java遍歷HashMap的6種常見方式,方法包括使用keySet()、entrySet()、forEach()、迭代器以及分別遍歷鍵和值,文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下
    2025-05-05
  • 基于SpringBoot2.0版本與老版本的區(qū)別

    基于SpringBoot2.0版本與老版本的區(qū)別

    這篇文章主要介紹了SpringBoot2.0版本與老版本的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10

最新評(píng)論

辽宁省| 阿鲁科尔沁旗| 公安县| 荥阳市| 和平县| 彭山县| 湖南省| 利辛县| 安国市| 上虞市| 阜阳市| 永登县| 灌云县| 连城县| 钦州市| 乌拉特中旗| 咸阳市| 临城县| 荆州市| 璧山县| 保康县| 横峰县| 项城市| 淄博市| 兴化市| 孟村| 克东县| 耒阳市| 尚志市| 井冈山市| 德清县| 扬中市| 延庆县| 紫阳县| 三亚市| 怀来县| 陆良县| 台前县| 平凉市| 邵阳市| 哈巴河县|