天天看點

rabbitmq3.5.1 原理和叢集安裝

參考

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 &amp;&amp; make &amp;&amp; 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 &amp;&amp; mv rabbitmq_server-3.5.1 /usr/local

cd /usr/local &amp;&amp; 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,[&lt;&lt;""&gt;&gt;]},

(雖然可以以比較猥瑣的方式:将ebin目錄下rabbit.app中loopback_users裡的&lt;&lt;"guest"&gt;&gt;删除,或者在配置檔案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 &lt;vhostpath&gt;] [--priority &lt;priority&gt;] [--apply-to &lt;apply-to&gt;] &lt;name&gt; &lt;pattern&gt; &lt;definition&gt;  

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,如需轉載請自行聯系原作者

繼續閱讀