主頁 > 軟體設計 > 我與 5 種訊息佇列的 8 年情緣

我與 5 種訊息佇列的 8 年情緣

2022-12-31 07:05:26 軟體設計

 

 

談起訊息佇列,內心還是會有些波瀾,

 

訊息佇列、快取、分庫分表是高并發解決方案三劍客,而訊息佇列是我最喜歡,也是思考最多的技術,我想按照下面的四個階段分享我與訊息佇列的故事,同時也是對我技術成長經歷的回顧,

 

初識:ActiveMQ

進階:Redis & RabbitMQ

升華:MetaQ

鐘情:RocketMQ

 

一、初識ActiveMQ

 

1、異步&解耦

 

2011年初,我在一家互聯網彩票公司做研發,

 

我負責的是用戶中心系統,提供用戶注冊,查詢,修改等基礎功能,用戶注冊成功之后,需要給用戶發送短信,

 

因為原來都是面向程序編程,我就把新增用戶模塊和發送短信模塊都揉在一起了,

 

圖片

 

起初都還好,但問題慢慢地顯現出來,

 

  • 短信渠道不夠穩定,發送短信會達到5秒左右,這樣用戶注冊介面耗時很大,影響前端用戶體驗;

 

  • 短信渠道介面發生變化,用戶中心代碼就必須修改了,但用戶中心是核心系統,每次上線都必要謹小慎微,這種感覺很別扭,非核心功能影響到核心系統了,

 

第一個問題,我可以采取執行緒池的方法來做,主要是異步化,但第二個問題卻讓我束手無措,

 

于是我向技術經理請教,他告訴我引入訊息佇列去解決這個問題,

 

  • 將發送短信功能單獨拆成獨立的Job服務;

 

  • 用戶中心用戶注冊成功后,發送一條訊息到訊息佇列,Job服務收到訊息呼叫短信服務發送短信即可,

 

圖片

 

這時,我才明白:訊息佇列最核心的功能就是異步和解耦

 

2、調度中心

 

彩票系統的業務是比較復雜的,在彩票訂單的生命周期里,經過創建,拆分子訂單,出票,算獎等諸多環節,每一個環節都需要不同的服務處理,每個系統都有自己獨立的表,業務功能也相對獨立,假如每個應用都去修改訂單主表的資訊,那就會相當混亂了,

 

公司的架構師設計了調度中心的服務,調度中心的職責是維護訂單核心狀態機,訂單返獎流程,彩票核心資料生成,

 

圖片

 

調度中心通過訊息佇列和出票網關,算獎服務等系統傳遞和交換資訊,

 

這種設計在那個時候青澀的我的眼里,簡直就是水滴vs人類艦隊,降維打擊,

 

隨著我對業務理解的不斷深入,我隱約覺得:“好的架構是簡潔的,也是應該易于維護的”,

 

當彩票業務日均千萬交易額的時候,調度中心的研發維護人員也只有兩個人,調度中心的原始碼里業務邏輯,日志,代碼規范都是極好的,

 

在我日后的程式人生里,我也會下意識模仿調度中心的編碼方式,“不玩奇技淫巧,代碼是給人閱讀的”,

 

3、重啟大法

 

隨著彩票業務的爆炸增長,每天的訊息量從30萬激增到150~200萬左右,一切看起來似乎很平穩,

 

某一天雙色球投注截止,調度中心無法從訊息佇列中消費資料,訊息總線處于只能發,不能收的狀態下,整個技術團隊都處于極度的焦慮狀態,“要是出不了票,那可是幾百萬的損失呀,要是用戶中了兩個雙色球?那可是千萬呀”,大家急得像熱鍋上的螞蟻,

 

這也是整個技術團隊第一次遇到消費堆積的情況,大家都沒有經驗,

 

首先想到的是多部署幾臺調度中心服務,部署完成之后,調度中心消費了幾千條訊息后還是Hang住了,這時,架構師只能采用重啟的策略,你沒有看錯,就是重啟大法,說起來真的很慚愧,但當時真的只能采用這種方式,

 

