1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        「微服務(wù)設(shè)計(jì)之禪」重試模式

        共 3152字,需瀏覽 7分鐘

         ·

        2020-12-13 09:57

        前言

        微服務(wù)本質(zhì)上分布式架構(gòu),當(dāng)我們使用分布式系統(tǒng)時(shí)任何不可預(yù)知的問(wèn)題都會(huì)發(fā)生(例如網(wǎng)絡(luò)可用性問(wèn)題、服務(wù)可用性問(wèn)題、中間件可用性問(wèn)題)。一個(gè)系統(tǒng)的問(wèn)題可能會(huì)直接影響另外一個(gè)系統(tǒng)的使用或性能。所以在系統(tǒng)設(shè)計(jì)過(guò)程既要保證自身運(yùn)行的彈性需求,也要避免對(duì)下游服務(wù)級(jí)聯(lián)故障。

        重試模式

        在微服務(wù)技術(shù)架構(gòu)中,當(dāng)有多個(gè)服務(wù)(A,B,C ,D)時(shí),一個(gè)服務(wù)(A)可能依賴(lài)于另一服務(wù)(B),而另一服務(wù)(B)又可能依賴(lài)于 C,依此類(lèi)推。有時(shí)由于某些問(wèn)題,服務(wù) D 可能無(wú)法按預(yù)期響應(yīng)。服務(wù) D 可能引發(fā)了某些異常,例如 OutOfMemory Error 或 Internal Server Error。此類(lèi)異常會(huì)影響下游服務(wù),這可能導(dǎo)致用戶(hù)體驗(yàn)較差,如下所示。

        1607306376

        類(lèi)似于網(wǎng)絡(luò)通信異常等,大部分情況通過(guò)刷新再次請(qǐng)求服務(wù)接口即可解決。在微服務(wù)架構(gòu)中,生產(chǎn)環(huán)境針對(duì)服務(wù) D 部署了多個(gè)實(shí)例,并通過(guò)負(fù)載均衡等實(shí)現(xiàn)服務(wù) D 高可用。如果其中一個(gè)實(shí)例網(wǎng)絡(luò)請(qǐng)求有問(wèn)題,無(wú)法響應(yīng)期望結(jié)果,我們可以通過(guò)重試該請(qǐng)求,通過(guò)負(fù)載均衡器將請(qǐng)求發(fā)送至運(yùn)行狀態(tài)良好的實(shí)例獲取正確結(jié)果。因此通過(guò)“重試”模式,可以使得應(yīng)用可用性得到保證。

        1607306392

        示例程序

        架構(gòu)圖

        1607306406

        如上圖所示,簡(jiǎn)單模擬電商下單邏輯

        • 用戶(hù)登錄瀏覽商品 (商品庫(kù)存模塊)
        • 扣減商品庫(kù)存 (商品庫(kù)存模塊)
        • 創(chuàng)建商品訂單 (訂單模塊)

        product-service 通過(guò)調(diào)用 order-service 服務(wù)下單

        代碼實(shí)現(xiàn)

        ├──?retry-demo
        ???├──?order-service????????#訂單服務(wù)??(8070)
        ???└──?product-service??????#商品庫(kù)存服務(wù)??(8050)
        • 依賴(lài)說(shuō)明。由于 hystrix 年久失修,這里使用 resilience4j 斷路保護(hù)器做演示
        <dependency>
        ????<groupId>io.github.resilience4jgroupId>
        ????<artifactId>resilience4j-spring-boot2artifactId>
        ????<version>1.6.1version>
        dependency>
        • 針對(duì)接口定義重試策略
        resilience4j.retry:
        ??instances:
        ????ratingService:
        ??????maxRetryAttempts:?1?#重試策略
        ??????retryExceptions:???#針對(duì)哪些異常進(jìn)行重試
        ????????-?org.springframework.web.client.HttpServerErrorException

        • 消費(fèi)方接口。product-service 8050
        /**
        ?*?用戶(hù)點(diǎn)擊購(gòu)買(mǎi)
        ?*/

        @SneakyThrows
        @GetMapping("/order")
        public?String?buy()?{
        ????//?模擬調(diào)用?訂單服務(wù)下單
        ????orderService.createOrder().get();
        ????return?"success";
        }
        • 定義遠(yuǎn)程調(diào)用類(lèi)使用 Retry 包裝
        /**
        ?*?創(chuàng)建訂單
        ?*?name:?指定接口重試配置名稱(chēng)
        ?*?fallbackMethod:?重試后降級(jí)方法
        ?*/

        @Bulkhead(name?=?"createOrder",?fallbackMethod?=?"getError")
        public?CompletableFuture?createOrder()?{
        ????return?CompletableFuture.supplyAsync(()?->?restTemplate.getForEntity("http://localhost:8070/createOrder"
        ????????????,?String.class).getBody());
        }

        public?CompletableFuture?getError(Throwable?error)?{
        ????log.warn("創(chuàng)建訂單失敗了?{}",?error.getMessage());
        ????return?CompletableFuture.completedFuture("");
        }

          • 服務(wù)提供方。order-service 8070
        @RestController
        public?class?PayController?{
        ????private?static?int?num?=?0;
        ????@SneakyThrows
        ????@GetMapping("/createOrder")
        ????public?String?createOrder()?{
        ????????log.info("開(kāi)始請(qǐng)求創(chuàng)建訂單接口?{}",?++num);
        ????????//?請(qǐng)求次數(shù)奇數(shù)模擬創(chuàng)建訂單異常
        ????????if?(num?%?2?!=?0)?{
        ????????????throw?new?RuntimeException();
        ????????}
        ????????return?"創(chuàng)建訂單服務(wù)";
        ????}
        }

        開(kāi)始測(cè)試

        • 請(qǐng)求商品服務(wù),返回成功
        curl?http://localhost:8050/order
        success?
        • 訂單服務(wù)日志,由于是第一次請(qǐng)求觸發(fā)異常,然后服務(wù)調(diào)用方自動(dòng)重試產(chǎn)生第二次調(diào)用。
        2020-12-06?15:50:07.664??INFO?25846?---?[nio-8070-exec-1]?c.e.o.controller.OrderController?????????:?開(kāi)始請(qǐng)求創(chuàng)建訂單接口?1
        2020-12-06?15:50:07.686?ERROR?25846?---?[nio-8070-exec-1]?o.a.c.c.C.[.[.[/].[dispatcherServlet]????:?Servlet.service()?for?servlet?[dispatcherServlet]?in?context?with?path?[]?threw?exception?[Request?processing?failed;?nested?exception?is?java.lang.RuntimeException]?with?root?cause

        ...?異常日志?...

        2020-12-06?15:50:08.271??INFO?25846?---?[nio-8070-exec-2]?c.e.o.controller.OrderController?????????:?開(kāi)始請(qǐng)求創(chuàng)建訂單接口?2

        總結(jié)

        重試模式可以通過(guò)編碼的形式自動(dòng)發(fā)起重試,避免終端用戶(hù)手動(dòng)刷新體驗(yàn)問(wèn)題。但重試模式的缺點(diǎn)是會(huì)造成整體的響應(yīng)時(shí)間,部分業(yè)務(wù)邏輯不能適用(比如冪等接口[1]等)

        源碼:https://github.com/lltx/microservices-pattern[2]

        參考資料和部分圖片來(lái)源 https://www.vinsguru.com[3]

        參考資料

        [1]

        冪等接口: https://juejin.cn/post/6892966720017793037

        [2]

        源碼:https://github.com/lltx/microservices-pattern: https://github.com/lltx/microservices-pattern

        [3]

        參考資料和部分圖片來(lái)源 https://www.vinsguru.com: https://www.vinsguru.com


        瀏覽 51
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            啊灬啊灬啊灬啊灬高潮了在线 | 天堂九九九 | 国产毛片网站 | 国产91亚洲成人精品观看 | 大巴车男人狂躁女人视频 | 日逼视屏| 国产精品 | 欧美成人网站免费在线观看 | 亚洲激情成人五月天 | 麻豆三级毛片精品三级 |