RabbitMQ的安裝與入門

RabbitMQ的安裝

這裏暫時使用window環境,稍後補充linux下的安裝。首先,因爲RabbitMQ由ERLANG實現,所以首先需要安裝ERLANG環境,安裝好之後纔是RabbitMQ的安裝和配置。

ERLANG環境

1.先去官網下載最新的OPT。直接打開exe文件執行安裝,記錄下安裝的目錄文件路徑。

2.將ERLANG加入系統環境:
這裏寫圖片描述
這裏寫圖片描述

3.此時打開erlang表示成功。
這裏寫圖片描述

RabbitMQ安裝

1.下載RabbitMQ,直接運行exe文件即可。
2.檢驗安裝是否成功:
進入命令行,輸入你的安裝目錄和rabbitmqctl status命令,看到一大串東西就說明安裝成功。
這裏寫圖片描述
3.安裝 RabbitMQWeb的管理插件。繼續命令行輸入:rabbitmq-plugins enable rabbitmq_management,此時就可以訪問http://localhost:15672啦。
這裏寫圖片描述

默認的管理員賬戶和密碼都是guest,我們可以通過命令來創建新的管理員。

1.新增加用戶:命令行(rabbitmqctl.bat add_user 用戶名 密碼)。
這裏寫圖片描述
2.將用戶升級爲管理員(這樣纔可以登陸後臺管理界面)。輸入rabbitmqctl.bat set_user_tags 用戶名 administrator
這裏寫圖片描述
3.使用test1 test1登陸成功,這樣RabbitMQ就安裝好了。
這裏寫圖片描述

RabbitMQ入門

RabbitMQ消息隊列一共有6種,從簡單到複雜分別爲簡單模式、 Work模式、訂閱模式、路由模式、通配符模式和RPC模式。
下面我將使用java簡單做幾個測試demo。
maven中加入的dependency:

<dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>3.6.5</version>
 </dependency>

簡單模式

這裏寫圖片描述

一個生產者將消息發送到隊列中,一個消費者從隊列中獲得消息。
我們創建兩個獨立的項目,分別表示消費者和生產者。
這裏寫圖片描述
生產者端代碼:

public class Producer {

    private final static String QUEUE_NAME = "RabbitMQ.demo";

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        // 創建連工廠
        ConnectionFactory factory = new ConnectionFactory();
        // 設置相關信息
        factory.setHost("localhost");
        // 創建一個鏈接
        Connection connection = factory.newConnection();
        // 創建一個通道
        Channel channel = connection.createChannel();
        // 在通道里聲明一個隊列
        channel.queueDeclare("", false, false, false, null);
        // 發佈消息到隊列中
        String message = "This is 消息隊列 demo";
        for (int i = 0; i < 20; i++) {
            channel.basicPublish("", QUEUE_NAME, null, (message+i).getBytes("UTF-8"));
            TimeUnit.MILLISECONDS.sleep(300);
            System.out.println("生產者發送了消息:" +"["+i+"]" +message);
        }
        // 關閉資源
        channel.close();
        connection.close();
    }
}

解釋一下queueDeclare中的參數。
Parameters:
queue :隊列的名字,這沒啥好說的。
durable :是否需要持久化,指的是隊列持久化到數據庫中,持久化設置爲true的話,即使RabbitMQ服務崩潰也不會丟失隊列裏面的數據。
exclusive :是否排外,設置爲true的隊列只可以在本次的連接中被訪問,新的隊列就會被排外不能訪問。
autoDelete :是否自動刪除,也就是關閉connection的時候隊列裏面的數據是否自動刪除。
arguments :隊列的屬性,如構造參數。(應該沒翻譯錯吧other properties (construction arguments) for the queue)。

從RabbitMQ控制檯可以知道,消息發送成功。
這裏寫圖片描述

消費端代碼

public class Customer {


    private final static String QUEUE_NAME = "RabbitMQ.demo";

    public static void main(String[] args) throws IOException, TimeoutException, ShutdownSignalException, ConsumerCancelledException, InterruptedException {
        // 創建連工廠
        ConnectionFactory factory = new ConnectionFactory();
        // 設置相關信息
        factory.setHost("localhost");
        // 創建一個鏈接
        Connection connection = factory.newConnection();
        // 創建一個通道
        Channel channel = connection.createChannel();
        // 在通道里聲明一個隊列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null)
        System.out.println("消費者1消息隊列開始關注消息");
        //定義隊列的消費者
        QueueingConsumer consumer = new QueueingConsumer(channel);
        //監聽隊列
        //false表示接受消息需返回給消息隊列確認
        channel.basicConsume(QUEUE_NAME, true,consumer);
        //獲取消息
        while(true){
            TimeUnit.SECONDS.sleep(1);
            QueueingConsumer.Delivery nextDelivery = consumer.nextDelivery();
            //getBody()方法獲得隊列中的消息
            String message = new String(nextDelivery.getBody());
            System.out.println("消費者1隊列獲得了消息:"+message);
        }
    }
}

