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ì)之禪」隔離模式

        共 2586字,需瀏覽 6分鐘

         ·

        2020-12-17 12:26

        前言

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

        隔離模式

        9dad4a8f788e945c6b5ad18a04c55d21.webp

        如上圖,如果我們仔細(xì)觀察船的結(jié)構(gòu)時(shí)會(huì)發(fā)現(xiàn),使用了多個(gè)隔板將船分為了多個(gè)小的隔間。隔板用于密封船體的各個(gè)部分,避免由于某個(gè)部位泄漏導(dǎo)致整個(gè)船淹沒。當(dāng)我們進(jìn)行軟件設(shè)計(jì)時(shí),應(yīng)該將整個(gè)應(yīng)用拆分為多個(gè)組件,并且一個(gè)組件的故障不會(huì)影響到全局,這就所謂的隔離模式。

        例如:假設(shè)有兩個(gè)服務(wù) A 和 B,服務(wù) A 只能同時(shí)處理 5 個(gè)并發(fā)請(qǐng)求。服務(wù) A 里面有兩個(gè)接口

        • /a/b 依賴于服務(wù) B (耗時(shí)比較多)

        • /a???? ?本地服務(wù)

        dee63e6581ace714cc03d7888901e71b.webp

        當(dāng)有 10 個(gè)并發(fā)請(qǐng)求 A 服務(wù)接口, 其中 5 個(gè)請(qǐng)求 /a/b接口 ,5 個(gè)請(qǐng)求 /a由于/a/b 需要調(diào)用服務(wù) B 耗時(shí)比較多,可能會(huì)造成 5 個(gè)線程阻塞應(yīng)用無法處理 /a 雖然只是本地處理。由于一個(gè)接口耗時(shí)占用了整個(gè)應(yīng)用的資源導(dǎo)致其他接口無法使用,導(dǎo)致用戶體驗(yàn)很差。

        43cec0b9851b6efdc38ee378f4645186.webp

        通過隔離模式分配特定接口的資源限制,避免資源瓶頸。如上圖,將a/b 接口最大處理線程設(shè)置為 2,這樣應(yīng)用始終會(huì)有剩余線程處理其他接口請(qǐng)求。

        示例程序

        架構(gòu)圖

        bfe79e3060058bb82c5764e5a320776a.webp

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

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

        product-service 提供兩個(gè)接口


        1. /products 查詢?nèi)可唐氛故?/li>

        1. /order 調(diào)用 order 服務(wù)下單

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

        ├──?bulkhead-demo
        ???├──?order-service????????#訂單服務(wù)??(8070)
        ???└──?product-service??????#商品庫存服務(wù)??(8050)
        • 依賴說明。由于 hystrix 年久失修,這里使用 resilience4j 斷路保護(hù)器做演示
        <dependency>
        ????<groupId>io.github.resilience4jgroupId>
        ????<artifactId>resilience4j-spring-boot2artifactId>
        ????<version>1.6.1version>
        dependency>
        • 消費(fèi)方定義隔離策略
        server:
        ??tomcat:
        ????threads:
        ??????max:?5?#限制應(yīng)用只能處理5?個(gè)并發(fā),方便測(cè)試

        resilience4j.bulkhead:
        ??instances:
        ????createOrder:??#?限制此接口只能使用兩個(gè)
        ??????maxConcurrentCalls:?2
        • 消費(fèi)方接口。product-service 8050
        ??/**
        ???*?用戶點(diǎn)擊購買
        ???*/

        ??@SneakyThrows
        ??@GetMapping("/order")
        ??public?String?buy()?{
        ??????//?模擬調(diào)用?訂單服務(wù)下單
        ??????orderService.createOrder().get();
        ??????return?"success";
        ??}

        ??/***
        ???*?獲取全部商品接口
        ???*/

        ??@SneakyThrows
        ??@GetMapping("/products")
        ??public?String?products()?{
        ??????//?模擬查詢DB?耗時(shí)
        ??????Thread.sleep(100);
        ??????return?"products";
        ??}
        • 定義遠(yuǎn)程調(diào)用類使用 Bulkhead 包裝
        /**
        ?*?創(chuàng)建訂單
        ?*?name:?指定接口隔離配置名稱
        ?*?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?{
        ????@SneakyThrows
        ????@GetMapping("/pay")
        ????public?String?pay(){
        ????????//?模擬調(diào)用支付渠道耗時(shí)?10s
        ????????Thread.sleep(10000);
        ????????return?"支付成功";
        ????}
        }

        測(cè)試

        • Jmeter 10 個(gè)線程請(qǐng)求 /order 接口, 10 個(gè)線程請(qǐng)求 /products ,30S 請(qǐng)求服務(wù)性能如下

        測(cè)試使用資源隔離

        資源隔離下,30S 共計(jì)執(zhí)行樣本 1750 次,通過率 43.5/每秒

        f8dc5efd1e3f410e7c20f704eab1c67f.webp1607306553

        測(cè)試不使用資源隔離(去掉@Bulkhead 邏輯)

        由于未做資源隔離,30S 共計(jì)執(zhí)行樣本 50 次,通過率 49.8/每分鐘

        2c9e5a959d95709b850f1bf29789af0b.webp

        總結(jié)

        在應(yīng)用資源緊張的前提下,通過設(shè)置資源隔離策略能大大提升整個(gè)應(yīng)用的性能。所謂資源緊張即請(qǐng)求并發(fā)大于容器的處理前最大值,如上邊壓測(cè) tomcat 限制只能處理 5 個(gè)并發(fā),但是我們測(cè)試是 20 個(gè)并發(fā)。

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

        參考資料和部分圖片來源 https://www.vinsguru.com

        往期推薦

        「微服務(wù)設(shè)計(jì)之禪」超時(shí)模式

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

        「2020封箱」Spring Boot 2.4.1 發(fā)布

        Spring Boot 2.4.0 正式發(fā)布,全面擁抱云原生




        瀏覽 80
        點(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>
            AAA在线视频 | 久操中文| 国语对白中文字幕 | 国产黄色视频在线免费看 | 青榴社区 | 夜夜操女人 | 一区二区三区精密机械 | 国产一区精品 | 韩国伦理片免费观看app 3d触手无尽粗暴蹂躏h | 在线你懂得 |