是一種應用程序對應用程序的通訊方法。應用程序經過讀寫出入隊列的消息(針對應用程序的數據)來通訊,而無需專用鏈接來連接它們。java
消息傳遞指的是程序之間經過在消息中發送數據進行通訊,而不是經過直接調用彼此來通訊,直接調用一般是用於諸如遠程過程調用的技術。排隊指的是應用程序經過隊列來通訊。隊列的使用除去了接收和發送應用程序同時執行的要求。node
排隊指的是應用程序經過 隊列來通訊。隊列的使用除去了接收和發送應用程序同時執行的要求。python
高級消息隊列協議,是應用層協議的一個開放標準,爲面向消息的中間件設計。消息中間件主要用於組件之間的解耦,消息的發送者無需知道消息使用者的存在,反之亦然。web
AMQP 的主要特徵是面向消息、隊列、路由(包括點對點和發佈 / 訂閱)、可靠性、安全。vim
屬於一個流行的開源消息隊列系統。屬於AMQP( 高級消息隊列協議 ) 標準的一個 實現。是應用層協議的一個開放標準,爲面向消息的中間件設計。用於在分佈式系統中存儲轉發消息,在 易用性、擴展性、高可用性等方面表現不俗。安全
消息中間件主要用於組件之間的解耦,消息的發送者無需知道消息使用者的存在,反之亦然。
AMQP 的主要特徵是面向消息、隊列、路由(包括點對點和發佈 / 訂閱)、可靠性、安全。ruby
RabbitMQ特色:
使用Erlang編寫
支持持久化
支持HA
提供C# , erlang,java,perl,python,ruby等的client開發端bash
(一)、耦合
一、耦合是指兩個或兩個以上的體系或兩種運動形式間經過相互做用而彼此影響以致聯合起來的現象。服務器
二、在軟件工程中,對象之間的耦合度就是對象之間的依賴性。對象之間的耦合越高,維護成本越高,所以對象的設計應使類和構件之間的耦合最小。cookie
三、分類:有軟硬件之間的耦合,還有軟件各模塊之間的耦合。耦合性是程序結構中各個模塊之間相互關聯的度量。它取決於各個模塊之間的接口的複雜程度、調用模塊的方式以及哪些信息經過接口。
(二)、解耦
一、解耦,字面意思就是解除耦合關係。
二、在軟件工程中,下降耦合度便可以理解爲解耦,模塊間有依賴關係必然存在耦合,理論上的絕對零耦合是作不到的,但能夠經過一些現有的方法將耦合度降至最低。
三、設計的核心思想:儘量減小代碼耦合,若是發現代碼耦合,就要採起解耦技術。讓數據模型,業務邏輯和視圖顯示三層之間彼此下降耦合,把關聯依賴降到最低,而不至於牽一髮而動全身。原則就是A功能的代碼不要寫在B的功能代碼中,若是二者之間須要交互,能夠經過接口,經過消息,甚至能夠引入框架,但總之就是不要直接交叉寫。
Broker:簡單來講就是消息隊列服務器實體。
Exchange:消息交換機,它指定消息按什麼規則,路由到哪一個隊列。
Queue:消息隊列載體,每一個消息都會被投入到一個或多個隊列。
Binding:綁定,它的做用就是把exchange和queue按照路由規則綁定起來。
Routing Key:路由關鍵字, exchange根據這個關鍵字進行消息投遞。
vhost:虛擬主機,一個broker裏能夠開設多個vhost,用做不一樣用戶的權限分離。
producer:消息生產者,就是投遞消息的程序。
consumer:消息消費者,就是接受消息的程序。
channel:消息通道,在客戶端的每一個鏈接裏,可創建多個channel,每一個channel表明一個會話任務。
MQ 是消費 - 生產者模型的一個典型的表明,一端往消息隊列中不斷寫入消息,而另外一端則能夠讀取或者訂閱隊列中的消息。 MQ 則是遵循了 AMQP協議的具體實現和產品。在項目中,將一些無需即時返回且耗時的操做提取出來,進行了異步處理,而這種異步處理的方式大大的節省了服務器的請求響應時間,從而提升了系統的吞吐量。
( 1)客戶端鏈接到消息隊列服務器,打開一個channel。
( 2)客戶端聲明一個exchange,並設置相關屬性。
( 3)客戶端聲明一個queue,並設置相關屬性。
( 4)客戶端使用routing key,在exchange和queue之間創建好綁定關係。
( 5)客戶端投遞消息到exchange。
( 6) exchange接收到消息後,就根據消息的key和已經設置的binding,進行消息路由,將消息投遞到一個或多個隊列裏
元數據能夠持久化在 RAM 或 Disc。從這個角度能夠把 RabbitMQ 集羣中的節點分紅兩種 :RAM Node和 Disk Node.
RAM Node 只會將元數據存放在RAM
Disk node 會將元數據持久化到磁盤。
單節點系統就沒有什麼選擇了 , 只容許 disk node, 不然因爲沒有數據冗餘一旦重啓就會丟掉全部的配置信息 . 但在集羣環境中能夠選擇哪些節點是 RAM node.在集羣中聲明(declare) 建立 exchange queue binding, 這類操做要等到全部的節點都完成建立纔會返回 :
若是是內存節點就要修改內存數據 ,
若是是 disk node 就要等待寫磁盤 , 節點過多這裏的速度就會被大大的拖慢 。
有些場景 exchang queue 至關固定 , 變更不多 ,那即便全都是 disc node, 也沒有什麼影響 . 若是使用 Rabbitmq 作 RPC( RPC :Remote Procedure Call—遠程過程調用), RPC 或者相似 RPC 的場景這個問題就嚴重了 , 頻繁建立銷燬臨時隊列 , 磁盤讀寫能力就很快成爲性能瓶頸了。因此 , 大多數狀況下 , 咱們儘可能把 Node 建立爲RAM Node. 這裏就有一個問題了 , 要想集羣重啓後元數據能夠恢復就須要把集羣元數據持久化到磁盤 , 那須要規劃 RabbitMQ 集羣中的 RAM Node 和 Disc Node 。
只要有一個節點是 Disc Node 就能提供條件把集羣元數據寫到磁盤 ,RabbitMQ 的確也是這樣要求的 : 集羣中只要有一個 disk node 就能夠 , 其它的均可以是 RAM node. 節點加入或退出集羣必定至少要通知集羣中的一個 disk node 。
若是集羣中 disk node 都宕掉 , 就不要變更集羣的元數據 . 聲明 exchange queue 修改用戶權限 , 添加用戶等等這些變更在節點重啓以後沒法恢復 。
有一種狀況要求全部的 disk node 都要在線狀況在才能操做 , 那就是增長或者移除節點 。RAM node 啓動的時候會鏈接到預設的 disk node 下載最新的集羣元數據 . 若是你有兩個 disk node(d1 d2), 一個 RAM node 加入的時候你只告訴 d1, 而剛好這個 RAM node 重啓的時候 d1 並無啓動 , 重啓就會失敗 . 因此加入 RAM 節點的時候 , 把全部的disk node 信息都告訴它 ,RAM node 會把 disk node 的信息持久化到磁盤以便後續啓動能夠按圖索驥 .
一、前期準備
(1)條件:準備3臺Linux系統,確保配置好網絡源及epel源
(2)三臺機器可以靜態解析彼此(/etc/hosts)
(3)設置能夠免密登陸(ssh-keygen;ssh-copy-id)
二、安裝部署過程
(1)全部節點都安裝rabbitmq和erlang軟件包:
yum install -y erlang rabbitmq-server.noarch
systemctl start rabbitmq-server.service
systemctl enable rabbitmq-server.service
systemctl status rabbitmq-server.service
查看監聽的端口:
netstat -lantp | grep 5672
配置文件:
vim /etc/rabbitmq/rabbitmq.config
(2)節點1:編輯rabbitmq變量文件
[root@ren3 ~]# vim /etc/rabbitmq/rabbitmq-env.conf RABBITMQ_NODE_PORT=5672 ulimit -S -n 4096 RABBITMQ_SERVER_ERL_ARGS="+K true +A30 +P 1048576 -kernel inet_default_connect_options [{nodelay,true},{raw,6,18,<<5000:64/native>>}] -kernel inet_default_listen_options [{raw,6,18,<<5000:64/native>>}]" RABBITMQ_NODE_IP_ADDRESS=192.168.11.3
(3)節點1:將rabbitmq變量文件拷貝到其餘兩個節點上,以後修改相應節點的IP
scp /etc/rabbitmq/rabbitmq-env.conf ren4:/etc/rabbitmq/
scp /etc/rabbitmq/rabbitmq-env.conf ren5:/etc/rabbitmq/
查看rabbitmq插件:
/usr/lib/rabbitmq/bin/rabbitmq-plugins list
(4)全部節點開啓rabbitmq的web管理頁面
/usr/lib/rabbitmq/bin/rabbitmq-plugins enable rabbitmq_management mochiweb webmachine rabbitmq_web_dispatch amqp_client rabbitmq_management_agent
或者
rabbitmq-plugins enable rabbitmq_management
重啓服務
systemctl restart rabbitmq-server.service
systemctl status rabbitmq-server.service
查看端口
[root@ren3 ~]# ss -tnl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 192.168.11.3:5672 *:* LISTEN 0 128 *:25672 *:* LISTEN 0 128 *:4369 *:* LISTEN 0 128 *:22 *:* LISTEN 0 128 *:15672 *:* LISTEN 0 100 127.0.0.1:25 *:* LISTEN 0 128 :::22 :::* LISTEN 0 100 ::1:25 :::*
添加防火牆規則
firewall-cmd --add-port=5672/tcp
firewall-cmd --add-port=15672/tcp
firewall-cmd --add-port=25672/tcp
firewall-cmd --add-port=4369/tcp
登陸驗證:http://192.168.11.3:15672/#/ (用戶名默認:guest;密碼默認:guest)
(5)節點1發送erlang.cookie到其餘節點,來配置集羣(節點1爲主節點)
查看節點狀態
rabbitmqctl status
拷貝erlang.cookie到其餘節點
scp /var/lib/rabbitmq/.erlang.cookie ren4:/var/lib/rabbitmq/.erlang.cookie
scp /var/lib/rabbitmq/.erlang.cookie ren5:/var/lib/rabbitmq/.erlang.cookie
(6)節點2和節點3中止應用,並以ram的方式加入節點1,以後重啓應用
systemctl restart rabbitmq-server.service
rabbitmqctl stop_app
rabbitmqctl join_cluster --ram rabbit@ren3
rabbitmqctl start_app
(7)節點1檢查集羣狀態
[root@ren3 mnesia]# rabbitmqctl cluster_status Cluster status of node rabbit@ren3 ... [{nodes,[{disc,[rabbit@ren3,rabbit@ren5]},{ram,[rabbit@ren4]}]}, {running_nodes,[rabbit@ren4,rabbit@ren5,rabbit@ren3]}, {cluster_name,<<"rabbit@ren3">>}, {partitions,[]}, {alarms,[{rabbit@ren4,[]},{rabbit@ren5,[]},{rabbit@ren3,[]}]}]
(8)登陸驗證:http://192.168.11.3:15672/#/ (guest/guest)
三、其餘命令:
(1)修改guest密碼爲admin(默認用戶爲:guest 密碼爲:guest)
rabbitmqctl change_password guest admin
(2)添加一個openstack的用戶,並設置密碼爲admin。而且設置權限和成爲管理員:
rabbitmqctl add_user openstack admin rabbitmqctl set_permissions openstack ".*" ".*" ".*" rabbitmqctl set_user_tags openstack administrator
(3)添加管理員:
rabbitmqctl add_user mqadmin mqadmin rabbitmqctl set_user_tags mqadmin administrator rabbitmqctl set_permissions -p / mqadmin ".*" ".*" ".*"
(4)更改節點類型(內存型或者磁盤型)
rabbitmqctl stop_app
rabbitmqctl change_cluster_node_type disc 或 rabbitmqctl change_cluster_node_type ram
rabbitmqctl start_app
(5)從集羣移除節點(或者重置節點)
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
rabbitmqctl cluster_status
(6)從某個節點移除集羣中其它節點
rabbitmqctl forget_cluster_node rabbit@ren5
rabbitmqctl reset
rabbitmqctl start_app
rabbitmqctl cluster_status
四、注意事項