當前位置:股票大全官網 - 基金投資 - 從發布-訂閱模式到消息隊列

從發布-訂閱模式到消息隊列

發布-訂閱模式又稱為觀察者模式(網上也有很多說這兩種模式區別,個人覺得區別不大),在發布-訂閱模式中,主要是兩大塊。就是發布和訂閱,那麽發布(publish)和訂閱(subscribe)之前的關聯點就是主題(topic).

舉個生活的例子,午餐定外賣,燕姐(broker)在外賣群裏發布了兩個可以點的餐館,都城和輝記(這個可以稱為主題),小明(Consumer)點了輝記的,文哥(Consumer)點了都城的(這個可以稱為訂閱),都城餐館(producer)和輝記餐館(producer)做好了飯菜就回給外賣小哥送過來(消息協議),飯菜到了燕姐那裏之後,那麽小明和文哥就能去燕姐那裏去拿(pull),也可以燕姐送過來(push)。這就是我們生活中最常見的發布-訂閱模式。

從上文中可以得到,外賣群是壹個載體(MQ),承載消息的存儲和傳送,從這裏可以引出消息隊列的這個概念,下面,繼續說下消息隊列。

MQ (Message Queue) 又稱消息隊列. 隊列我們都知道,那什麽是消息呢?消息指的是同壹臺機器的進程之間,或不同機器之間傳輸的數據。最簡單的說,我們壹個Rpc 請求,所帶的數據就是壹個消息。這就是傳統的通信模式。但是這種模式有很多缺陷,例如當網絡不好的時候,這種調用可能會丟失。

隊列提供了壹種壹步通信協議,這意味著消息的發送者和接收者不需要同時於消息保持聯系,發送者的消息會存儲在隊列中,直到接收者拿到它。 壹般我們把消息的發送者稱為生產者,消息的接收者稱為消費者。由於生產者和消費者之間是不透明的,他們靠中間的紐帶-隊列來聯系,那麽在隊列中,是消費者占主動還是生產者占主動呢,其實根據不同的獲取消息的方式可以分為 pull or push 著兩種。按字面上的理解,就是pull 是消費者需要自己控制去隊列拉取消息,而push則是生產者占主動位置,將產生的消息push 給消費者,而這種push 可以點對點,也可以是壹對多,而這種壹對多的模式就是我們常說的廣播模式

在分布式系統中,消息中間件是非常重要的組件,主要解決應用耦合,異步消息,流量削峰等問題。

常用的消息隊列中間件有 activeMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ

(可參考 /s/ad7jibTb5nTzh3nDQYKFeg ? 覺得這篇文章寫得很不錯也很詳細)

這次我主要寫的是kafka 這個消息中間件,kafka 是采用pull 這種模式來消費信息的,生產者將消息放入隊列中,而消費者可以通過epull 方法獲取消息來消費,下面還是先說下kafka 的幾個關鍵概念吧

Kafka是最初由Linkedin公司開發,是壹個分布式、分區的、多副本的、多訂閱者,基於zookeeper協調的分布式日誌系統(也可以當做MQ系統),常見可以用於web/nginx日誌、訪問日誌,消息服務等等,Linkedin於2010年貢獻給了Apache基金會並成為頂級開源項目

主要應用場景是:日誌收集系統和消息系統。

Kafka主要設計目標如下:

同時支持離線數據處理和實時數據處理。

壹個典型的kafka集群中包含若幹producer,若幹broker,若幹consumer,以及壹個Zookeeper集群。Kafka通過Zookeeper管理集群配置,選舉leader,以及在consumer group發生變化時進行rebalance。producer使用push模式將消息發布到broker,consumer使用pull模式從broker訂閱並消費消息。

Topic & Partition

壹個topic可以認為壹個壹類消息,每個topic將被分成多個partition,每個partition在存儲層面是append log文件。

在Kafka文件存儲中,同壹個topic下有多個不同partition,每個partition為壹個目錄,partiton命名規則為topic名稱+有序序號,第壹個partiton序號從0開始,序號最大值為partitions數量減1

每個partion(目錄)相當於壹個巨型文件被平均分配到多個大小相等segment(段)數據文件中。但每個段segment file消息數量不壹定相等,這種特性方便old segment file快速被刪除。

每個partiton只需要支持順序讀寫就行了,segment文件生命周期由服務端配置參數決定。

這樣做的好處就是能快速刪除無用文件,有效提高磁盤利用率。

segment file組成:由2大部分組成,分別為index file和data file,此2個文件壹壹對應,成對出現,後綴".index"和“.log”分別表示為segment索引文件、數據文件.

segment文件命名規則:partion全局的第壹個segment從0開始,後續每個segment文件名為上壹個segment文件最後壹條消息的offset值。數值最大為64位long大小,19位數字字符長度,沒有數字用0填充。

同壹Topic的壹條消息只能被同壹個Consumer Group內的壹個Consumer消費,但多個Consumer Group可同時消費這壹消息。

這是Kafka用來實現壹個Topic消息的廣播(發給所有的Consumer)和單播(發給某壹個Consumer)的手段。壹個Topic可以對應多個Consumer Group。如果需要實現廣播,只要每個Consumer有壹個獨立的Group就可以了。要實現單播只要所有的Consumer在同壹個Group裏。用Consumer Group還可以將Consumer進行自由的分組而不需要多次發送消息到不同的Topic。

參考:

/detail/blog.action?bid=1016&hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io