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

springcloud?gateway實(shí)現(xiàn)簡易版灰度路由步驟詳解

 更新時間:2023年11月22日 10:08:23   作者:linyb極客之路  
這篇文章主要為大家介紹了springcloud?gateway實(shí)現(xiàn)簡易版灰度路由步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

前陣子時間和朋友聊天,他們有個sass微服務(wù),因?yàn)橹安鸱诌^細(xì),導(dǎo)致服務(wù)不僅調(diào)用鏈路過長,而且浪費(fèi)服務(wù)資源,他們后面做了服務(wù)合并的重構(gòu),并即將上線。他覺得上線不能直接把線上的租戶都全切到重構(gòu)版的sass微服務(wù),而是需要實(shí)現(xiàn)如下的效果

他就問我說,有沒有啥開源平臺可以快速支持,因?yàn)橹皶r間都耗費(fèi)在重構(gòu)業(yè)務(wù)上,這塊就沒考慮周全,現(xiàn)在臨近上線,預(yù)留的時間不多。后面和他細(xì)聊,得知他們這套sass服務(wù),租戶不多,其次他們微服務(wù)API網(wǎng)關(guān)是springcloud gateway。了解到這個信息后,我就跟他說直接拿API網(wǎng)關(guān)稍微改造一下,就可以達(dá)到他目前想要的效果。下面就來聊聊如何利用springcloud gateway實(shí)現(xiàn)簡易版灰度路由

實(shí)現(xiàn)關(guān)鍵

?springcloud gateway 自定義斷言工廠 + 開啟服務(wù)發(fā)現(xiàn)路由定位器 + PropertiesRouteDefinitionLocator 生成的route與DiscoveryClientRouteDefinitionLocator生成route path映射保持一致

實(shí)現(xiàn)步驟

注: 本示例注冊中心使用eureka,其他注冊中心也可以

1、項(xiàng)目POM引入相關(guān)GAV

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

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

2、自定義斷言工廠

@Slf4j
public class ParamRoutePredicateFactory
        extends AbstractRoutePredicateFactory<ParamRoutePredicateFactory.Config> {
    public static final String PARAM_KEY = "param";
    public static final String PARAM_VALUES = "values";
    public static final String SEPARATOR = "&";
    public ParamRoutePredicateFactory() {
        super(Config.class);
    }
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(PARAM_KEY,PARAM_VALUES);
    }
    @Override
    public ShortcutType shortcutType() {
        return ShortcutType.DEFAULT;
    }
    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return exchange -> isHitTargetParam(config, exchange);
    }
    private boolean isHitTargetParam(Config config, ServerWebExchange exchange) {
        boolean hasParamkey = HttpRequestParserUtils.hasKey(config.param.toLowerCase(), exchange);
        if(hasParamkey){
            String value = HttpRequestParserUtils.parse(config.param.toLowerCase(), exchange);
            if(StringUtils.hasText(config.values) && config.values.contains(SEPARATOR)){
                String[] valueArr = config.values.split(SEPARATOR);
                for (String targetValue : valueArr) {
                    if(targetValue.equals(value)){
                        log.info(">>>>>>>>>>>>>>>>>>>> Request Key --> 【{}】 Hit Value --> 【{}】 In Target Values 【{}】", config.param,value, config.values);
                        return true;
                    }
                }
            }
        }
        return false;
    }
    @Validated
    public static class Config {
        @NotEmpty
        private String param;
        private String values;
        public String getParam() {
            return param;
        }
        public Config setParam(String param) {
            this.param = param;
            return this;
        }
        public String getValues() {
            return values;
        }
        public Config setValues(String values) {
            this.values = values;
            return this;
        }
        @Override
        public String toString() {
            return "Config{" +
                    "param='" + param + '\'' +
                    ", values=" + values +
                    '}';
        }
    }

3、配置斷言工程自動裝配

@Configuration
@ConditionalOnProperty(name = "spring.cloud.gateway.ext.enabled", havingValue = "true",matchIfMissing = true)
@AutoConfigureBefore({ GatewayDiscoveryClientAutoConfiguration.class})
@ConditionalOnClass(DispatcherHandler.class)
public class GatewayAutoExtConfiguration {
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(name = "spring.cloud.gateway.properties-route-definition-locator.load.first", havingValue = "true",matchIfMissing = true)
    public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(
            GatewayProperties properties) {
        return new PropertiesRouteDefinitionLocator(properties);
    }
    @Bean
    @ConditionalOnMissingBean
    public ParamRoutePredicateFactory paramRoutePredicateFactory(){
        return new ParamRoutePredicateFactory();
    }
}

