足球资料库数据/孙祥/nba五佳球/足球直播哪个平台好 - cctv5今日现场直播

首頁 > 知識庫 > 正文

深度解析RabbitMQ集群
2016-03-14 21:48:35   來源: mengyidan1988   評論:0 點擊:

摘要:OpenStack已經在很多大型企業里支撐起核心生產業務,這都源于OpenStack中的核心技術與架構,超大規模高可用OpenStack平臺核心技術深入解析系列文章,主要介紹了EasyStack在企業級OpenStack一線實踐中的所見所感,將分為消息隊列篇,計算篇,存儲篇,網絡篇等等,每篇中的內容都以基礎、高級劃分,將OpenStack落地最后一公里實打實所遇到的問題分享給大家。 在上一篇中
摘要:OpenStack已經在很多大型企業里支撐起核心生產業務,這都源于OpenStack中的核心技術與架構,超大規模高可用OpenStack平臺核心技術深入解析系列文章,主要介紹了EasyStack在企業級OpenStack一線實踐中的所見所感,將分為消息隊列篇,計算篇,存儲篇,網絡篇等等,每篇中的內容都以基礎、高級劃分,將OpenStack落地最后一公里實打實所遇到的問題分享給大家。

在上一篇中,我們已經詳細介紹了RabbitMQ的發展歷程與AMQP協議中的相關概念,接下來,我們開始進入高級篇的部分,深入介紹如何搭建RabbitMQ集群,以及在RabbitMQ集群中做插件管理、構建HA方案、如何實現通過RabbitMQ支撐高并發的大規模生產集群,本文中將深入解析RabbitMQ服務器與集群。

一、RabbitMQ 服務器



首先,RabbitMQ是基于Erlang語言編寫,RabbitMQ 服務器啟動后,erlang框架會啟動底層的Erlang node,上層啟動Erlang 應用和其它的輔助應用,此架構類似于JVM,在一個節點的應用出問題時,該節點仍繼續運行,如上圖所示。

如何查看RabbitMQ當前的運行狀態?

在部署好的集群當中,您可以通過rabbitmqctl status可以查看到RabbitMQ的狀態。



上圖中,紅框內為運行的應用。 Rabbit即為RabbitMQ 服務器。其余則為Erlang/OTP提供的application。

? os_mon: operating system monitor,操作系統監控

? xmerl: Functions for exporting XML data to an external format,導出XML數據到外部格式

? mnesia: a distributed DataBase Management System (DBMS), appropriate for telecommunications applications and other Erlang applications which require continuous operation and exhibit soft real-time properties. 一個分布式數據庫管理系統,適合于電信應用和其他需要持續操作并展示實時信息的應用

? SASL (System Architecture Support Libraries)

? Kernel & stdlib: The Kernel application is the first application started. It is mandatory in the sense that the minimal system based on Erlang/OTP consists of Kernel and STDLIB. 是第一個啟動的服務,其作為Erlang框架的核心。

注:以上Erlang/OTP的應用都可以通過 “erl –man ”查詢它的幫助文檔。

如何啟動RabbitMQ服務?

RabbitMQ 服務器是通過erl啟動,啟動時需要進行一系列的應用參數配置:



如上圖所示,配置的參數包括了節點名稱,配置,日志,插件等等

RabbitMQ 服務啟動后,會運行哪些進程?

epmd(Erlang Port Mapper Daemon):

? Erlang Port Mapper Daemon (epmd). 當啟動分布式的Erlang node時,epmd將記錄IP/Port信息。 當使用rabbitmqctl join_cluster將Erlang node連接成集群時,epmd負責節點名稱和IP/Port的轉換。

Beam.smp:

RabbitMQ創建的眾多處理消息的線程。

如何設置防火墻?

由于RabbitMQ中上述的應用都在監聽不同的端口,如果rabbitmq-server所在的節點需要進行防火墻設置,則需要打開如下端口:
epmd:4369rabbit:5672(默認值,可通過RABBITMQ_NODE_PORT更改)rabbit management plugin: 15672Kernel application: 41055  (在 rabbit.conf 中配置)

如何管理RabbitMQ?

RabbitMQ提供的唯一操作工具就是rabbitmqctl。除了常規的queue/exchange/policy/user/permission等操作外,可以利用它的“eval”子命令,來擴展出很多功能。比如查詢net_ticktime / erlang cookie。



如何選擇RabbitMQ的消息保存方式?

RabbitMQ對于queue中的message的保存方式有兩種方式:disc和ram。如果采用disc,則需要對exchange/queue/delivery mode都要設置成durable模式。Disc方式的好處是當RabbitMQ失效了,message仍然可以在重啟之后恢復。而使用ram方式,RabbitMQ處理message的效率要高很多,ram和disc兩種方式的效率比大概是3:1。所以如果在有其它HA手段保障的情況下,選用ram方式是可以提高消息隊列的工作效率的。

如果使用ram方式,RabbitMQ能夠承載的訪問量則取決于可用的內存數了。RabbitMQ使用兩個參數來限制使用系統的內存,避免系統被自己獨占。
[{rabbit, [{vm_memory_high_watermark_paging_ratio, 0.75},          {vm_memory_high_watermark, 0.4}]}].

vm_memory_high_watermark:表示RabbitMQ使用內存的上限為系統內存的40%。也可以通過absolute參數制定具體可用的內存數。當RabbitMQ使用內存超過這個限制時,RabbitMQ 將對消息的發布者進行限流,直到內存占用回到正常值以內。

