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>

        面試官:為什么要用消息隊(duì)列?你項(xiàng)目中是怎么用的?

        共 4488字,需瀏覽 9分鐘

         ·

        2021-05-29 09:59


        包含原理+BAT案例實(shí)踐,看完需要5分鐘

        本文內(nèi)容預(yù)覽:

        1. 是什么?為什么?
          1.1 什么是消息隊(duì)列
          1.2 為什么要使用消息隊(duì)列
          1.3 引入消息隊(duì)列的帶來了哪些問題
        2. 怎么樣?
          2.1 支撐七年雙11零故障的RocketMQ
          2.2 快手萬億級(jí)kafka集群的平滑擴(kuò)容
          2.3 快手/美團(tuán)對(duì)kafka緩存污染的優(yōu)化
          2.4 CMQ在微信紅包支付場景下的應(yīng)用

        Part1是什么?為什么?

        1什么是消息隊(duì)列

        說到Java中的隊(duì)列應(yīng)該都不會(huì)陌生。其具有通過先進(jìn)先出,或者雙端進(jìn)出的方式進(jìn)行數(shù)據(jù)管理;通過阻塞以達(dá)到自動(dòng)平衡負(fù)載的功能。

        消息隊(duì)列之所以以隊(duì)列命名,起初也是因?yàn)槠涔δ芎筒僮?,和java的本地隊(duì)列有相似之處。所以,我們可以簡單的認(rèn)為消息隊(duì)列就是為了滿足分布式下各服務(wù)之間的數(shù)據(jù)傳輸、管理和消費(fèi)的一種中間服務(wù)。

        2為什么要使用消息隊(duì)列

        問:你們的系統(tǒng)中為什么要引入消息隊(duì)列?

        我們總歸需要知曉消息隊(duì)列的使用價(jià)值,以及自己的業(yè)務(wù)場景下的實(shí)際痛點(diǎn)才能回答為什么要用消息隊(duì)列這個(gè)問題,才能回答系統(tǒng)引入消息隊(duì)列的價(jià)值所在。

        系統(tǒng)間解耦

        以前幾天在后臺(tái)和關(guān)注公號(hào)的一個(gè)大佬討論的廣告流水更新的操作為例:

        廣告檢索系統(tǒng),需要感知廣告貼的信息變動(dòng)來更新自己的索引,但實(shí)際上檢索系統(tǒng)和投放、物料、資產(chǎn)等系統(tǒng)間沒有必要依靠接口對(duì)感知行為進(jìn)行強(qiáng)關(guān)聯(lián),且接口的方式在維護(hù)和系統(tǒng)的壓力方面不友好,那么,消息隊(duì)列的作用就顯的很重要了,各系統(tǒng)發(fā)布各自的消息,誰需要誰訂閱,達(dá)到目的同時(shí)不會(huì)增加額外的系統(tǒng)調(diào)用壓力。(注:builder的接口調(diào)用是為了獲取最新的信息,此處可以通過壓縮等方式進(jìn)行優(yōu)化)

        因此,當(dāng)系統(tǒng)間無實(shí)時(shí)數(shù)據(jù)交互要求,但還需要其業(yè)務(wù)信息時(shí),可以用消息隊(duì)列來達(dá)到系統(tǒng)間解耦的作用,只要發(fā)布方定義好消息隊(duì)列格式,消費(fèi)方的任何操作均可和發(fā)布方無關(guān),減少了不必要的聯(lián)調(diào)和發(fā)布沖突等影響。

        服務(wù)異步化

        最典型的一個(gè)例子,就是支付場景下的結(jié)果通知功能。

        我們知道,一般情況下不管是app push 還是短信通知,都是比較耗時(shí)的操作。所以,沒有必要因?yàn)檫@些非核心功能的耗時(shí)操作而影響了支付的核心操作,只要我們?cè)谥Ц恫僮魍瓿芍?,將支付結(jié)果發(fā)到短信中心指定的消息topic下,短信中心自然會(huì)接收到此消息并保證通知給用戶。

        圖片來源于知乎回答

        因此使用消息隊(duì)列,讓非核心的操作異步化,提高整個(gè)業(yè)務(wù)鏈路的高效和穩(wěn)定,是很有效的。

        削峰填谷

        這個(gè)功能使我們本篇關(guān)注的重點(diǎn),面對(duì)特殊場景如秒殺、春晚紅包等萬億級(jí)流量的脈沖式壓力下,一種保護(hù)我們系統(tǒng)的服務(wù)免于崩潰的有效手段就是消息隊(duì)列。

        通過消息中心高性能的存儲(chǔ)和處理能力,將超過系統(tǒng)處理能力的多余流量暫時(shí)存儲(chǔ)起來,并在系統(tǒng)處理能力內(nèi)平緩釋放出來,達(dá)到削峰的效果。

        比如我們的廣告計(jì)費(fèi)系統(tǒng),面對(duì)上萬并發(fā)的商業(yè)貼檢索量,數(shù)千并發(fā)的點(diǎn)擊操作,實(shí)時(shí)接口的方式一定是不合適的,畢竟廣告行為和支付行為不一樣,支付失敗用戶還可以重試,但用戶的商業(yè)貼點(diǎn)擊行為是不可回放的,本次流量過去就過去了,因此,需要利用消息隊(duì)列將扣費(fèi)請(qǐng)求緩存下來,來保證計(jì)費(fèi)系統(tǒng)的穩(wěn)定。

        其他

        還如廣播、事務(wù)型、最終一致性等特性,也是消息隊(duì)列經(jīng)常用到的功能。

        3消息隊(duì)列會(huì)存在哪些問題

        業(yè)務(wù)上增加響應(yīng)延遲

        前面提到,消息隊(duì)列使得業(yè)務(wù)非核心流程異步化,可以提高整個(gè)業(yè)務(wù)操作的時(shí)效性和流暢度,提升用戶操作體驗(yàn)。,也是因?yàn)閿?shù)據(jù)進(jìn)入隊(duì)列的原因,不可避免的會(huì)耽擱消費(fèi)速度。導(dǎo)致業(yè)務(wù)生效不及時(shí)。

        比如,之前遇到的商品推薦,產(chǎn)品要求推薦列表中不能出現(xiàn)滿減秒殺的商品,以消除特殊商品對(duì)推薦效果產(chǎn)生影響。除了秒殺,我們還需要感知商品的上下架、黑名單、庫存等等,因次,用redis中的bit多個(gè)偏移量來維護(hù)一個(gè)商品的多個(gè)狀態(tài)。然后接收促銷組的消息來變更推薦緩存集群中的商品狀態(tài),但由于消息的延遲,就有可能導(dǎo)致商品狀態(tài)變更不及時(shí)的情況發(fā)生。不過只要權(quán)衡之下業(yè)務(wù)和技術(shù)上是可接受的就OK了。

        架構(gòu)上引入不穩(wěn)定因素

        消息隊(duì)列的引入,相當(dāng)于在原有的分布式服務(wù)鏈路中新增了一個(gè)系統(tǒng),系統(tǒng)復(fù)雜度也隨之變大了。同時(shí),消息隊(duì)列的作用要求其具有高性能和高可用。

        所以,面對(duì)怎樣部署高可用穩(wěn)定集群、消息發(fā)送不成功怎么重試、broker數(shù)據(jù)同步策略怎么設(shè)置、broker異常導(dǎo)致消息重發(fā)怎么冪等、消費(fèi)不成功怎么重試等等問題,需要中間件團(tuán)隊(duì)和業(yè)務(wù)系統(tǒng)一起努力應(yīng)對(duì)。


        Part2怎么樣?

        4支撐七年雙11零故障的RocketMQ

        2020 年雙十一交易峰值達(dá)到 58.3W 筆/秒。RocketMQ為了阿里的交易生態(tài)有很多深度定制,這里我們只介紹其中針對(duì)高可用的優(yōu)化。

        個(gè)人理解,push消費(fèi)模式只適合于消費(fèi)速度遠(yuǎn)大于生產(chǎn)速度的場景,如果是大流量并發(fā)場景,基本還是以Pull消費(fèi)為主。

        而pull前broker和client間會(huì)進(jìn)行負(fù)載均衡建立連接,那么,一旦Client被Hang住,(沒有宕就不會(huì)rebalance,即時(shí)宕機(jī)也是默認(rèn)20s才會(huì)rebalance),就會(huì)讓broker與該client關(guān)聯(lián)的隊(duì)列消息無法及時(shí)被消費(fèi),導(dǎo)致積壓。怎么辦:POP,新的消費(fèi)模式

        <<< 左右滑動(dòng)見更多 >>>

        POP 消費(fèi)中并不需要rebalance去分配消費(fèi)隊(duì)列,取而代之的是請(qǐng)求所有的 broker 獲取消息進(jìn)行消費(fèi)。broker 內(nèi)部會(huì)把自身的三個(gè)隊(duì)列的消息根據(jù)一定的算法分配給等待的 POPClient。即使 PopClient 2 出現(xiàn) hang,但內(nèi)部隊(duì)列的消息也會(huì)讓 Pop Client1 和 Pop Client2 進(jìn)行消費(fèi)。這樣避免了消費(fèi)堆積。[1]

        5快手萬億級(jí)kafka集群的平滑擴(kuò)容[2]

        要實(shí)現(xiàn)平滑,則需要讓producer無感的實(shí)現(xiàn)partition遷移。

        大致原理是將待遷移partition的數(shù)據(jù)和新的partition數(shù)據(jù)進(jìn)行同步并持續(xù)一段時(shí)間,直到消費(fèi)者全部趕上同步的開始節(jié)點(diǎn),然后再變更路由,刪除原partition,完成遷移。

        <<< 左右滑動(dòng)見更多 >>>

        相同的數(shù)據(jù)同步思路,在facebook的分布式隊(duì)列災(zāi)備方案上也有應(yīng)用。

        6快手/美團(tuán)對(duì)kafka緩存污染的優(yōu)化[3]

        kafka的高性能,來源于順序文件讀寫和操作系統(tǒng)緩存pagecache的支持,在單partition,單consumer的場景下,kafka表現(xiàn)的非常優(yōu)秀。但是,如果同一機(jī)器上,存在不同的partition,甚至,消費(fèi)模式有實(shí)時(shí)和延遲消費(fèi)的混合場景,將會(huì)出現(xiàn)PageCache資源競爭,導(dǎo)致緩存污染,影響broker的服務(wù)的處理效率。

        美團(tuán)應(yīng)對(duì)實(shí)時(shí)/延遲消費(fèi)緩存污染

        將數(shù)據(jù)按照時(shí)間維度分布在不同的設(shè)備中,近實(shí)時(shí)部分的數(shù)據(jù)緩存在 SSD 中,這樣當(dāng)出現(xiàn) PageCache 競爭時(shí),實(shí)時(shí)消費(fèi)作業(yè)從 SSD 中讀取數(shù)據(jù),保證實(shí)時(shí)作業(yè)不會(huì)受到延遲消費(fèi)作業(yè)影響當(dāng)消費(fèi)請(qǐng)求到達(dá) Broker 時(shí),Broker 直接根據(jù)其維護(hù)的消息偏移量和設(shè)備的關(guān)系從對(duì)應(yīng)的設(shè)備中獲取數(shù)據(jù)并返回,并且在讀請(qǐng)求中并不會(huì)將 HDD 中讀取的數(shù)據(jù)回刷到 SSD,防止出現(xiàn)緩存污染。同時(shí)訪問路徑明確,不會(huì)由于 Cache Miss 而產(chǎn)生的額外訪問開銷。

        快手應(yīng)對(duì)follower數(shù)據(jù)同步引起的緩存污染

        broker 中引入了兩個(gè)對(duì)象:一個(gè)是 block cache;另一個(gè)是 flush queue。

        Producer 的寫入請(qǐng)求在 broker 端首先會(huì)被以原 message 的形式寫入 flush queue 中,之后再將數(shù)據(jù)寫入到 block cache 的一個(gè) block 中,之后整個(gè)請(qǐng)求就結(jié)束了。在 flush queue 中的數(shù)據(jù)會(huì)由其他線程異步地寫入到磁盤中(會(huì)經(jīng)歷 page cache 過程)。保證queue不受follower的影響

        consumer 首先會(huì)從 block cache 中檢索數(shù)據(jù),如果命中,則直接返回。否則,則從磁盤讀取數(shù)據(jù)。這樣的讀取模式保障了 consumer 的 cache miss 讀并不會(huì)填充 block cache,從而避免了產(chǎn)生污染。

        總結(jié)

        我們可以看出,解決緩存污染的基本出發(fā)點(diǎn),還是要拆解不同消費(fèi)速度的任務(wù)、或不同的數(shù)據(jù)生產(chǎn)來源,分而治之的思路避免相互間緩存的影響。

        7CMQ在紅包支付場景下的應(yīng)用[4]

        紅包操作的背后流程簡化為:從 A 帳號(hào)中把余額讀出來,然后做減法操作,再把結(jié)果寫回 A 帳號(hào)中;然后拆紅包對(duì) B 帳號(hào)做加法操作,把結(jié)果寫到 B 帳號(hào)中。

        而由于賬務(wù)系統(tǒng)能承載的壓力有限(和賬務(wù)相關(guān)的系統(tǒng)一般都會(huì)由于鎖、事務(wù)等原因影響處理效率),可能導(dǎo)致入賬失敗,如果按實(shí)時(shí)業(yè)務(wù)邏輯,則需要對(duì)拆紅包進(jìn)行實(shí)時(shí)回滾(回滾需要對(duì)A的賬戶再進(jìn)行一次加法),而引入CMQ后,業(yè)務(wù)鏈路變成將失敗的請(qǐng)求寫入CMQ,由CMQ的高可用來保證數(shù)據(jù)一致,直到賬務(wù)系統(tǒng)最終入賬成功。簡化了賬務(wù)系統(tǒng)由于系統(tǒng)壓力而導(dǎo)致的入賬失敗而導(dǎo)致紅包賬務(wù)回滾帶來的額外系統(tǒng)操作。

        Part3總結(jié)

        本篇從消息隊(duì)列的作用出發(fā),從阿里雙11、快手、美團(tuán)、微信紅包等案例,就消息隊(duì)列本身的優(yōu)化方案和業(yè)務(wù)對(duì)消息隊(duì)列的高效利用,闡述了消息隊(duì)列在高并發(fā)的優(yōu)化場景下的作用。如有問題,歡迎留言討論,相互學(xué)習(xí)!

        參考資料

        [1]

        版權(quán)聲明:本文為CSDN博主「阿里巴巴云原生」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議: https://blog.csdn.net/alisystemsoftware/article/details/111314602

        [2]

        快手萬億級(jí)別 Kafka 集群應(yīng)用實(shí)踐與技術(shù)演進(jìn)之路: https://www.infoq.cn/article/Q0oQzLQiay31MWiOBJH*

        [3]

        美團(tuán)把 Kafka 作為應(yīng)用層緩存的實(shí)踐: https://www.infoq.cn/article/k6dqfqqihpjfepl3y3hs

        [4]

        春晚微信紅包案例: https://cloud.tencent.com/document/product/406/4789


        推薦?? :1049天,100K!簡單復(fù)盤!

        推薦?? :年薪 40W Java 開發(fā)是什么水平?

        推薦?? :Github掘金計(jì)劃:Github上的一些優(yōu)質(zhì)項(xiàng)目搜羅

        我是 Guide哥,擁抱開源,喜歡烹飪。Github 接近 10w 點(diǎn)贊的開源項(xiàng)目 JavaGuide 的作者。未來幾年,希望持續(xù)完善 JavaGuide,爭取能夠幫助更多學(xué)習(xí) Java 的小伙伴!共勉!凎!點(diǎn)擊查看我的2020年工作匯報(bào)!
        歡迎準(zhǔn)備面試的朋友加入我的星球
        一個(gè)純 Java 面試交流圈子 !Ready!
        原創(chuàng)不易,歡迎點(diǎn)贊分享。咱們下期再會(huì)!
        瀏覽 156
        點(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>
            男男啪啪免费网站www | 男人操女人网站 | 婷婷开心五月天 | 国产成人高潮毛片 | 91视频大香蕉 | 一区二区三区四区国产精品 | 国产国语对白 | 全肉乱妇淑芬全文阅读 | 日本三级电影在线播放 | 国产一级毛片A级免责 |