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

SpringCloud的全鏈路灰度發(fā)布方案詳解

 更新時間:2023年09月01日 09:04:53   作者:959y  
這篇文章主要介紹了SpringCloud的全鏈路灰度發(fā)布方案詳解,灰度發(fā)布(又名金絲雀發(fā)布)是指在黑與白之間,能夠平滑過渡的一種發(fā)布方式,灰度發(fā)布可以保證系統(tǒng)的穩(wěn)定性,?在初始灰度的時候可以發(fā)現(xiàn),?調整問題,?保證其影響度,需要的朋友可以參考下

1.什么是灰度發(fā)布

灰度發(fā)布(又名金絲雀發(fā)布)是指在黑與白之間,能夠平滑過渡的一種發(fā)布方式。

在上面可以進行A/B測試, 即讓一部分用戶繼續(xù)用產品特性A, 一部分用戶使用產品特性B, 如果用戶B沒有反對意見的話, 那么會逐漸擴大范圍, 把用戶都往特性B 上改。

灰度發(fā)布可以保證系統(tǒng)的穩(wěn)定性, 在初始灰度的時候可以發(fā)現(xiàn), 調整問題, 保證其影響度。

2.什么是全鏈路灰度發(fā)布

網(wǎng)關灰度發(fā)布:

網(wǎng)關通過灰度標記路由到文章服務B, 至于從文章服務B到評論服務是通過openfeign內部調用的, 默認無法實現(xiàn)灰度標記grayTag的透傳, 因此文章服務B 最終調用的是評論服務A, 并不是評論服務B。

在這里插入圖片描述

全鏈路灰度發(fā)布需要實現(xiàn)的是:

  • 網(wǎng)關通過灰度標記將部分流量轉發(fā)給文章服務B
  • 文章服務B能夠實現(xiàn)灰度標記grayTag的透傳,最終調用評論服務B

全鏈路灰度發(fā)布需要實現(xiàn)兩個點:

  • 網(wǎng)關路由轉發(fā)實現(xiàn)灰度發(fā)布
  • 服務內部通過openFeign調用實現(xiàn)灰度發(fā)布(透傳灰度標記grayTag)。

3.網(wǎng)關層的灰度路由轉發(fā)

Ribbon+Spring Cloud Gateway 進行改造負載均衡策略實現(xiàn)灰度發(fā)布.

  • 在網(wǎng)關的全局過濾器中根據(jù)業(yè)務規(guī)則給流量打上灰度標記
  • 將灰度標記放入請求頭中,傳遞給下游服務
  • 改造Ribbon負載均衡策略,根據(jù)流量標記從注冊中心獲取灰度服務
  • 請求路由轉發(fā)

根據(jù)什么條件打上灰度標記

這個需要根據(jù)實際的業(yè)務需要,比如根據(jù)用戶所在的地區(qū)、使用客戶端類型、隨機截取流量

這里我將直接使用一個標記grayTag,只要客戶端請求頭中攜帶了這個參數(shù),并且設置為true,則走灰度發(fā)布邏輯。

grayTag=true

為什么要在請求頭中添加灰度標記傳遞給下游服務

這一步非常關鍵,實現(xiàn)灰度標記透傳給下游服務的關鍵,將灰度標記放在請求頭中,下游服務只需要從請求頭中獲取灰度標記便知道是否是灰度發(fā)布,這個和令牌中繼一個原理。

灰度標記如何請求隔離

Spring MVC中的每個請求都是開啟一個線程進行處理,因此可以將灰度標記放置在 ThreadLocal 中進行線程隔離。

如何知道注冊中心的服務哪個是灰度服務

Nacos支持在服務中配置一些元數(shù)據(jù),可以將灰度標記配置在元數(shù)據(jù)中,這樣就能區(qū)分哪些是灰度服務,哪些是正常服務。

如何針對特定的服務進行灰度發(fā)布

在這里插入圖片描述

我們知道網(wǎng)關路由中配置的服務很多,如何只針對文章服務進行灰度發(fā)布

只需要將自定義的Ribbon灰度發(fā)布規(guī)則只對文章服務生效 利用注解RibbonClients, 指定特定微服務

@RibbonClients(value ={
        //只對文章服務進行灰度發(fā)布
        @RibbonClient(value = "article-server",configuration = GrayRuleConfig.class)
} )
@SpringBootApplication
public class GatewayApplication {
}

@RibbonClients其中有一個屬性defaultConfiguration,一旦使用這個屬性,那么灰度發(fā)布的策略對網(wǎng)關路由中配置的所有服務都將生效。

具體如何實現(xiàn)

網(wǎng)關中首先需要定義一個全局過濾器:

