02消息隊列系列-RabbitMQ的初步認識、安裝、web管理端使用
參考鏈接:
深入剖析 rabbitMQ
一、關於RabbitMQ
RabbitMQ 本質其實是用 Erlang 開發的 AMQP(Advanced Message Queuing Protocol )的具體實現,最初起源於金融系統,主要用於在分布式系統中存儲轉發消息,在易用性、擴展性、高可用性等方面有着不俗的表現。
2010年4月,RabbitMQ 科技公司被 VMware 旗下的 SpringSource 收購,在 2013 年 5 月被並入 Pivotal 。
其實 VMware,Pivotal 本質上是一家的。不同的是,VMware 是獨立上市子公司,而 Pivotal 是整合了EMC的某些資源,現在並沒有上市。其中我們現在使用的 Spring 系列框架,就是 Pivotal 公司熱門的產品之一。
直到后來 Pivotal 將其開源,RabbitMQ 才逐漸走向大眾!
二、RabbitMQ模型介紹
2.1 內部結構分析
RabbitMQ 本質是 AMQP 協議的一個開源實現,在詳細介紹 RabbitMQ 之前,我們先來看一下 AMQP 的內部結構圖!
基本概念如下:
- Publisher:消息的生產者,也是一個向交換器發布消息的客戶端應用程序
- Exchange:交換器,用來接收生產者發送的消息並將這些消息路由給服務器中的隊列
- Binding:綁定,用於將消息隊列和交換器之間建立關聯。一個綁定就是基於路由將交換器和消息隊列連接起來的路由規則,所以可以將它理解稱一個由綁定構成的路由表。
- Queue:消息隊列,用來保存消息直到發送給消費者
- Connection:網絡連接,比如一個TCP連接
- Virtual Host:虛擬主機,表示一批交換器、消息隊列和相關對象。虛擬主機是共享相同的身份認證和加密環境的獨立服務器域。每個vhost本質上就是一個mini版的RabbitMQ服務器,擁有自己的隊列、交換器、綁定和權限機制。vhost是AMQP概念的基礎,必須在連接時指定,RabbitMQ默認的vhost是
/
- Broker:表示消息隊列服務器實體
- Message:消息實體,它由消息頭和消息體組成。消息頭主要由路由鍵、交換器、隊列、priority(相對於其他消息的優先權)、delivery-mode(指出該消息可能需要持久性存儲)等屬性組成,而消息體就是指具體的業務對象
相比傳統JMS模型,AMQP主要多了Exchange、Binding這個新概念。
在 AMQP 模型中,消息的生產者不是直接將消息發送到Queue
隊列,而是將消息發送到Exchange
交換器,其中還新加了一個中間層Binding
綁定,作用就是通過路由鍵Key
將交換器和隊列建立綁定關系。
就好比類似用戶表和角色表,中間通過用戶角色表來將用戶和角色建立關系,從而實現關系綁定,在 RabbitMQ 中,消息生產者不直接跟隊列建立關系,而是將消息發送到交換器之后,由交換器通過已經建立好的綁定關系,將消息發送到對應的隊列!
RabbitMQ 最終的架構模型,核心部分就變成如下圖所示:
從圖中很容易看出,與 JMS 模型最明顯的差別就是消息的生產者不直接將消息發送給隊列,而是由Binding
綁定決定交換器的消息應該發送到哪個隊列,進一步實現了在消息的推送方面,更加靈活!
2.2 交換器分發策略
當消息的生產者將消息發送到交換器之后,是不會存儲消息的,而是通過中間層綁定關系將消息分發到不同的隊列上,其中交換器的分發策略分為四種:Direct、Topic、Headers、Fanout!
- Direct:直連類型,即在綁定時設定一個 routing_key,消息的 routing_key 匹配時,才會被交換器投送到綁定的隊列中去,原則是先匹配、后投送
- Topic:按照規則轉發類型,支持通配符匹配,和Direct功能一樣,但是在匹配 routing_key的時候,更加靈活,支持通配符匹配,原則也是先匹配、后投送
- Headers:頭部信息匹配轉發類型,根據消息頭部中的 header attribute參數類型,將消息轉發到對應的隊列,原則也是先匹配、后投送
- Fanout:廣播類型,將消息轉發到所有與該交換機綁定的隊列上,不關心 routing_key
2.2.1 Direct
Direct 是 RabbitMQ 默認的交換機模式,也是最簡單的模式,消息中的路由鍵(routing key)如果和 Binding 中的 binding key 一致, 交換器就將消息發到對應的隊列中。
如果傳入的 routing key 為 black
,不會轉發到black.green
。Direct 類型交換器是完全匹配、單播的模式。
2.2.2 Topic
Topic 類型交換器轉發消息和 Direct 一樣,不同的是:它支持通配符轉發,相比 Direct 類型更加靈活!
兩種通配符:*
只能匹配一個單詞,#
可以匹配零個或多個。
如果傳入的 routing key 為 black#
,不僅會轉發到black
,也會轉發到black.green
。
2.2.3 Headers
headers 也是根據規則匹配, 相比 direct 和 topic 固定地使用 routing_key , headers 則是通過一個自定義匹配規則的消息頭部類進行匹配。
在隊列與交換器綁定時,會設定一組鍵值對規則,消息中也包括一組鍵值對( headers 屬性),當這些鍵值對有一對, 或全部匹配時,消息被投送到對應隊列。
此外 headers 交換器和 direct 交換器完全一致,但性能差很多,目前幾乎用不到了。
2.2.4 Fanout
Fanout 類型交換器與上面幾個不同,不管路由鍵或者是路由模式,會把消息發給綁定給它的全部隊列,如果配置了 routing_key 會被忽略,也被成為消息廣播模式。很像子網廣播,每台子網內的主機都獲得了一份復制的消息。
三、RabbitMQ安裝
RabbitMQ 基於 erlang 進行通信,相比其它的軟件,安裝有些麻煩,為了跟生產環境保持一直,操作系統選擇CentOS7
,不過本例采用rpm
方式安裝,任何新手都可以完成安裝,過程如下!
3.1 安裝前命令准備
輸入如下命令,完成安裝前的環境准備。
yum install lsof build-essential openssl openssl-devel unixODBC unixODBC-devel make gcc gcc-c++ kernel-devel m4 ncurses-devel tk tc xz wget vim
3.2 下載RabbitMQ、erlang、socat的安裝包
本次下載的是RabbitMQ-3.6.5
版本,采用rpm
一鍵安裝,適合新手直接上手。
先創建一個rabbitmq
目錄,本例的目錄路徑為/usr/app/rabbitmq
,然后在目錄下執行如下命令,下載安裝包!
- 下載erlang
wget www.rabbitmq.com/releases/erlang/erlang-18.3-1.el7.centos.x86_64.rpm
- 下載socat
wget http://repo.iotti.biz/CentOS/7/x86_64/socat-1.7.3.2-5.el7.lux.x86_64.rpm
- 下載RabbitMQ
wget www.rabbitmq.com/releases/rabbitmq-server/v3.6.5/rabbitmq-server-3.6.5-1.noarch.rpm
3.3 安裝安裝包
下載完之后,按順序依次安裝軟件包,這個很重要哦~
- 安裝erlang
rpm -ivh erlang-18.3-1.el7.centos.x86_64.rpm
- 安裝socat
rpm -ivh socat-1.7.3.2-5.el7.lux.x86_64.rpm
- 安裝rabbitmq
rpm -ivh rabbitmq-server-3.6.5-1.noarch.rpm
安裝完成之后,修改rabbitmq
的配置,默認配置文件在/usr/lib/rabbitmq/lib/rabbitmq_server-3.6.5/ebin
目錄下。
vim /usr/lib/rabbitmq/lib/rabbitmq_server-3.6.5/ebin/rabbit.app
修改loopback_users
節點的值!
最后只需通過如下命令,啟動服務即可!
rabbitmq-server start &
運行腳本之后,如果報錯,例如下圖!
解決辦法如下:
vim /etc/rabbitmq/rabbitmq-env.conf
在文件里添加一行,如下配置!
NODENAME=rabbit@localhost
然后,再保存!再次以下命令啟動服務!
rabbitmq-server start &
通過如下命令,查詢服務是否啟動成功!
lsof -i:5672
3.4 啟動可視化的管控台
輸入如下命令,啟動控制台!
rabbitmq-plugins enable rabbitmq_management
用瀏覽器打開http://ip:15672
,這里的ip
就是 CentOS 系統的 ip,結果如下:
賬號、密碼,默認為guest
,如果出現無法訪問,檢測防火牆是否開啟,如果開啟將其關閉即可!
登錄之后的監控平台,界面如下:
3.5 Docker引擎下安裝啟動RabbitMQ
3.5.1 進入docker hub鏡像倉庫地址
3.5.2 搜索RabbitMQ
進入官方的鏡像,可以看到以下幾種類型的鏡像;我們選擇帶有“mangement”的版本(包含web管理頁面)
3.5.3 拉取鏡像
docker pull rabbitmq:3.7.7-management
3.5.4 根據下載的鏡像創建和啟動容器
docker run -d -p 5672:5672 -p 15672:15672
-d 后台運行容器
-p 指定服務運行的端口(5672:應用訪問端口;15672:控制台Web端口號)
3.5.5 使用瀏覽器打開web管理端:http://Server-IP:15672
四、web界面使用
進入 web 管理界面之后,可以很清晰的看到分了 6 個菜單目錄,分別是:Overview、Connections、Channels、Exchanges、Queues、Admin。
4.1 Overview
4.1.1 Overview-> Totals
4.1.1.1 Queued message 所有隊列的阻塞情況
4.1.1.2 Message rates 所有隊列的消費情況
速率=(num1-num0)/(s1-s0)
num1:s1時刻的個數
num0:s0時刻的個數
4.1.1.3 整體角色的個數
4.1.2 Overview-> Nodes
4.1.2.1 broker的屬性
- Name:broker名稱
- File descriptors:broker打開的文件描述符和限制。
- Socket descriptors:broker管理的網絡套接字數量和限制。當限制被耗盡時,RabbitMQ將停止接受新的網絡連接。
- Erlang processes:erlang啟動的進程數。
- Memory:當前broker占用的內存。
- Disk space:當前broker占用的硬盤。
- Uptime:當前broker持續運行的時長。
- Info:未知。
- Reset stats:未知。
4.1.3 Overview-> Ports and contexts
4.1.4 Overview-> Export definitions
定義由用戶,虛擬主機,權限,參數,交換,隊列和綁定組成。 它們不包括隊列的內容或集群名稱。 獨占隊列不會被導出。
4.1.5 Overview-> Inport definitions
導入的定義將與當前定義合並。 如果在導入過程中發生錯誤,則所做的任何更改都不會回滾。
4.2 Connections
當前所有客戶端活動的連接。包括生成者和消費者。
- Name:名稱。
- User name:使用的用戶名。
- State:當前的狀態,running:運行中;idle:空閑。
- SSL/TLS:是否使用ssl進行連接。
- Protocol:使用的協議。
- Channels:創建的channel的總數。
- From client:每秒發出的數據包。
- To client:每秒收到的數據包。
4.3 Channels
當前連接所有創建的通道。
- channel:名稱。
- User name:使用的用戶名。
- Mode:渠道保證模式。 可以是以下之一,或者不是:C: confirm。T:transactional(事務)。
- State :當前的狀態,running:運行中;idle:空閑。
- Unconfirmed:待confirm的消息總數。
- Prefetch:設置的prefetch的個數。
- Unacker:待ack的消息總數。
- publish:producter pub消息的速率。
- confirm:producter confirm消息的速率。
- deliver/get:consumer 獲取消息的速率。
- ack:consumer ack消息的速率。
4.4 Exchanges
Name:名稱。
Type:exchange type
Features:功能。 可以是以下之一,或者不是:D: 持久化。I:Internal,存在該功能表示這個exchange不可以被client用來推送消息,僅用來進行exchange和exchange之間的綁定,否則可以推送消息也可以綁定。
Message rate in:消息進入的速率。
Message rate out:消息出去的速率。
4.4.1 Exchanges-> Add a new exchange
新增一個交換器
- Name:交換器名稱
- Type:交換器類型
- Durability:是否持久化,Durable:持久化,Transient:不持久化
- Auto delete:是否自動刪除,當最后一個綁定(隊列或者exchange)被unbind之后,該exchange 自動被刪除
- Internal:是否是內部專用exchange,是的話,就意味着我們不能往該exchange里面發消息
- Arguments:參數,是AMQP協議留給AMQP實現做擴展使用的
我們先新建一個名稱為hello-exchange
,類型為direct
的交換器,結果如下。
等會用於跟隊列關聯!
4.5 Queues
隊列管理
- Name:名稱。
- Type:隊列類型
- Features:功能。 可以是以下之一,或者不是:D: 持久化。
- State:當前的狀態,running:運行中;idle:空閑。
- Ready:待消費的消息總數。
- Unacked:待應答的消息總數。
- Total:總數 Ready+Unacked。
- incoming:消息進入的速率。
- deliver/get:消息獲取的速率。
- ack:消息應答的速率。
4.5.1 Queues-> Add a new queue
- Type:隊列類型
- Name:隊列名稱
- Durability:是否持久化,Durable:持久化,Transient:不持久化
- Auto delete:是否自動刪除,是的話,當隊列內容為空時,會自動刪除隊列
- Arguments:參數,是AMQP協議留給AMQP實現做擴展使用的
同樣的,新建一個名稱為hello-mq
的消息隊列,結果如下。
隊列新建好了之后,繼續來建立綁定關系!
4.5.1.1 綁定隊列
建立綁定關系,既可以從隊列進入也可以從交換器進入。
- 如果是從交換器進入,那么被關聯的對象就是隊列。
- 如果是從隊列進入,那么被關聯的對象就是交換器。
我們選擇從隊列入手,被綁定的交換器是hello-exchange
,因為類型是direct
,所以還需要填寫routing key
。
建立完成之后,在交換器那邊也可以看到對應的綁定關系。
4.5.1.2 發送消息
最后,我們從交換器入手,選擇對應的交換器,點擊Publish message
標簽,填寫對應的路由鍵 key,發送一下數據,查看數據是否發送到對應的隊列中。
然后點擊進入 Queues 菜單,查詢消息隊列基本情況。
然后選擇hello-mq
消息隊列,點擊Get messages
標簽,獲取隊列中的消息。
結果如下,可以很清晰的看到,消息寫入到隊列!
4.6 Admin
系統管理,主要介紹用戶、虛擬主機、權限等信息
- Name:名稱。
- Tags:角色標簽,只能選取一個。
- administrator (超級管理員)
- 可登陸管理控制台(啟用management plugin的情況下),可查看所有的信息,並且可以對用戶,策略(policy)進行操作。
- monitoring(監控者)
- 可登陸管理控制台(啟用management plugin的情況下),同時可以查看rabbitmq節點的相關信息(進程數,內存使用情況,磁盤使用情況等)
- policymaker(策略制定者)
- 可登陸管理控制台(啟用management plugin的情況下), 同時可以對policy進行管理。
- management(普通管理者)
- 僅可登陸管理控制台(啟用management plugin的情況下),無法看到節點信息,也無法對策略進行管理。
- none(其他)
- 無法登陸管理控制台,通常就是普通的生產者和消費者。
- administrator (超級管理員)
- Can access virtual hosts:允許進入的vhost。
- Has password:設置了密碼。
到此結束