調度中心重啟后,消費了一兩萬后又Hang住了,只能又重啟一次,來來回回持續20多次,像擠牙膏一樣,而且隨著出票截止時間的臨近,這種思想上的緊張和恐懼感更加強烈,終于,通過1小時的手工不斷重啟,訊息終于消費完了,

 

我當時正好在讀畢玄老師的《分布式java應用基礎與實踐》,猜想是不是執行緒阻塞了,于是我用Jstack命令查看堆疊情況,果然不出所料,執行緒都阻塞在提交資料的方法上,

 

我們馬上和DBA溝通,發現oracle資料庫執行了非常多的大事務,每次大的事務執行都需要30分鐘以上,導致調度中心的調度出票執行緒阻塞了,

 

技術部后來采取了如下的方案規避堆積問題:

 

  • 生產者發送訊息的時候,將超大的訊息拆分成多批次的訊息,減少調度中心執行大事務的幾率;

 

  • 資料源配置引數,假如事務執行超過一定時長,自動拋例外,回滾,

 

4、復盤

 

Spring封裝的ActiveMQ的API非常簡潔易用,使用程序中真的非常舒服,

 

受限于當時彩票技術團隊的技術水平和視野,我們在使用ActiveMQ中遇到了一些問題,

 

1)高吞吐下,堆積到一定訊息量易Hang住

 

技術團隊發現在吞吐量特別高的場景下,假如訊息堆積越大,ActiveMQ有較小幾率會Hang住的,

 

出票網關的訊息量特別大,有的訊息并不需要馬上消費,但是為了規避訊息佇列Hang住的問題,出票網關消費資料的時候,先將訊息先持久化到本地磁盤,生成本地XML檔案,然后異步定時執行訊息,通過這種方式,我們大幅度提升了出票網關的消費速度,基本杜絕了出票網關佇列的堆積,

 

但這種方式感覺也挺怪的,消費訊息的時候,還要本地再存盤一份資料,訊息存盤在本地,假如磁盤壞了,也有丟訊息的風險,

 

2)高可用機制待完善

 

我們采用的master/slave部署模式,一主一從,服務器配置是4核8G ,

 

這種部署方式可以同時運行兩個ActiveMQ, 只允許一個slave連接到Master上面,也就是說只能有2臺MQ做集群,這兩個服務之間有一個資料備份通道,利用這個通道Master向Slave單向地資料備份,這個方案在實際生產線上不方便, 因為當Master掛了之后, Slave并不能自動地接收Client發來的請來,需要手動干預,且要停止Slave再重啟Master才能恢復負載集群,

 

還有一些很詭異丟訊息的事件,生產者發送訊息成功,但master控制臺查詢不到,但slave控制臺竟然能查詢到該訊息,

 

但消費者沒有辦法消費slave上的訊息,還得通過人工介入的方式去處理,

 

二、進階Redis&RabbitMQ

 

2014年,我在藝龍網從事紅包系統和優惠券系統優化相關作業,

 

1、Redis可以做訊息佇列嗎

 

酒店優惠券計算服務使用的是初代流式計算框架Storm,Storm這里就不詳細介紹,可以參看下面的邏輯圖:

 

圖片

 

這里我們的Storm集群的水源頭(資料源)是redis集群,使用list資料結構實作了訊息佇列的push/pop功能,

 

圖片

 

流式計算的整體流程:

 

1)酒店資訊服務發送酒店資訊到Redis集群A/B;

 

2)Storm的spout組件從Redis集群A/B獲取資料, 獲取成功后,發送tuple訊息給Bolt組件;

 

3)Bolt組件收到訊息后,通過運營配置的規則對資料進行清洗;

 

4)最后Storm把處理好的資料發送到Redis集群C;

 

5)入庫服務從Redis集群C獲取資料,存盤資料到資料庫;

 

6)搜索團隊掃描資料庫表,生成索引,

 

圖片

storm說明

 