public class GlobalGrayFilter implements GlobalFilter{
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
         //① 解析請求頭,查看是否存在灰度發(fā)布的請求頭信息,如果存在則將其放置在ThreadLocal中
        HttpHeaders headers = exchange.getRequest().getHeaders();
        if (headers.containsKey(GrayConstant.GRAY_HEADER)){
            String gray = headers.getFirst(GrayConstant.GRAY_HEADER);
            if (StrUtil.equals(gray,GrayConstant.GRAY_VALUE)){
                //②設置灰度標記
                GrayRequestContextHolder.setGrayTag(true);
            }
        }
       //③ 將灰度標記放入請求頭中
   ServerHttpRequest tokenRequest = exchange.getRequest().mutate()
    //將灰度標記傳遞過去
    .header(GrayConstant.GRAY_HEADER,GrayRequestContextHolder.getGrayTag().toString())
    .build();
            ServerWebExchange build = exchange.mutate().request(tokenRequest).build();
            return chain.filter(build);
    }
}

GrayRule:

public class GrayRule extends ZoneAvoidanceRule {
    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {
    }
    @Override
    public Server choose(Object key) {
        try {
            //從ThreadLocal中獲取灰度標記
            boolean grayTag = GrayRequestContextHolder.getGrayTag().get();
            //獲取所有可用服務
            List<Server> serverList = this.getLoadBalancer().getReachableServers();
            //灰度發(fā)布的服務
            List<Server> grayServerList = new ArrayList<>();
            //正常的服務
            List<Server> normalServerList = new ArrayList<>();
            for(Server server : serverList) {
                NacosServer nacosServer = (NacosServer) server;
                //從nacos中獲取元素劇進行匹配
                if(nacosServer.getMetadata().containsKey(GrayConstant.GRAY_HEADER)
                        && nacosServer.getMetadata().get(GrayConstant.GRAY_HEADER).equals(GrayConstant.GRAY_VALUE)) {
                    grayServerList.add(server);
                } else {
                    normalServerList.add(server);
                }
            }
            //如果被標記為灰度發(fā)布,則調用灰度發(fā)布的服務
            if(grayTag) {
                return originChoose(grayServerList,key);
            } else {
                return originChoose(normalServerList,key);
            }
        } finally {
            //清除灰度標記
            GrayRequestContextHolder.remove();
        }
    }
    private Server originChoose(List<Server> noMetaServerList, Object key) {
        Optional<Server> server = getPredicate().chooseRoundRobinAfterFiltering(noMetaServerList, key);
        if (server.isPresent()) {
            return server.get();
        } else {
            return null;
        }
    }
}
  • 獲取灰度標記
  • 從Nacos注冊中心獲取灰度服務和正常服務
  • 根據(jù)灰度標記去判斷,如果灰度發(fā)布則選擇特定的灰度服務進行轉發(fā)

定義一個配置類,注入改造的灰度策略GrayRule

public class GrayRuleConfig {
    @Bean
    public GrayRule grayRule(){
        return new GrayRule();
    }
}

這個GrayRuleConfig不能被掃描進入IOC容器,一旦掃描進入則全局生效

4.openFeign透傳灰度標記

如何從請求頭中取出灰度標記

可以通過實現(xiàn)RequestInterceptor將原先的請求頭給復制過去

@Component
@Slf4j
public class FeignRequestInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        HttpServletRequest httpServletRequest = RequestContextUtils.getRequest();
        Map<String, String> headers = getHeaders(httpServletRequest);
        for (Map.Entry<String, String> entry : headers.entrySet()) {
            //② 設置請求頭到新的Request中
            template.header(entry.getKey(), entry.getValue());
        }
    }
    /**
     * 獲取原請求頭
     */
    private Map<String, String> getHeaders(HttpServletRequest request) {
        Map<String, String> map = new LinkedHashMap<>();
        Enumeration<String> enumeration = request.getHeaderNames();
        if (enumeration != null) {
            while (enumeration.hasMoreElements()) {
                String key = enumeration.nextElement();
                String value = request.getHeader(key);
                //將灰度標記的請求頭透傳給下個服務
                if (StrUtil.equals(GrayConstant.GRAY_HEADER,key)&&Boolean.TRUE.toString().equals(value)){
                    //① 保存灰度發(fā)布的標記
                    GrayRequestContextHolder.setGrayTag(true);
                    map.put(key, value);
                }
            }
        }
        return map;
    }
}

也需要使用@RibbonClients注解去標注文章服務調用的哪些服務需要灰度發(fā)布。

@RibbonClients(value = {
        //指定對comments這個服務開啟灰度部署
        @RibbonClient(value = "comments",configuration = GrayRuleConfig.class)
})
public class ArticleApplication {}