注: 這邊有些細(xì)節(jié)點(diǎn)說明一下,該配置先于GatewayDiscoveryClientAutoConfiguration裝配,主要是實(shí)現(xiàn)PropertiesRouteDefinitionLocator 比DiscoveryClientRouteDefinitionLocator優(yōu)先加載,為啥這么做,后面說

4、在application.yml文件開啟服務(wù)發(fā)現(xiàn)路由定位器

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true

測試灰度路由

1、測試微服務(wù)comsumer1

a、測試配置

spring:
  application:
    name: ${APPLICATION_NAME:comsumer}
  profiles:
    active: eureka

b、編寫測試控制器

@RestController
@RequestMapping("echo")
public class EchoController {

    @GetMapping("{message}")
    public String echo(@PathVariable("message") String message){
        System.out.println("comsumer:" + message);
        return "comsumer :" + message;
    }

}

2、測試微服務(wù)comsumer2

a、測試配置

spring:
  application:
    name: ${APPLICATION_NAME:otherComsumer}
  profiles:
    active: eureka

b、編寫測試控制器

@RestController
@RequestMapping("echo")
public class EchoController {

    @GetMapping("{message}")
    public String echo(@PathVariable("message") String message){
        System.out.println("otherComsumer:" + message);
        return "otherComsumer :" + message;
    }

}

注:這個兩個服務(wù)主要用來模擬新老集群數(shù)據(jù)

3、網(wǎng)關(guān)添加測試路由配置

