多機集羣搭建
1.安裝單機版的
注意:不一樣於單機多節點的狀況,在多機環境,若是要在cluster集羣內部署多個節點,須要注意兩個方面:
1)保證須要部署的這幾個節點在同一個局域網內
2)須要有相同的Erlang Cookie,不然不能進行通訊,爲保證cookie的徹底一致,採用從一個節點copy的方式,下面就會使用這種方式java
2.要搭建集羣,先將以前單機版中歷史記錄幹掉,刪除rabbitmq/var/lib/rabbitmq/mnesia下的全部內容。node
3.分別在192.168.1.103 192.168.1.104 192.168.1.105節點上安裝rabbitmq server。瀏覽器
4.在瀏覽器訪問每個rabbitmq實例,是夠能夠顯示登陸頁面,若是顯示成功,繼續往下進行。服務器
5.設置不一樣節點間同一認證的Erlang Cookie
將192.168.1.103上的rabbitmq/var/lib/rabbitmq/.erlang.cookie中的內容複製到192.168.1.104和192.168.1.105上的rabbitmq/var/lib/rabbitmq/.erlang.cookie文件中, 即三臺服務器必須具備相同的cookie,若是不相同的話,沒法搭建集羣
注意:
官方在介紹集羣的文檔中提到過.erlang.cookie通常會存在這兩個地址:第一個是$home/.erlang.cookie也就是/root 目錄下,第二個地方就是/var/lib/rabbitmq/.erlang.cookie。
若是咱們使用解壓縮方式安裝部署的rabbitmq,那麼這個文件會在${home}目錄下,也就是$home/.erlang.cookie。
若是咱們使用rpm等安裝包方式進行安裝的,那麼這個文件會在/var/lib/rabbitmq目錄下。cookie
6.分別在三個節點的/etc/hosts下設置相同的配置信息,而後重啓機器
192.168.1.103 rabbit1
192.168.1.104 rabbit2
192.168.1.105 rabbit3
重啓以後[root@localhost ~]# 改成[root@rabbit1 ~]# hostname就會生效app
7.使用 -detached運行各節點
rabbitmq-server -detached測試
8.建立集羣
1)rabbit1爲主節點,另外兩個爲從節點搭建,主節點不用動,只在兩個從節點運行以下命令,我這裏只舉一個節點(rabbit2)的例子,rabbit3執行相同的命令
[root@rabbit2 rabbitmq]# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rabbit2 ...
[root@rabbit2 rabbitmq]# rabbitmqctl reset
Resetting node rabbit@rabbit2 ...
[root@rabbit2 rabbitmq]# rabbitmqctl join_cluster rabbit@rabbit1
Clustering node rabbit@rabbit2 with rabbit@rabbit1 ...
[root@rabbit2 rabbitmq]# rabbitmqctl start_app
Starting node rabbit@rabbit2 ....net
2)使用rabbitmqctl cluster_status查看集羣狀態
[root@rabbit2 rabbitmq]# rabbitmqctl cluster_status
Cluster status of node rabbit@rabbit2 ...
[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2]}]},
{running_nodes,[rabbit@rabbit1,rabbit@rabbit2]},
{cluster_name,<<"rabbit@rabbit2">>},
{partitions,[]},
{alarms,[{rabbit@rabbit1,[]},{rabbit@rabbit2,[]}]}]code
9.我這裏建立完成以後,以前的admin用戶沒法使用了,從新添加用戶,參考以前搭建單機版的命令server
10.使用剛纔的帳號密碼登陸,出現如下界面,表示成功。
11.測試,生產者使用192.168.1.103:5672生產消息,消費者使用192.168.1.104:5672獲取消息,若是能獲取到表示集羣搭建成功
Producer類:
package com.rabbitmq.test.T_helloworld; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.test.util.ConnectionUtil; /** * helloworld * @author lenovo * */ public class Producer { private final static String QUEUE_NAME = "test_queue"; public static void main(String[] argv) throws Exception { //定義一個連接工廠 ConnectionFactory factory=new ConnectionFactory(); //設置服務地址,IP,端口,帳號密碼信息 factory.setHost("192.168.1.103"); factory.setPort(5672); factory.setUsername("admin"); factory.setPassword("admin"); //vhost:虛擬主機,一個broker裏能夠開設多個vhost,用做不一樣用戶的權限分離。 //factory.setVirtualHost("/testrabbit"); // 獲取到鏈接以及mq通道 Connection connection = factory.newConnection(); //Connection connection = ConnectionUtil.getConnection(); // 從鏈接中建立通道 Channel channel = connection.createChannel(); /* * 聲明(建立)隊列 * 參數1:隊列名稱 * 參數2:爲true時server重啓隊列不會消失 * 參數3:隊列是不是獨佔的,若是爲true只能被一個connection使用,其餘鏈接創建時會拋出異常 * 參數4:隊列再也不使用時是否自動刪除(沒有鏈接,而且沒有未處理的消息) * 參數5:創建隊列時的其餘參數 */ channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 消息內容 String message = "Hello World!"; /* * 向server發佈一條消息 * 參數1:exchange名字,若爲空則使用默認的exchange * 參數2:routing key * 參數3:其餘的屬性 * 參數4:消息體 * RabbitMQ默認有一個exchange,叫default exchange,它用一個空字符串表示,它是direct exchange類型, * 任何發往這個exchange的消息都會被路由到routing key的名字對應的隊列上,若是沒有對應的隊列,則消息會被丟棄 */ channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); System.out.println(" [生產者] Sent '" + message + "'"); //關閉通道和鏈接 channel.close(); connection.close(); } }
Consumer類:
package com.rabbitmq.test.T_helloworld; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.QueueingConsumer; import com.rabbitmq.test.util.ConnectionUtil; public class Consumer { private final static String QUEUE_NAME = "test_queue"; public static void main(String[] argv) throws Exception { //定義一個連接工廠 ConnectionFactory factory=new ConnectionFactory(); //設置服務地址,IP,端口,帳號密碼信息 factory.setHost("192.168.1.104"); factory.setPort(5672); factory.setUsername("admin"); factory.setPassword("admin"); //vhost:虛擬主機,一個broker裏能夠開設多個vhost,用做不一樣用戶的權限分離。 //factory.setVirtualHost("/testrabbit"); // 獲取到鏈接以及mq通道 Connection connection = factory.newConnection(); // 從鏈接中建立通道 Channel channel = connection.createChannel(); // 聲明隊列(若是你已經明確的知道有這個隊列,那麼下面這句代碼能夠註釋掉,若是不註釋掉的話,也能夠理解爲消費者必須監聽一個隊列,若是沒有就建立一個) channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 定義隊列的消費者 QueueingConsumer consumer = new QueueingConsumer(channel); /* * 監聽隊列 * 參數1:隊列名稱 * 參數2:是否發送ack包,不發送ack消息會持續在服務端保存,直到收到ack。 能夠經過channel.basicAck手動回覆ack * 參數3:消費者 */ channel.basicConsume(QUEUE_NAME, true, consumer); // 獲取消息 while (true) { QueueingConsumer.Delivery delivery = consumer.nextDelivery(); String message = new String(delivery.getBody()); System.out.println(" [消費者] Received '" + message + "'"); } } }