rabbitmq單機多實例集羣搭建

1.安裝單機版的java


2.要搭建集羣,先將以前單機版中歷史記錄幹掉,刪除rabbitmq /var/lib/rabbitmq/mnesia下的全部內容。node


3.啓動3個實例
#由於我配置了web管理插件,因此還要指定其web插件佔用的端口號,若是不指定,將不能啓動多個節點,由於端口號被佔用web

RABBITMQ_NODE_PORT=5672 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15672}]" RABBITMQ_NODENAME=rabbit rabbitmq-server -detached
RABBITMQ_NODE_PORT=5673 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15673}]" RABBITMQ_NODENAME=rabbit2 rabbitmq-server -detached
RABBITMQ_NODE_PORT=5674 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15674}]" RABBITMQ_NODENAME=rabbit3 rabbitmq-server -detached


4.在瀏覽器訪問每個rabbitmq實例,是夠能夠顯示登陸頁面,若是顯示成功,繼續往下進行瀏覽器


5.咱們以rabbit爲主節點,剩下兩個爲從節點(在從節點執行如下命令,主節點不用動,-n指定具體那個節點)
          [root@localhost mnesia]# rabbitmqctl -n rabbit2 stop_app
          Stopping rabbit application on node rabbit2@localhost ...
          [root@localhost mnesia]# rabbitmqctl -n rabbit2 reset
          Resetting node rabbit2@localhost ...
          [root@localhost mnesia]# rabbitmqctl -n rabbit2 join_cluster rabbit@`hostname -s`
          Clustering node rabbit2@localhost with rabbit@localhost ...
          [root@localhost mnesia]# rabbitmqctl -n rabbit2 start_app
          Starting node rabbit2@localhost ...
          [root@localhost mnesia]# rabbitmqctl -n rabbit3 stop_app
          Stopping rabbit application on node rabbit3@localhost ...
          [root@localhost mnesia]# rabbitmqctl -n rabbit3 reset
          Resetting node rabbit3@localhost ...
          [root@localhost mnesia]# rabbitmqctl -n rabbit3 join_cluster rabbit@`hostname -s`
          Clustering node rabbit3@localhost with rabbit@localhost ...
          [root@localhost mnesia]# rabbitmqctl -n rabbit3 start_app
          Starting node rabbit3@localhost ...
這是查看每個rabbitmq的節點,能夠看到如下場景,證實多實例啓動成功app

6.若是想加入一個新的節點到集羣,只須要執行第五步相同的命令便可!測試

刪除節點:rabbitmqctl forget_cluster_node rabbit3@hostname.net

7.使用rabbitmqctl -n rabbit cluster_status查看集羣信息
          [root@localhost mnesia]# rabbitmqctl -n rabbit cluster_status
          Cluster status of node rabbit@localhost ...
          [{nodes,[{disc,[rabbit2@localhost,rabbit3@localhost,rabbit@localhost]}]},
           {running_nodes,[rabbit3@localhost,rabbit2@localhost,rabbit@localhost]},
           {cluster_name,<<"rabbit@localhost">>},
           {partitions,[]},
           {alarms,[{rabbit3@localhost,[]},
                    {rabbit2@localhost,[]},
                    {rabbit@localhost,[]}]}]
搭建過程當中,可能會出現以下錯誤,我感受只要是出現帶mnesia關鍵字的,把rabbitmq/var/lib/rabbitmq/mnesia下全部內容刪掉(rm -rf *)。
Clustering node hare@localhost with rabbit@localhost ...
Error: mnesia_not_running插件


8.測試,生產者使用5672生產消息,消費者使用5673獲取消息,若是能獲取到表示集羣搭建成功
Producer類:code

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類:server

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.103");
        factory.setPort(5673);
        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 + "'");
        }
    }
}
相關文章
相關標籤/搜索