disruptor筆記之四:事件消費知識點小結
歡迎訪問我的GitHub
https://github.com/zq2599/blog_demos
內容:所有原創文章分類彙總及配套原始碼,涉及Java、Docker、Kubernetes、DevOPS等;
《disruptor筆記》系列連結
關於獨立消費和共同消費
-
本篇是《disruptor筆記》的第四篇,前面章節寫了不少程式碼,搞得讀者和作者都辛苦,本篇稍微放鬆一下,熟悉一個重要概念:disruptor事件的消費模式,包括獨立消費和共同消費兩種;
-
舉個例子,假設在電商場景中,每產生一個訂單都要發郵件和簡訊通知買家,如果產生了十個訂單,就有以下兩種情況要考慮:
第一種:要發十封郵件和十條簡訊,此時,郵件系統和簡訊系統是各自獨立的,他們各自消費這十個訂單的事件,也就是說十個事件被消費二十次,所以郵件系統和簡訊系統各自<font color="red">獨立消費</font>,彼此沒有關係,如下圖,一個原點代表一個事件:
第二種:假設郵件系統處理能力差,為了提升處理能力,部署了兩臺郵件伺服器,因此是這兩臺郵件伺服器共同處理十個訂單事件,合起來一共傳送了十封郵件,如下圖,一號郵件伺服器和二號郵件伺服器是<font color="red">共同消費</font>,某個訂單事件只會在一個郵件伺服器被消費:
獨立消費的核心知識點
- 使用的API是handleEventsWith
- 業務處理邏輯放入EventHandler的實現類中
- 內部實現用BatchEventProcessor類,一個消費者對應一個BatchEventProcessor例項,任務是獲取事件再呼叫EventHandler的onEvent方法處理
- 一個消費者對應一個SequenceBarrier例項,用於等待可消費事件
- 一個消費者對應一個Sequence例項(BatchEventProcessor的成員變數),用於記錄消費進度
- 每個BatchEventProcessor例項都會被放入集合(consumerRepository.consumerInfos)
- Disruptor的start方法中,會將BatchEventProcessor放入執行緒池執行,也就是說每個消費者都在獨立執行緒中執行
共同消費的核心知識點
- 使用的API是handleEventsWithWorkerPool
- 業務處理邏輯放入WorkHandler的實現類中
- 內部實現用WorkerPool和WorkProcessor類合作完成的,WorkerPool例項只有一個,每個消費者對應一個WorkProcessor例項
- SequenceBarrier例項只有一個,用於等待可消費事件
- 每個消費者都有自己的Sequence例項,另外還有一個公共的Sequence例項(WorkerPool的成員變數),用於記錄消費進度
- WorkerPool例項會包裹成WorkerPoolInfo例項再放入集合(consumerRepository.consumerInfos)
- Disruptor的start方法中,會呼叫WorkerPool.start方法,這裡面會將每個WorkProcessor放入執行緒池執行,也就是說每個消費者都在獨立執行緒中執行
精簡的小結
- 上述核心知識點還是有點多,咱們用對比來精簡一下,以下是精華中的精華,真不能再省了,請重點關注:
- 獨立消費的每個消費者都有屬於自己獨有的SequenceBarrier例項,共同消費者是所有人共用同一個SequenceBarrier例項
- 獨立消費的每個消費者都有屬於自己獨有的Sequence例項,對於共同消費者,雖然他們也有屬於自己的Sequence例項,但這個Sequence例項的值是從一個公共Sequence例項(WorkerPool的成員變數workSequence)得來的
- 獨立消費和共同消費都有自己的取資料再消費的程式碼,放在一起對比看就一目瞭然了,如下圖,共同消費時,每個消費者的Sequence值其實來自公共Sequence例項,多執行緒之間用CAS競爭來搶佔事件用於消費:
用圖說話
- 最後放上自制圖一張,希望有一圖勝千言的效果吧:
- 至此,理論分析結束,接下來的文章會乘熱打鐵,基於上述知識點進行實戰,編碼實現三個場景:
- 100個訂單,簡訊和郵件系統獨立消費
- 100個訂單,郵件系統的兩個郵件伺服器共同消費;
- 100個訂單,簡訊系統獨立消費,與此同時,兩個郵件伺服器共同消費;
你不孤單,欣宸原創一路相伴
歡迎關注公眾號:程式設計師欣宸
微信搜尋「程式設計師欣宸」,我是欣宸,期待與您一同暢遊Java世界... https://github.com/zq2599/blog_demos
「其他文章」
- 瀏覽器上寫程式碼,4核8G微軟伺服器免費用,Codespaces真香
- Java擴充套件Nginx之三:基礎配置項
- Java擴充套件Nginx之一:你好,nginx-clojure
- JavaCV的攝像頭實戰之十四:口罩檢測
- JavaCV人臉識別三部曲之二:訓練
- JavaCV人臉識別三部曲之一:視訊中的人臉儲存為圖片
- JavaCV的攝像頭實戰之八:人臉檢測
- 超詳細的編碼實戰,讓你的springboot應用識別圖片中的行人、汽車、狗子、喵星人(JavaCV YOLO4)
- Java應用日誌如何與Jaeger的trace關聯
- Spring Cloud Gateway實戰之五:內建filter
- Spring Cloud Gateway的斷路器(CircuitBreaker)功能
- Java版流媒體編解碼和影象處理(JavaCPP FFmpeg)
- DL4J實戰之六:圖形化展示訓練過程
- 純淨Ubuntu16安裝CUDA(9.1)和cuDNN
- disruptor筆記之六:常見場景
- Spring Cloud Gateway過濾器精確控制異常返回(分析篇)
- disruptor筆記之四:事件消費知識點小結
- disruptor筆記之二:Disruptor類分析
- disruptor筆記之一:快速入門
- Spring Native實戰(暢快體驗79毫秒啟動springboot應用)