參考
http://dl528888.blog.51cto.com/2382721/1864895
<a href="http://kaibinyuan.blog.51cto.com/7304008/1610110" target="_blank">http://kaibinyuan.blog.51cto.com/7304008/1610110</a>
原因:
最近有一個異步需要使用消息隊列,或許最終會選擇阿裡的rocketmq
性能
單台TPS基本上是在2000-3000左右
最新rabbitmq版本是3.6.2
yum安裝
配置檔案
RPM- /etc/rabbitmq/
http://www.cnblogs.com/stormli/p/rabbitmq.html
Broker:簡單來說就是消息隊列伺服器實體。
Exchange:消息交換機,它指定消息按什麼規則,路由到哪個隊列。
Queue:消息隊列載體,每個消息都會被投入到一個或多個隊列。
Binding:綁定,它的作用就是把exchange和queue按照路由規則綁定起來。
Routing Key:路由關鍵字,exchange根據這個關鍵字進行消息投遞。
vhost:虛拟主機,一個broker裡可以開設多個vhost,用作不同使用者的權限分離。
producer:消息生産者,就是投遞消息的程式。
consumer:消息消費者,就是接受消息的程式。
channel:消息通道,在用戶端的每個連接配接裡,可建立多個channel,每個channel代表一個會話任務
http://blog.csdn.net/u013142781/article/details/50487028
AMQP當中有四個概念非常重要:虛拟主機(virtual host),交換機(exchange),隊列(queue)和綁定(binding)。一個虛拟主機持有一組交換機、隊列和綁定。為什麼需要多個虛拟主機呢?很簡單,RabbitMQ當中,使用者隻能在虛拟主機的粒度進行權限控制。是以,如果需要禁止A組通路B組的交換機/隊列/綁定,必須為A和B分别建立一個虛拟主機。每一個RabbitMQ伺服器都有一個預設的虛拟主機“/”。如果這就夠了,那現在就可以開始了。
通過 Erlang 的分布式特性(通過 magic cookie 認證節點)進行 RabbitMQ 叢集,各 RabbitMQ 服務為對等節點,即每個節點都提供服務給用戶端連接配接,進行消息發送與接收。
這些節點通過 RabbitMQ HA 隊列(鏡像隊列)進行消息隊列結構複制。本方案中搭建 3 個節點,并且都是磁盤節點(所有節點狀态保持一緻,節點完全對等),隻要有任何一個節點能夠工作,RabbitMQ 叢集對外就能提供服務。
Rabbitmq系統架構
RabbitMQ Server: 也叫broker server,是一種傳輸服務,負責維護一條從Producer到consumer的路線,保證資料能夠按照指定的方式進行傳輸。
Producer,資料的發送方。
Consumer,資料的接收方。
Exchanges 接收消息,轉發消息到綁定的隊列。主要使用3種類型:direct, topic, fanout。
Queue RabbitMQ内部存儲消息的對象。相同屬性的queue可以重複定義,但隻有第一次定義的有效。
Bindings 綁定Exchanges和Queue之間的路由。
Connection: 就是一個TCP的連接配接。Producer和consumer都是通過TCP連接配接到RabbitMQ Server的。
Channel:虛拟連接配接。它建立在上述的TCP連接配接中。資料流動都是在Channel中進行的。也就是說,一般情況是程式起始建立TCP連接配接,第二步就是建立這個Channel。
2.源碼安裝
紅色标記必須做
yum remove rabbitmq-server -y
yum -y install erlang
yum -y install gcc gcc-c++ ncurses-devel
wget http://www.erlang.org/download/otp_src_R16B01.tar.gz
tar xvf otp_src_R16B01.tar.gz
cd otp_src_R16B01
./configure && make && make install
wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.5.1/rabbitmq-server-generic-unix-3.5.1.tar.gz
tar zxvf rabbitmq-server-generic-unix-3.5.1.tar.gz
#ln -svf /usr/local/src/rabbitmq_server-3.4.3 /usr/local/rabbitmq-node1
#mkdir -p /usr/local/rabbitmq-node1
cd /opt/soft && mv rabbitmq_server-3.5.1 /usr/local
cd /usr/local && mv rabbitmq_server-3.5.1 rabbitmq-node1
mv rabbitmq_server-3.5.1 /opt/local/rabbitmq
vim ~/.bash_profile
PATH=/opt/mysql/bin:$PATH:$HOME/bin:/usr/lib/rabbitmq/bin/:/usr/local/rabbitmq-node1/sbin/:$PATH
source ~/.bash_profile
啟用web插件
#rabbitmq-plugins enable rabbitmq_management #啟用
關閉web插件
# rabbitmq-plugins disable rabbitmq_management
rabbitmq-plugins enable rabbitmq_management
rabbitmq-plugins list
rabbitmqctl stop
rabbitmq-server -detached
rabbitmqctl cluster_status
scp -P 8022 .erlang.cookie [email protected]:/root/
ps -ef | grep rabbitmq | grep -v "grep"
kill -9 54239
rabbitmqctl join_cluster rabbit@rabbitmq-test2
rabbitmqctl stop_app
rabbitmqctl start_app
rabbitmqctl change_password guest kaibin
cat /usr/local/rabbitmq-node2/ebin/rabbit.app | grep loopback --color
{loopback_users,[<<"">>]},
(雖然可以以比較猥瑣的方式:将ebin目錄下rabbit.app中loopback_users裡的<<"guest">>删除,或者在配置檔案rabbitmq.config中對該項進行配置,
https://my.oschina.net/hncscwc/blog/262246
并重新開機rabbitmq,可通過任意IP使用guest賬号登陸管理控制台
http://kaibinyuan.blog.51cto.com/7304008/1610110
處于安全的考慮,guest這個預設的使用者隻能通過localhost來登入,其他的IP無法直接使用這個賬号為了解決這個問題,需要在rabbitmq的配置檔案中将loopback_users配置設定為空
http://dwf07223.blog.51cto.com/8712758/1547226
解決RabbitMQ遠端不能通路的問題
注意:rabbitmq從3.3.0開始禁止使用guest/guest權限通過除localhost外的通路。
如果想使用guest/guest通過遠端機器通路,需要在rabbitmq配置檔案中(/etc/rabbitmq/rabbitmq.config)中設定loopback_users為[]。
/etc/rabbitmq/rabbitmq.config檔案完整内容如下(注意後面的半角句号):
[{rabbit, [{loopback_users, []}]}].
rabbitmq的web管理界面預設guest:guest,這樣的話,不是很安全,需要更改下
[root@rabbitmq-test1 ~]# rabbitmqctl change_password guest kaibin
Changing password for user "guest" ...
...done.
)
設計鏡像隊列政策
rabbitmqctl set_policy ha-all '^(?!amq\.).*' '{"ha-mode": "all"}'
#rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
#沿用3.2的環境,現在我們把名為“hello”的隊列設定為同步給所有節點
#rabbitmqctl set_policy ha-all “hello” ‘{“ha-mode”:”all”}’
ha-all 是同步模式,指同步給所有節點,還有另外兩種模式ha-exactly表示在指定個數的節點上進行鏡像,節點的個數由ha-params指定,ha-nodes表示在指定的節點上進行鏡像,節點名稱通過ha-params指定;
hello 是同步的隊列名,可以用正規表達式比對;
{“ha-mode”:”all”} 表示同步給所有,同步模式的不同,此參數也不同。
執行上面指令後,可以在web管理界面檢視queue 頁面,裡面hello隊列的node節點後會出現+2标簽,表示有2個從節點,而主節點則是目前顯示的node(xf7021是測試用的名字,按4-2應該為rabbitmq(1-3))。
鏡像模式:消息實體會主動在各節點之間同步,而不是在消費者擷取時才同步。降低系統性能消耗帶寬
設定ha模式
rabbitmqctl set_policy [-p <vhostpath>] [--priority <priority>] [--apply-to <apply-to>] <name> <pattern> <definition>
name 政策名稱
pattern 正規表達式,用來比對資源,符合的就會應用設定的政策
definition 是json格式設定的政策。
apply-to 表示政策應用到什麼類型的地方,一般有queues,exchange和all,預設是all
priority 是個整數優先級
其中ha-mode有三種模式:
all: 同步至所有的.
exactly: 同步最多N個機器. 當現有叢集機器數小于N時,同步所有,大于等于N時則不進行同步. N需要額外通過ha-params來指定.
nodes: 隻同步至符合指定名稱的nodes. N需要額外通過ha-params來指定.# 這裡設定的是同步全部的queue, 可以按需自己選擇指定的queue
rabbitmqctl set_policy ha-all '.*' '{"ha-mode":"all"}'
線上操作
rabbitmq有主從之分,誰先啟動,就是主
不需要再rabbitmqctl start_app
指令詳細介紹
https://my.oschina.net/guol/blog/186445
stop_app
#停止erlang node上的rabbitmq的應用,但是erlang node還是會繼續運作的
要在生産上使用,以下幾點,有幾點有可能用的上
注意的地方:
0.修改叢集cluster_node_type
[root@rabbitmq-test1 rabbitmq]# rabbitmqctl stop_app
Stopping node 'rabbit@rabbitmq-test1' ...
[root@rabbitmq-test1 rabbitmq]# rabbitmqctl change_cluster_node_type ram
Turning 'rabbit@rabbitmq-test1' into a ram node ...
[root@rabbitmq-test1 ~]# rabbitmqctl cluster_status
Cluster status of node 'rabbit@rabbitmq-test1' ...
[{nodes,[{disc,['rabbit@rabbitmq-test2']},{ram,['rabbit@rabbitmq-test1']}]},
{running_nodes,['rabbit@rabbitmq-test2','rabbit@rabbitmq-test1']},
{partitions,[]}]
關于節點類型(ram |disk)
ram節點的狀态儲存在記憶體中,disk節點儲存在磁盤中被加入的節點為disk,如本例中rabbit@host2為ram節點,rabbit@host1,rabbit@host3為ram節點,可以通過rabbitmqctl cluster指令改變加入的叢集以及節點類型該指令後可以加多個節點名稱,指定的節點就會變成disk節點
1.[root@rabbitmq-node1 ~]# cat /etc/rabbitmq/rabbitmq-env.conf
RABBITMQ_MNESIA_BASE=/var/lib/rabbitmq///需要使用的MNESIA資料庫的路徑
RABBITMQ_LOG_BASE=/var/log/rabbitmq///log的路徑
RABBITMQ_PLUGINS_DIR=/usr/lib/rabbitmq/lib/rabbitmq_server-2.8.6/plugins//插件的路徑
2.自動配置叢集
vi /etc/rabbitmq/rabbitmq.config
添加以下内容
[{rabbit,
[{cluster_nodes, {['rabbit@r1', 'rabbit@r2'], disc}}]}].
之後啟動叢集
在r1和r2上執行
然後檢視叢集狀态
3.高可用
安裝并配置 HAProxy
在 192.168.1.4 上安裝 HAProxy,然後修改 /etc/haproxy/haproxy.cfg:
listen rabbitmq_cluster 0.0.0.0:5672
mode tcp
balance roundrobin
server node1 192.168.1.1:5672 check inter 2000 rise 2 fall 3
server node2 192.168.1.2:5672 check inter 2000 rise 2 fall 3
server node2 192.168.1.3:5672 check inter 2000 rise 2 fall 3
4.使用者與權限
在正式應用之前,我們先在RabbitMQ裡建立一個vhost,加一個使用者,并設定該使用者的權限。使用rabbitmqctl用戶端工具,在根目錄下建立”/mq_test”這個vhost:
rabbitmqctl add_vhost /mq_test
建立一個使用者名”test”,設定密碼”test123″:
rabbitmqctl add_user test test123
設定pyh使用者對/pyhtest這個vhost擁有全部權限:
rabbitmqctl set_permissions -p /mq_test test “.*” “.*” “.*”、
後面三個”*”代表pyh使用者擁有對/pyhtest的配置、寫、讀全部權限
conn = amqp.Connection(host='localhost',userid='test',password='123456',ssl=False,virtual_host='test_host')
# rabbitmq-plugins enable rabbitmq_management
# rabbitmq-plugins list
# rabbitmqctl add_user admin admin
# rabbitmqctl set_user_tags admin administrator
RABBITMQ建立帳戶
如果是叢集的話,隻要在一台主機設定即可,其它會自動同步。
#rabbitmqctl add_user iom 123456 –iom為建立的使用者,123456為密碼
#rabbitmqctl set_user_tags iom administrator –将使用者設定為管理者角色
#rabbitmqctl set_permissions -p / iom “.*” “.*” “.*”
–在 / 虛拟主機裡設定iom使用者配置權限,寫權限,讀權限。.*是正規表達式裡用法。rabbitmq的權限是根據不同的虛拟主機(virtual hosts)配置的,同使用者在不同的虛拟主機(virtual hosts)裡可能不一樣。
5.rabbit_hosts=192.168.8.180:5672,192.168.8.53:5672,192.168.8.87:5672
測試rabbitmq的haproxy下的lb
将之前的測試代碼中的
mq_servers = ['10.22.129.57', '10.22.129.58', '10.22.129.59']
改成
mq_servers = ['10.22.129.53', '10.22.129.53', '10.22.129.53']
執行測試代碼,發現三個消息均發送成功,然後即使手動關閉其中一台mq,消息依然發送成功,通過rabbitctl list_queues也依然可以看到消息是成功收到3條的.
至此,可以看到rabbitmq-server成功的解除了single-point狀态。
6.使用service方式啟動rabbitmq-server報錯erlexec: HOME must be set
解決辦法:
在啟動腳本中使用export指定HOME變量
export HOME=/opt/data/rabbitmq/
7.最常用的指令
檢視所有隊列資訊
[root@rabbitmq-test1 ~]# rabbitmqctl list_queues
Listing queues ...
清除所有隊列
rabbitmqctl reset
8.關于端口
rabbimq 55672 15672 為監控插件端口
rabbitmq 5672為資料端口
9.一些特别應該注意的東西
§ cookie在所有節點上必須完全一樣,同步時一定要注意。
§ erlang是通過主機名來連接配接服務,必須保證各個主機名之間可以ping通。可以通過編輯/etc/hosts來手工添加主機名和IP對應關系。如果主機名ping不通,rabbitmq服務啟動會失敗。
§ 如果queue是非持久化queue,則如果建立queue的那個節點失敗,發送方和接收方可以建立同樣的queue繼續運作。但如果是持久化queue,則隻能等建立queue的那個節點恢複後才能繼續服務。
§ 在叢集中繼資料有變動的時候需要有disk node線上,但是在節點加入或退出的時候所有的disk node必須全部線上。如果沒有正确退出disk node,叢集會認為這個節點當掉了,在這個節點恢複之前不要加入其它節點。
本文轉自 liqius 51CTO部落格,原文連結:http://blog.51cto.com/szgb17/1882187,如需轉載請自行聯系原作者