控制檯輸出:
這裏寫圖片描述

Work模式

這裏寫圖片描述

一個生產者,一個隊列,多個消費者。

生產者代碼和簡單模式一樣,消費端只需要複製多個消費者即可。

注意的是,默認情況下,多個消費者依次獲得消息,不能越界,就算你已經早早的消費了消息,但是你還是需要等待,按照順序從列隊拿消息。這顯然是不合理,應該是能者多勞。這時我們只需要在生產者加入一行:

channel.basicQos(1);//表示一個時間服務器只會發送一條消息給消費者

訂閱模式

這裏寫圖片描述

生產者將數據發送給交換機或多個隊列,消費者從隊列中獲得。

生產者代碼:

public class Producer {


    //生產者和交換機綁定了
    private final static String EXCHANGE_NAME = "test_exchange_fanout";

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        // 創建連工廠
        ConnectionFactory factory = new ConnectionFactory();
        // 設置相關信息
        factory.setHost("localhost");
        // 創建一個鏈接
        Connection connection = factory.newConnection();
        // 創建一個通道
        Channel channel = connection.createChannel();
        //使用交換機,就聲明一個交還機,type=fanout
        channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
        /*//一個時刻只會發送一條消息給消費者
        channel.basicQos(1);*/
        // 發佈消息到隊列中
        String message = "This is 消息隊列 demo";
        for (int i = 0; i < 20; i++) {
            //設置路由b
            channel.basicPublish(EXCHANGE_NAME, "", null, (message+i).getBytes("UTF-8"));
            TimeUnit.MILLISECONDS.sleep(300);
            System.out.println("生產者發送了消息:" +"["+i+"]" +message);
        }
        // 關閉資源
        channel.close();
        connection.close();
    }
}

消費者1:

public class Customer {



    private final static String QUEUE_NAME = "RabbitMQ1.demo";
    private final static String EXCHANGE_NAME = "test_exchange_fanout";

    public static void main(String[] args) throws IOException, TimeoutException, ShutdownSignalException, ConsumerCancelledException, InterruptedException {
        // 創建連工廠
        ConnectionFactory factory = new ConnectionFactory();
        // 設置相關信息
        factory.setHost("localhost");
        // 創建一個鏈接
        Connection connection = factory.newConnection();
        // 創建一個通道
        Channel channel = connection.createChannel();
        // 在通道里聲明一個隊列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //綁定到交換機
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
        System.out.println("消費者1消息隊列開始關注消息");
        //定義隊列的消費者
        QueueingConsumer consumer = new QueueingConsumer(channel);
        //監聽隊列
        //false表示接受消息需返回給消息隊列確認
        channel.basicConsume(QUEUE_NAME, true,consumer);
        //獲取消息
        while(true){
            TimeUnit.SECONDS.sleep(1);
            QueueingConsumer.Delivery nextDelivery = consumer.nextDelivery();
            String message = new String(nextDelivery.getBody());
            System.out.println("消費者1隊列獲得了消息:"+message);
        }
    }
}

消費者2和消費者代碼一樣,只需要修改QUEUE_NAME即可。
控制檯輸出:
這裏寫圖片描述
這裏寫圖片描述

這表明,兩個消費者都獲得了相同的消息。

路由模式

這裏寫圖片描述

生產者將特定的消息傳給交換機,然會由交換機發送給特定的隊列,消費者只需要指定特定的路由key即可。

生產者:我們只需要修改交換機的名稱爲direct,指定路由的key即可,這裏設置key=b
這裏寫圖片描述

消費者1:表示接受key=a的消息,其他的接收不到。
這裏寫圖片描述
輸出:
這裏寫圖片描述

消費者2:表示接受key=b的消息,其他的接收不到。
這裏寫圖片描述
輸出:
這裏寫圖片描述

統配符模式

這裏寫圖片描述

統配符模式其實也可以歸類於路由模式,只不過統配符模式中路由的key可以使用通配符表示。代碼可以參考路由模式。只不過需要修改一下交換機類型爲topic:

channel.exchangeDeclare(EXCHANGE_NAME, "topic");
.....
.....
//設置通配符爲a.*
channel.basicPublish(EXCHANGE_NAME, "a.*", null, (message+i).getBytes("UTF-8"));
.....
.....

這樣任何配以a.開頭的消費者都能獲得此生產者的消息。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章