這套流式計算服務每天處理千萬條資料,處理得還算順利,但方案在團隊內部還是有不同聲音:

 

  • storm的拓撲升級時候,或者優惠券服務重啟的時候,偶爾出現丟訊息的情況,但訊息的丟失,對業務來講沒有那么敏感,而且我們也提供了手工重繪的功能,也在業務的容忍范圍內;

 

  • 團隊需要經常關注Redis的快取使用量,擔心Redis佇列堆積, 導致out of memory;

 

  • 架構師認為搜索團隊直接掃描資料庫不夠解耦,建議將Redis集群C替換成Kafka,搜索團隊從kafka直接消費訊息,生成索引,

 

我認為使用Redis做訊息佇列應該滿足如下條件:

 

  • 容忍小概率訊息丟失,通過定時任務/手工觸發達到最終一致的業務場景;

 

  • 訊息堆積概率低,有相關的報警監控;

 

  • 消費者的消費模型要足夠簡單,

 

2、RabbitMQ是管子不是池子

 

RabbitMQ是用erlang語言撰寫的,RabbitMQ滿足了我的兩點需求:

 

  • 高可用機制,藝龍內部是使用的鏡像高可用模式,而且這種模式在藝龍已經使用了較長時間了,穩定性也得到了一定的驗證,

 

  • 我負責的紅包系統里,RabbitMQ每天的吞吐也在百萬條訊息左右,訊息的發送和消費都還挺完美,

 

優惠券服務原使用SqlServer,由于資料量太大,技術團隊決定使用分庫分表的策略,使用公司自主研發的分布式資料庫DDA,

 

圖片

 

因為是第一次使用分布式資料庫,為了測驗DDA的穩定性,我們模擬發送1000萬條訊息到RabbitMQ,然后優惠券重構服務消費訊息后,按照用戶編號hash到不同的mysql庫,

 

RabbitMQ集群模式是鏡像高可用,3臺服務器,每臺配置是4核8G ,

 

我們以每小時300萬條訊息的速度發送訊息,最開始1個小時生產者和消費者表現都很好,但由于消費者的速度跟不上生產者的速度,導致訊息佇列有積壓情況產生,第三個小時,訊息佇列已堆積了500多萬條訊息了, 生產者發送訊息的速度由最開始的2毫秒激增到500毫秒左右,RabbitMQ的控制臺已血濺當場,標紅報警,

 

這是一次無意中的測驗,從測驗的情況來看,RabbitMQ很優秀,但RabbitMQ對訊息堆積的支持并不好,當大量訊息積壓的時候,會導致 RabbitMQ 的性能急劇下降,

 

有的朋友對我講:“RabbitMQ明明是管子,你非得把他當池子?”

 

隨著整個互聯網資料量的激增, 很多業務場景下是允許適當堆積的,只要保證消費者可以平穩消費,整個業務沒有大的波動即可,

 

我心里面越來越相信:訊息佇列既可以做管子,也可以當做池子,

 

三、升華MetaQ

 

Metamorphosis的起源是我從對linkedin的開源MQ–現在轉移到apache的kafka的學習開始的,這是一個設計很獨特的MQ系統,它采用pull機制,而 不是一般MQ的push模型,它大量利用了zookeeper做服務發現和offset存盤,它的設計理念我非常欣賞并贊同,強烈建議你閱讀一下它的設計檔案,總體上說metamorphosis的設計跟它是完全一致的,

——MetaQ的作者莊曉丹

 

1、驚艷消費者模型

 

2015年,我主要從事神州專車訂單研發作業,

 

MetaQ滿足了我對于訊息佇列的幻想:“分布式,高吞吐,高堆積”,

 

MetaQ支持兩種消費模型:集群消費和廣播消費 ,因為以前使用過的消費者模型都是用隊列模型,當我第一次接觸到這種發布訂閱模型的時候還是被驚艷到了,

 

1)集群消費

 

圖片

 

訂單創建成功后,發送一條訊息給MetaQ,這條訊息可以被派單服務消費,也可以被BI服務消費,

 

2)廣播消費

 

派單服務在將訂單指派給司機的時候,會給司機發送一個推送訊息,推送就是用廣播消費的模式實作的,

 

圖片

 

