RabbitMQ第一篇--入門

1.簡介:java

RabbitMQ是一個消息中間件,主要做用是用來接收和轉發消息。你能夠將他想象成是郵局:git

當你在郵箱中放入了一封信,那麼郵遞員確定會將信送給它的接收者。而RabbitMQ就像是郵局、web

郵箱、郵遞員。它負責從一處接收消息,按要發送的「地址」將消息轉發到指定「地址」。數組

RabbitMQ和郵局的不一樣之處也就在於它並不處理報刊和雜誌,而是接收、存儲並轉發二進制的消息(Message)緩存

2.RabbitMQ中的經常使用術語:服務器

  • 生產者:一般負責發送消息的程序被咱們稱爲「消息生產者」。能夠 用此圖表示消息生產者:

                    

  • 隊列:就像一個郵箱,它存在於RabbitMQ內部,消息只能存儲在隊列中。隊列自己並沒有任何限制,它能夠存儲任意多的消息。從本質來講隊列就是一個無限大小的緩衝區。多個「消息生產者」能夠將多條消息放入同一個隊列中,同理,多個消費者也能夠嘗試從同一個隊列中獲取消息。能夠用下圖表示隊列:

               

  • 消費者:一般等待消息到來並處理消息的程序稱爲:「消費者」用下圖來表示消費者:

                    

一般狀況下,消息的生產者、消費者、以及消息中間件並不在同一臺機器中。異步

3.使用Java客戶端:maven

在這節的示例中,咱們將寫兩個Java文件;一個負責發送單條消息(消息生產者),ide

一個負責接收並打印消息(消息消費者)。在下圖中P表明生產者,C表明消費者,測試

中間的紅色格子表明隊列(消息緩存的地方)

       

4.引入Java依賴包:

本例採用Maven的形式引入,依賴以下:

在pom文件中添加如下代碼

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

消息生產者的Java代碼(Send.java):

maven引入依賴後請自行導包,代碼中有註釋,再也不對代碼作解釋。

public class Send {
    private static final String QUEUE_NAME = "hello";

    /**
     * 如下代碼均爲本機測試,RabbitMQ安裝後默認啓用guest帳戶,用戶名guest,密碼guest
     * 可是該帳戶默認僅能在localhost中使用.請注意.
     * 測試代碼請根據本身的環境修改userName和password
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception{
        //建立鏈接工廠,設置鏈接地址,用戶名,密碼
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        factory.setUsername("admin");
        factory.setPassword("admin");
        //建立鏈接
        Connection connection = factory.newConnection();
        //經過鏈接建立信道,信道的建立和銷燬代價比鏈接要小的多
        Channel channel = connection.createChannel();
        //發送的消息體
        String message = "hello rabbitmq";
        //發送消息,消息體格式爲字節數組
        channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
        //關閉鏈接和通道
        channel.close();
        connection.close();
    }
}

消費者Java代碼(Recv.java)

public class Recv {

    //隊列名稱
    private static final String QUEUE_NAME = "hello";

    public static void main(String[] argv) throws Exception {
        //建立連接工廠,設置用戶名密碼
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        factory.setUsername("admin");
        factory.setPassword("admin");
        Connection connection = factory.newConnection();
        //建立通道
        Channel channel = connection.createChannel();
        //聲明隊列,發送者和生產者都作了隊列聲明的操做
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
        //建立消費者,重寫消息的處理方法
        Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
                    throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println(" [x] Received '" + message + "'");
            }
        };
        //消費消息.
        channel.basicConsume(QUEUE_NAME, true, consumer);
    }
}

上述兩個Java文件中,發送者和消費者都作了隊列的聲明操做。在RabbitMQ中該操做是冪等的(只有在該隊列不存在時纔會建立,不會重複建立)

之因此在生產者和消費中都建立隊列,是由於並不肯定會先啓動哪一個服務.徹底有可能先啓動消費者再啓動生產者.咱們要確保消費者從該隊列消費

消息時該隊列已經存在.在下一章你就會看到這樣的例子.

而RabbitMQ隊列的建立是冪等的.因此生產者和消費者同時作隊列的聲明並不會引發什麼問題.

消息生產者的示意圖:

消息經過生產者Send.java將消息發送到名爲hello的隊列

            

消費者的示意圖:
消費者Revc.java從名爲hello的隊列中取出消息執行本身的邏輯

        

RabbitMQ服務器會異步的將消息推送出來,因此在消費者中提供一個回調.並重寫handleDelivery方法處理消息.
在此處僅僅是將消息打印出來.
程序到此處已經寫完了,如今你能夠運行項目了.步驟:
1.先運行Send.java,程序將發送一條消息到hello隊列.此時你能夠先不啓動消費者,去MQ的web管理控制檯中看看

在管理控制檯的Queues下能夠看到名爲hello的隊列中有一條準備好的消息.
此時啓動消費者.會看到控制檯hello隊列中的ready消息爲0,已經被消費者消費掉了.隊列也隨之被清空
Java控制檯會打印出來消息內容.

示例代碼地址:https://git.oschina.net/li_mingzhu/rabbitmq.git

相關文章
相關標籤/搜索