5.Nacos中服務如何做灰度標記

配置文件:

spring:
  cloud:
    nacos:
      discovery:
        metadata:
          ## 灰度標記
          grayTag: true

在Nacos中動態(tài)的指定灰度標記

在這里插入圖片描述

配置完成之后,在客戶端請求的時候只需要攜帶grayTag=true這個請求頭即可調用灰度服務。

6.總結

  1. 網(wǎng)關中通過全局過濾器實現(xiàn)灰度打標,將灰度標記放入請求頭中傳遞給下游服務
  2. 網(wǎng)關通過自定義的負載均衡策略,從注冊中心獲取灰度服務,進行轉發(fā)
  3. 在openFeign調用時需要從請求頭中獲取灰度標記,放入上下文中
  4. openFeign調用同樣是根據(jù)自定義的負載均衡策略從注冊中心獲取灰度服務,進行調用。
  5. Nacos進行灰度服務調用

到此這篇關于SpringCloud的全鏈路灰度發(fā)布方案詳解的文章就介紹到這了,更多相關SpringCloud全鏈路灰度發(fā)布內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Spring Boot 添加MySQL數(shù)據(jù)庫及JPA實例

    Spring Boot 添加MySQL數(shù)據(jù)庫及JPA實例

    本篇文章主要介紹了Spring Boot 添加MySQL數(shù)據(jù)庫及JPA,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • SpringBoot接收前端參數(shù)的幾種常用方式

    SpringBoot接收前端參數(shù)的幾種常用方式

    在Spring Boot開發(fā)中接收參數(shù)是非常常見且重要的一部分,依賴于請求的不同場景,Spring Boot提供了多種方式來處理和接收參數(shù),這篇文章主要給大家介紹了關于SpringBoot接收前端參數(shù)的幾種常用方式,需要的朋友可以參考下
    2024-07-07
  • Java5種遍歷HashMap數(shù)據(jù)的寫法

    Java5種遍歷HashMap數(shù)據(jù)的寫法

    這篇文章主要介紹了Java5種遍歷HashMap數(shù)據(jù)的寫法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03
  • Java中一個線程執(zhí)行死循環(huán)有什么后果

    Java中一個線程執(zhí)行死循環(huán)有什么后果

    這篇文章主要為大家詳細介紹了Java中一個線程執(zhí)行死循環(huán)有什么后果,當一個線程在執(zhí)行死循環(huán)時會影響另外一個線程嗎,下面為大家揭曉
    2016-05-05
  • springboot多線程并發(fā)執(zhí)行任務

    springboot多線程并發(fā)執(zhí)行任務

    本文主要介紹了springboot多線程并發(fā)執(zhí)行任務,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2026-03-03
  • JAVA如何自動下載SSL證書并導入到本地

    JAVA如何自動下載SSL證書并導入到本地

    這篇文章主要介紹了JAVA如何自動下載SSL證書并導入到本地問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Kafka中Producer和Consumer的作用詳解

    Kafka中Producer和Consumer的作用詳解

    這篇文章主要介紹了Kafka中Producer和Consumer的作用詳解,Kafka是一個分布式的流處理平臺,它的核心是消息系統(tǒng),Producer是Kafka中用來將消息發(fā)送到Broker的組件之一,它將消息發(fā)布到主題,并且負責按照指定的分區(qū)策略將消息分配到對應的分區(qū)中,需要的朋友可以參考下
    2023-12-12
  • spring security自定義登錄頁面

    spring security自定義登錄頁面

    在項目中我們肯定不能使用Spring自己生成的登錄頁面,而要用我們自己的登錄頁面,下面通過本文給大家分享spring security自定義登錄頁面的實現(xiàn)方法,一起看看吧
    2017-09-09
  • spring boot整合kafka過程解析

    spring boot整合kafka過程解析

    這篇文章主要介紹了spring boot整合kafka過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • 解決Java?API不能遠程訪問HBase的問題

    解決Java?API不能遠程訪問HBase的問題

    這篇文章主要介紹了解決Java?API不能遠程訪問HBase的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06

最新評論

江源县| 东乡族自治县| 五莲县| 聂拉木县| 福泉市| 盐城市| 睢宁县| 高密市| 得荣县| 巩留县| 禹州市| 贺兰县| 全椒县| 宣恩县| 潞城市| 福清市| 佛冈县| 葵青区| 左权县| 山东| 白水县| 琼海市| 历史| 康乐县| 吉林市| 杭锦后旗| 开鲁县| 延安市| 汤阴县| 伊宁县| 阿克苏市| 陕西省| 阜康市| 固阳县| 宾阳县| 滦南县| 随州市| 龙南县| 屏山县| 伊宁市| 武宣县|