大體流程是:

 

  • 司機端推送服務是一個TCP服務,啟動后,采用的是廣播模式消費MetaQ的PushTopic;

 

  • 司機端會定時發送TCP請求到推送服務,鑒權成功后,推送服務會保存司機編號和channel的參考;

 

  • 派單服務發送推送訊息到MetaQ;

 

  • 推送服務的每一臺機器都會收到該訊息,然后判斷記憶體中是否存在該司機的channel參考,若存在,則推送訊息,

 

這是非常經典的廣播消費的案例,我曾經研讀京麥TCP網關的設計,它的推送也是采用類似的方式,

 

2、激進的消峰

 

2015年是打車大戰硝煙彌漫的一年,

 

對神州專車來講,隨著訂單量的不斷增長,欣喜的同時,性能的壓力與日俱增,早晚高峰期,用戶打車的時候,經常點擊下單經常無回應,在系統層面來看,專車api網關發現大規模超時,訂單服務的性能急劇下降,資料庫層面壓力更大,高峰期一條記錄插入竟然需要8秒的時間,

 

整個技術團隊需要盡快提升專車系統的性能,此前已經按照模塊領域做了資料庫的拆分,但系統的瓶頸依然很明顯,

 

我們設計了現在看來有點激進的方案:

 

  • 設計訂單快取,快取方案大家要有興趣,我們可以以后再聊,里面有很多可以詳聊的點;

 

  • 在訂單的載客生命周期里,訂單的修改操作先修改快取,然后發送訊息到MetaQ,訂單落盤服務消費訊息,并判斷訂單資訊是否正常(比如有無亂序),若訂單資料無誤,則存盤到資料庫中,

 

圖片

 

這里有兩個細節:

 

  • 消費者消費的時候需要順序消費,實作的方式是按照訂單號路由到不同的partition,同一個訂單號的訊息,每次都發到同一個partition;

 

圖片

 

  • 一個守護任務,定時輪詢當前正在進行的訂單,當快取與資料不一致時候,修復資料,并發送報警,

 

這次優化大大提升訂單服務的整體性能,也為后來訂單服務庫分庫分表以及異構打下了堅實的基礎,根據我們的統計資料,基本沒有發生過快取和資料庫最后不一致的場景,但這種方案對快取高可用有較高的要求,還是有點小激進吧,

 

3、訊息SDK封裝

 

做過基礎架構的同學可能都有經驗:“三方組件會封裝一層”,神州架構團隊也是將metaq-client封裝了一層,

 

在我的思維里面,封裝一層可以減少研發人員使用第三方組件的心智投入,統一技術堆疊,也就如此了,

 

直到發生一次意外,我的思維升級了,那是一天下午,整個專車服務崩潰較長時間,技術團隊發現:"專車使用zookeeper做服務發現,zk集群的leader機器掛掉了,一直在選主,"

 

臨時解決后,我們發現MetaQ和服務發現都使用同一套zk集群,而且consumer的offset提交,以及負載均衡都會對zk集群進行大量的寫操作,

 

為了減少MetaQ對zk集群的影響,我們的目標是:“MetaQ使用獨立的zk集群”,

 

  • 需要部署新的zk集群;

  • MetaQ的zk資料需要同步到新的集群;

  • 保證切換到新的集群,應用服務基本無感知,

 

我很好奇向架構部同學請教,他說新的集群已經部署好了,但需要同步zk資料到新的集群,他在客戶端里添加了雙寫的操作,也就是說:我們除了會寫原有的zk集群一份資料,同時也會在新的zk集群寫一份,過了幾周后,MetaQ使用獨立的zk集群這個任務已經完成了,

 

這一次的經歷帶給我很大的感慨:“還可以這么玩?”,也讓我思考著:三方組件封裝沒有想象中那么簡單,

 

