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

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

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

前言

前陣子時間和朋友聊天,他們有個sass微服務,因為之前拆分過細,導致服務不僅調用鏈路過長,而且浪費服務資源,他們后面做了服務合并的重構,并即將上線。他覺得上線不能直接把線上的租戶都全切到重構版的sass微服務,而是需要實現(xiàn)如下的效果

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

實現(xiàn)關鍵

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

實現(xiàn)步驟

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

1、項目POM引入相關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();
    }
}

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

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

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

測試灰度路由

1、測試微服務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、測試微服務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;
    }

}

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

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

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

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

4、測試

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

2、當tenantId滿足10000&10001&10002的其中任意值時

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

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

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

該配置主要是為了讓我們自定義的PropertiesRouteDefinitionLocator 的BEAN失效,這樣他就會按默認的加載邏輯,即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ù)值調低。我們再驗證下

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

總結

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

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

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

相關文章

  • springboot中如何通過main方法調用service或dao

    springboot中如何通過main方法調用service或dao

    這篇文章主要介紹了springboot中如何通過main方法調用service或dao,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • SpringBoot2.x 整合 thumbnailator 圖片處理的示例代碼

    SpringBoot2.x 整合 thumbnailator 圖片處理的示例代碼

    這篇文章主要介紹了SpringBoot2.x 之整合 thumbnailator 圖片處理,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • Java 八種基本類型和基本類型封裝類

    Java 八種基本類型和基本類型封裝類

    八種基本數(shù)據(jù)類型分別是:int、short、float、double、long、boolean、byte、char;下面跟隨腳本之家小編一起學習java八種基本類型和基本類型封裝類
    2017-09-09
  • java程序中foreach用法示例

    java程序中foreach用法示例

    這篇文章主要介紹了java程序中foreach用法示例,需要的朋友可以參考下
    2014-04-04
  • scala中常用特殊符號詳解

    scala中常用特殊符號詳解

    這篇文章主要介紹了scala中常用特殊符號詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-06-06
  • Autowired的注入過程源碼解析

    Autowired的注入過程源碼解析

    這篇文章主要為大家介紹了Autowired的注入過程源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • Spring boot調用Oracle存儲過程的兩種方式及完整代碼

    Spring boot調用Oracle存儲過程的兩種方式及完整代碼

    這篇文章主要給大家介紹了關于Spring boot調用Oracle存儲過程的兩種方式及完整代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2020-08-08
  • JDK1.8下載、安裝和環(huán)境配置超詳細教程(最新最完整)

    JDK1.8下載、安裝和環(huán)境配置超詳細教程(最新最完整)

    jdk1.8是一款功能強大的Java語音軟件開發(fā)工具包,JDK是學好Java的第一步,本文重點給大家介紹JDK1.8下載、安裝和環(huán)境配置教程,需要的朋友可以參考下
    2022-11-11
  • Java數(shù)據(jù)長度獲取方式對比之length屬性、length()和size()方法詳解

    Java數(shù)據(jù)長度獲取方式對比之length屬性、length()和size()方法詳解

    在Java編程語言中l(wèi)ength、length()和size()是三個常見的用來獲取不同數(shù)據(jù)類型對象長度或大小的方法,但它們各自適用于不同的上下文,這篇文章主要給大家介紹了關于Java數(shù)據(jù)長度獲取方式對比之length屬性、length()和size()方法詳解
    2024-07-07
  • Maven導入依賴時爆紅的幾種解決方法

    Maven導入依賴時爆紅的幾種解決方法

    使用idea建立maven項目,maven導入依賴報紅,本文主要介紹了Maven導入依賴時爆紅的幾種解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-04-04

最新評論