spring:
  cloud:
    gateway:
      routes:
        - id: route-springboot-gray-comsumer-to-other-comsumer
          uri: http://localhost:8083
          predicates:
            - Path=/comsumer/**
              ## 多個租戶用&分割
            - Param=tenantId,10000&10001&10002
          filters:
            - StripPrefix=1
          order: 0

注: 這個配置心細(xì)的朋友,可能會發(fā)現(xiàn)貓膩了。這個PATH和開啟服務(wù)發(fā)現(xiàn)路由定位器生成的PATH是一樣,我們再來說下為啥上面實(shí)現(xiàn)PropertiesRouteDefinitionLocator 比DiscoveryClientRouteDefinitionLocator優(yōu)先加載,因?yàn)槁酚啥ㄎ黄鳟a(chǎn)生的route是有順序性,而當(dāng)PropertiesRouteDefinitionLocator 和DiscoveryClientRouteDefinitionLocator配置的PATH一樣時,如果DiscoveryClientRouteDefinitionLocator優(yōu)于PropertiesRouteDefinitionLocator加載,就會導(dǎo)致訪問相同路徑時,會優(yōu)先訪問DiscoveryClientRouteDefinitionLocator生成的route,就不會去走我們自定義配置的route。不過這個結(jié)論為時尚早,留個懸念,待會說明

4、測試

1、當(dāng)我們請求頭、cookie、query不加tenantId參數(shù)或者tenantId不為測試10000&10001&10002的值時

2、當(dāng)tenantId滿足10000&10001&10002的其中任意值時

可以發(fā)現(xiàn)已經(jīng)路由到我們配置的地址

3、當(dāng)我們對網(wǎng)關(guān)做如下配置

spring:
  cloud:
    gateway:
      properties-route-definition-locator:
        load:
          first: false

該配置主要是為了讓我們自定義的PropertiesRouteDefinitionLocator 的BEAN失效,這樣他就會按默認(rèn)的加載邏輯,即DiscoveryClientRouteDefinitionLocator會先于PropertiesRouteDefinitionLocator 加載

同時路由做如下配置

spring:
  cloud:
    gateway:
      routes:
        - id: route-springboot-gray-comsumer-to-other-comsumer
          uri: http://localhost:8083
          predicates:
            - Path=/comsumer/**
            ## 多個租戶用&分割
            - Param=tenantId,10000&10001&10002
          filters:
            - StripPrefix=1
          order: -1000

即將order的數(shù)值調(diào)低。我們再驗(yàn)證下

會發(fā)現(xiàn)效果和我們之前演示的效果是一樣的。其實(shí)這邊實(shí)現(xiàn)路由的關(guān)鍵點(diǎn),是抓住route的順序性,相同路徑,誰先加載,誰先路由。所以我實(shí)現(xiàn)PropertiesRouteDefinitionLocator 比DiscoveryClientRouteDefinitionLocator會優(yōu)先加載,就是為了實(shí)現(xiàn)當(dāng)path一樣時,PropertiesRouteDefinitionLocator 生成的route都比DiscoveryClientRouteDefinitionLocator生成route優(yōu)先,當(dāng)然也可以通過配置order改變這個順序

總結(jié)

?本示例主要講解如何利用springcloud gateway實(shí)現(xiàn)簡易版灰度路由,不過該實(shí)現(xiàn)比較適用于灰度規(guī)則比較簡單的場景。如果需要復(fù)雜規(guī)則,就需要深層次的定制,或者采用用istio來實(shí)現(xiàn)也是一個挺好的選擇

https://github.com/lyb-geek/springboot-learning/tree/master/springboot-gateway-simple-gray

以上就是springcloud gateway實(shí)現(xiàn)簡易版灰度路由步驟詳解的詳細(xì)內(nèi)容,更多關(guān)于spring cloud gateway灰度路由的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解Spring Cloud中Hystrix的請求合并

    詳解Spring Cloud中Hystrix的請求合并

    這篇文章主要介紹了詳解Spring Cloud中Hystrix的請求合并,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • Eclipse最新版使用過程中遇到的問題總結(jié)

    Eclipse最新版使用過程中遇到的問題總結(jié)

    這篇文章主要介紹了Eclipse最新版使用過程中遇到的問題總結(jié)的相關(guān)資料,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),具有參考借鑒價值,需要的朋友可以參考下
    2016-09-09
  • Java連接數(shù)據(jù)庫的步驟介紹

    Java連接數(shù)據(jù)庫的步驟介紹

    這篇文章介紹了Java連接數(shù)據(jù)庫的步驟,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • Java中RedisUtils工具類的使用

    Java中RedisUtils工具類的使用

    本文主要介紹了Java中RedisUtils工具類的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Java中的內(nèi)部類使用詳情

    Java中的內(nèi)部類使用詳情

    說起內(nèi)部類這個詞,想必很多人都不陌生,但是又會覺得不熟悉。原因是平時編寫代碼時可能用到的場景不多,用得最多的是在有事件監(jiān)聽的情況下,并且即使用到也很少去總結(jié)內(nèi)部類的用法。今天我們就來一探究竟
    2022-03-03
  • 深入解析Java編程中的StringBuffer與StringBuider

    深入解析Java編程中的StringBuffer與StringBuider

    這篇文章主要介紹了Java編程中的StringBuffer與StringBuider,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • Java使用Jedis操作Redis服務(wù)器的實(shí)例代碼

    Java使用Jedis操作Redis服務(wù)器的實(shí)例代碼

    本篇文章主要介紹了Java使用Jedis操作Redis服務(wù)器的實(shí)例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • Java synchronized 關(guān)鍵字原理、用法、優(yōu)化與實(shí)戰(zhàn)指南

    Java synchronized 關(guān)鍵字原理、用法、優(yōu)化與實(shí)戰(zhàn)指南

    文章主要討論了schronized關(guān)鍵字在Java中的核心定義和使用場景,synchronized用于實(shí)現(xiàn)線程互斥和同步,保證了原子操作、可見性和有序性,它通過互斥鎖實(shí)現(xiàn)線程安全問題的解決方案,感興趣的朋友一起看看吧
    2026-04-04
  • Spring boot集成Kafka消息中間件代碼實(shí)例

    Spring boot集成Kafka消息中間件代碼實(shí)例

    這篇文章主要介紹了Spring boot集成Kafka消息中間件代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-05-05
  • 淺談Maven的安裝及修改為阿里云下載依賴

    淺談Maven的安裝及修改為阿里云下載依賴

    下面小編就為大家?guī)硪黄獪\談Maven的安裝及修改為阿里云下載依賴。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05

最新評論

普兰县| 德令哈市| 杭锦旗| 潼南县| 上林县| 双辽市| 陇川县| 望奎县| 同心县| 锡林浩特市| 宾阳县| 临潭县| 辉县市| 长治县| 湘阴县| 织金县| 霸州市| 南汇区| 通许县| 伊吾县| 新疆| 民和| 奈曼旗| 南汇区| 尤溪县| 浦县| 承德市| 从化市| 甘洛县| 罗甸县| 军事| 霍林郭勒市| 永泰县| 盱眙县| 淮北市| 桐乡市| 蒲城县| 资兴市| 定兴县| 华宁县| 长乐市|