Vm_memory_high_watermark_paging_ratio:表示當RabbitMQ達到0.4*0.75=30%,系統將對queue中的內容啟用paging機制,將message等內容換頁到disk 中。

RabbitMQ的內存使用情況可以通過“rabbitmqctl status”或者管理插件中的Web UI查詢。



各個內存條目的含義請參照:https://www.rabbitmq.com/memory-use.html

當消息發送的速率超過了RabbitMQ的處理能力時該怎么辦?

RabbitMQ會自動減慢這個連接的速率,讓client端以為網絡帶寬變小了,發送消息的速率會受限,從而達到流控的目的。 使用”rabbitmqctl list_connections”查看連接,如果狀態為“flow”,則說明這個連接處于flow-control 狀態。

RabbitMQ集群

RabbitMQ基于Erlang編寫,天然支持clustering。集群是保證可靠性的一種方式,同時可以通過水平擴展以達到增加消息吞吐能力的目的。



上圖中是三個節點的RabbitMQ集群,Exchange A的metadata信息在所有節點上是一致的,queue的完整信息則只在它創建的那個節點上。每個RabbitMQ節點通常以“rabbit@”表示,所以hostname在運行RabbitMQ的節點中很重要。注意:如果更改了hostname,需要重置RabbitMQ內部的數據庫,否則服務無法工作。

如何構建集群?

單個rabbitmq-server啟動之后,在確保Erlang cookie相同的情況下,可以通過
rabbitmqctl stop_apprabbitmqctl join_cluster rabbit@<hostname>rabbitmqctl start_app

將幾個RabbitMQ節點連接成集群。RabbitMQ集群由Erlang/OTP提供的通訊機制保證集群節點之間的通訊。從邏輯上講,RabbitMQ集群是單一的message broker,消息隊列消費者連接集群中的任一個節點都可以。如果配合HAProxy,client只需要訪問單一一個地址,由HAProxy負責load balance,將訪問請求分發給各個節點。

如果單純做試驗,也可以在一個虛擬機上啟動三個RabbitMQ的實例,只要在啟動時通過設置RABBITMQ_NODE_PORT讓三個實例監聽不同端口即可。

RabbitMQ維護著四種類型的metadata: queue/exchange/binding/vhost,在集群中這些信息被同步到每個節點,因此當用戶訪問任何一個節點時,通過rabbitmqctl查詢到的queue/user/exchange等信息都是相同的。

通常我們將這些信息保存到磁盤上,也就是查詢RabbitMQ狀態時的“disc”方式,以便集群重啟時可以根據保存的metadata信息重建exchange等。

對于exchange來講,它的所有信息就是一個exchange名字加上一個查詢表。查詢表中記錄了所有的queue binding。當message被發送到exchange時,client連接的channel對routing key進行比對,根據binding進行正確的轉發。

對于Queue來講,雖然它的metadata在每個節點上都有,但只有在它被創建的那個RabbitMQ 節點上才具有完整的信息:比如state/contents等,這個node被稱為此queue的owner node。其他節點只知道這個queue的metadata信息和一個指向queue的owner node的指針。

如果一個client訪問RabbitMQ的節點上沒有需要的queue的完整信息,RabbitMQ將根據這個指針將請求轉發到owner node。



這張圖上可以看到,Exchange的所有信息被復制到集群中的所有節點,“Queue 1”的metadata被復制到每個節點,但它的完整信息(content)只存在于一個節點上,也就是這個queue的owner node。

Mnesia是RabbitMQ中的數據庫,它是內嵌在Erlang中的no-SQL數據庫。Exchange/Queue/Binding等的metadata信息都保存在mnesia的數據庫文件中。關于RabbitMQ的集群信息也保存在這里。Rabbitmqctl的reset操作實際上就是清空了mnesia數據庫所在目錄的內容。

RabbitMQ集群模式

除了上面講到的RabbitMQ 內嵌的clustering方式進行分布式的消息處理,RabbitMQ還有federation/shovel兩種分布式方式,這兩種方式以RabbitMQ plugin的形式存在。RabbitMQ對網絡延遲很敏感,在單個數據中心中使用clustering方式。在WAN環境中,則使用Federation或Shovel。

以Shovel為例,在rabbitmq.conf中定義rabbitmq_shovel的配置,主要是對兩個獨立RabbitMQ 節點中,定義源和目的節點中exchange/queue的replication關系。當一個請求發送到源RabbitMQ節點時,先響應請求,之后根據replication關系,shovel會異步的將message傳送到目的RabbitMQ節點進行處理。

這里對federation/shovel聯邦模式跟clustering集群模式一個簡單的對比。



作者:石奎,EasyStack高級架構師,曾任職WindRiver/EMC/華為等知名企業,十余年Linux操作系統定制開發及Kernel驅動開發經驗,2012年開始貢獻OpenStack社區,曾參與設計并實施國內金融領域首個支撐核心生產系統高可靠、高可用OpenStack云平臺,具有豐富的超大規模OpenStack云平臺的設計與實施經驗,去年開始深入研究NFV領域技術及項目設計實施。

相關熱詞搜索:RabbitMQ 集群 database 數據庫

上一篇:2016 年美國最賺錢職位排行榜,IT 相關比例高
下一篇:每天用的App竟然這么不安全 這15張PPT讓人觸目驚心!

分享到: 收藏