我們可以看下快手訊息的SDK封裝策略:

 

  • 對外只提供最基本的 API,所有訪問必須經過SDK提供的介面,簡潔的 API 就像冰山的一個角,除了對外的簡單介面,下面所有的東西都可以升級更換,而不會破壞兼容性;

 

  • 業務開發起來也很簡單,只要需要提供 Topic(全域唯一)和 Group 就可以生產和消費,不用提供環境、NameServer 地址等,SDK 內部會根據 Topic 決議出集群 NameServer 的地址,然后連接相應的集群,生產環境和測驗環境環境會決議出不同的地址,從而實作了隔離;

 

  • 上圖分為 3 層,第二層是通用的,第三層才對應具體的 MQ 實作,因此,理論上可以更換為其它訊息中間件,而客戶端程式不需要修改;

 

  • SDK 內部集成了熱變更機制,可以在不重啟 Client 的情況下做動態配置,比如下發路由策略(更換集群 NameServer 的地址,或者連接到別的集群去),Client 的執行緒數、超時時間等,通過 Maven 強制更新機制,可以保證業務使用的 SDK 基本上是最新的,

 

圖片

 

4、重構MetaQ , 自成體系

 

我有一個習慣:“經常找運維,DBA,架構師了解當前系統是否有什么問題,以及他們解決問題的思路,這樣,我就有另外一個視角來審視公司的系統運行情況”,

 

MetaQ也有他的缺點,

 

  • MetaQ的基層通訊框架是gecko,MetaQ偶爾會出現rpc無回應,應用假死的情況,不太好定位問題;

 

  • MetaQ的運維能力薄弱,只有簡單的Dashboard界面,無法實作自動化主題申請,訊息追蹤等功能,

 

有一天,我發現測驗環境的一臺消費者服務器啟動后,不斷報鏈接例外的問題,而且cpu占用很高,我用netstat命令馬上查一下,發現已經創建了幾百個鏈接,出于好奇心,我打開了原始碼,發現網路通訊框架gecko已經被替換成了netty,我們馬上和架構部的同學聯系,

 

我這才明白:他們已經開始重構MetaQ了,我從來沒有想過重構一個開源軟體,因為距離我太遠了,或者那個時候,我覺得自己的能力還達不到,

 

后來,神州自研的訊息佇列自成體系了,已經在生產環境運行的挺好,

 

時至今天,我還是很欣賞神州架構團隊,他們自研了訊息佇列,DataLink(資料異構中間件),分庫分表中間件等,他們愿意去創新,有勇氣去做一個更好的技術產品,

 

我從他們身上學到很多,

 

也許在看到他們重構MetaQ的那一刻,我的心里埋下了種子,

 

四、鐘情RocketMQ

 

1、開源的盛宴

 

2014年,我搜羅了很多的淘寶的訊息佇列的資料,我知道MetaQ的版本已經升級MetaQ 3.0,只是開源版本還沒有放出來,

 

大約秋天的樣子,我加入了RocketMQ技術群,誓嘉(RocketMQ創始人)在群里說:“最近要開源了,放出來后,大家趕緊fork呀”,他的這句話發在群里之后,群里都炸開了鍋,我更是歡喜雀躍,期待著能早日見到阿里自己內部的訊息中間件,

 

圖片

 

終于,RocketMQ終于開源了,我迫不及待想一窺他的風采,

 

因為我想學網路編程,而RocketMQ的通訊模塊remoting底層也是Netty寫的,所以,RocketMQ的通訊層是我學習切入的點,

 

我模仿RocketMQ的remoting寫了一個玩具的rpc,這更大大提高我的自信心,正好,藝龍舉辦技術創新活動,我想想,要不嘗試一下用Netty改寫下Cobar的通訊模塊,于是參考Cobar的原始碼花了兩周寫了個netty版的proxy,其實非常粗糙,很多功能不完善,后來,這次活動頒給我一個鼓勵獎,現在想想都很好玩,

 

因為在神州優車使用MetaQ的關系,我學習RocketMQ也比較得心應手,為了真正去理解原始碼,我時常會參考RocketMQ的原始碼,寫一些輪子來驗證我的學習效果,

 

雖然自己做了一些練習,但一直沒有在業務環境使用過,2018年是我真正使用RocketMQ的一年,也是有所得的一年,

 

1)短信服務

 

短信服務應用很廣泛,比如用戶注冊登錄驗證碼,營銷短信,下單成功短信通知等等,最開始設計短信服務的時候,我想學習業界是怎么做的,于是把目標鎖定在騰訊云的短信服務上,騰訊云的短信服務有如下特點:

 

  • 統一的SDK,后端入口是http/https服務 ,  分配appId/appSecret鑒權;

 

  • 簡潔的API設計:單發,群發,營銷單發,營銷群發,模板單發,模板群發,

 

于是,我參考了這種設計思路,

 

  • 模仿騰訊云的SDK設計,提供簡單易用的短信介面;

 

  • 設計短信服務API端,接收發短信請求,發送短信資訊到訊息佇列;

 

  • worker服務消費訊息,按照負載均衡的演算法,呼叫不同渠道商的短信介面;

 

  • Dashboard可以查看短信發送記錄,配置渠道商資訊,

 

圖片

 

短信服務是我真正意義第一次生產環境使用RocketMQ,當短信一條條發出來的時候,還是蠻有成就感的,

 

2)MQ控制臺

 

圖片

 

使用過RocketMQ的朋友,肯定對上圖的控制臺很熟悉,當時團隊有多個RocketMQ集群,每組集群都需要單獨部署一套控制臺,于是我想著:能不能稍微把控制臺改造一番,能滿足支持多組集群,

 

于是,擼起袖子干了起來,大概花了20天的時間,我們基于開源的版本改造了能支持多組集群的版本,做完之后,雖然能滿足我最初的想法,但是做得很粗糙,而且搜狐開源了他們自己的MQCloud ,我看了他們的設計之后, 覺得離一個訊息治理平臺還很遠,

 

后來我讀了《網易云音樂的訊息佇列改造之路》,《今日頭條在訊息服務平臺和容災體系建設方面的實踐與思考》這兩篇文章,越是心癢難耐,蠻想去做的是一個真正意義上的訊息治理平臺,一直沒有什么場景和機會,還是有點可惜,

 

最近看了哈羅單車架構專家梁勇的一篇文章《哈啰在分布式訊息治理和微服務治理中的實踐》,推薦大家一讀,

 

3)一扇窗子,開始自研組件

 

后來,我嘗試進一步深入使用RocketMQ,

 

  • 仿ONS風格封裝訊息SDK;

  • 運維側平滑擴容訊息佇列;

  • 生產環境DefaultMQPullConsumer消費模式嘗試

 

這些做完之后,我們又自研了注冊中心、配置中心,任務調度系統,設計這些系統的時候,從RocketMQ原始碼里汲取了很多的營養,雖然現在看來有很多設計不完善的地方,代碼質量也有待提高,但做完這些系統后,還是大大提升我的自信心,

 

RocketMQ給我打開了一扇窗子,讓我能看到更廣闊的Java世界,對我而言,這就是開源的盛宴,

 

2、Kafka:大資料生態的不可或缺的部分

 

Kafka是一個擁有高吞吐、可持久化、可水平擴展,支持流式資料處理等多種特性的分布式訊息流處理中間件,采用分布式訊息發布與訂閱機制,在日志收集、流式資料傳輸、在線/離線系統分析、實時監控等領域有廣泛的應用,

 

1)日志同步

 

在大型業務系統設計中,為了快速定位問題,全鏈路追蹤日志,以及故障及時預警監控,通常需要將各系統應用的日志集中分析處理,

 

Kafka設計初衷就是為了應對大量日志傳輸場景,應用通過可靠異步方式將日志訊息同步到訊息服務,再通過其他組件對日志做實時或離線分析,也可用于關鍵日志資訊收集進行應用監控,

 

日志同步主要有三個關鍵部分:日志采集客戶端,Kafka訊息佇列以及后端的日志處理應用,

 

  • 日志采集客戶端,負責用戶各類應用服務的日志資料采集,以訊息方式將日志“批量”“異步”發送Kafka客戶端,Kafka客戶端批量提交和壓縮訊息,對應用服務的性能影響非常小,

 

  • Kafka將日志存盤在訊息檔案中,提供持久化,

 

  • 日志處理應用,如Logstash,訂閱并消費Kafka中的日志訊息,最終供檔案搜索服務檢索日志,或者由Kafka將訊息傳遞給Hadoop等其他大資料應用系統化存盤與分析,

 

日志同步示意圖:

 

圖片

 

2)流計算處理

 

在很多領域,如股市走向分析、氣象資料測控、網站用戶行為分析,由于資料產生快、實時性強且量大,您很難統一采集這些資料并將其入庫存盤后再做處理,這便導致傳統的資料處理架構不能滿足需求,Kafka以及Storm、Samza、Spark等流計算引擎的出現,就是為了更好地解決這類資料在處理程序中遇到的問題,流計算模型能實作在資料流動的程序中對資料進行實時地捕捉和處理,并根據業務需求進行計算分析,最終把結果保存或者分發給需要的組件,

 

3)資料中轉樞紐

 

近10多年來,諸如KV存盤(HBase)、搜索(ElasticSearch)、流式處理(Storm、Spark、Samza)、時序資料庫(OpenTSDB)等專用系統應運而生,這些系統是為單一的目標而產生的,因其簡單性使得在商業硬體上構建分布式系統變得更加容易且性價比更高,通常,同一份資料集需要被注入到多個專用系統內,例如,當應用日志用于離線日志分析時,搜索單個日志記錄同樣不可或缺,而構建各自獨立的作業流來采集每種型別的資料再匯入到各自的專用系統顯然不切實際,利用訊息佇列Kafka版作為資料中轉樞紐,同份資料可以被匯入到不同專用系統中,

 

下圖是美團 MySQL 資料實時同步到 Hive 的架構圖,也是一個非常經典的案例,

 

圖片

 

3、如何技術選型

 

2018年去哪兒QMQ開源了,2019年騰訊TubeMQ開源了,2020年Pulsar如火如荼,

 

訊息佇列的生態是如此的繁榮,那我們如何選型呢?

 

我想我們不必局限于訊息佇列,可以再擴大一下,簡單談一談我的看法,

 

Databases are specializing – the “one size fits all” approach no longer applies.

——MongoDB設計哲學

 

第一點:先有場景,然后再有適配這種場景的技術,什么樣的場景選擇什么樣的技術,

 

第二點:現實往往很復雜,當我們真正做技術選型,并需要落地的時候,技術儲備和成本是兩個我們需要重點考量的因素,

 

1)技術儲備

 

  • 技術團隊有無使用這門技術的經驗,是否踩過生產環境的坑,以及針對這些坑有沒有完備的解決方案;

 

  • 架構團隊是否有成熟的SDK,工具鏈,甚至是技術產品,

 

2)成本

 

  • 研發,測驗,運維投入人力成本;

  • 服務器資源成本;

  • 招聘成本等,

 

最后一點是人的因素,特別是管理者的因素,每一次大的技術選型考驗技術管理者的視野,格局,以及管理智慧,

 

五、寫在最后

 

我覺得這個世界上沒有什么毫無道理的橫空出世,真的,如果沒有大量的積累大量的思考是不會把事情做好的,總之,在經歷了這部電影以后,我覺得我要學的太多了,這世界上有太多的能人,你以為的極限,弄不好,只是別人的起點,所以只有不停地進取,才能不丟人,那,人可以不上學,但一定要學習,真的,

——韓寒《后會無期》演講

 

我學習訊息佇列的程序是不斷思考,不斷實踐的程序,雖然我以為的極限,弄不好,只是別人的起點,但至少現在,當我面對這門技術的時候,我的內心充滿了好奇心,同時也是無所畏懼的,

 

我始終相信:每天學習一點點,比昨天進步一點點就好,

 

作者丨勇哥

本文來自博客園,作者:古道輕風,轉載請注明原文鏈接:https://www.cnblogs.com/88223100/p/My-8-year-relationship-with-5-message-queues.html

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/541018.html

標籤:其他

上一篇:go-淺學設計模式隨記

下一篇:go-淺學設計模式隨記

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more