RabbitMQ系列(三)RabbitMQ進階-Queue隊列特性 (一)簡單隊列

RabbitMQ Spring 項目整合

1.新建mave項目

1.1 新建 maven項目,後期咱們再整合spring boot amqp新建spring boot項目,路要一步一步走,先從簡單的maven項目,瞭解原理,再從spring boot項目 看spring boot封裝了什麼東西,到底簡化了我們的哪些操作
在這裏插入圖片描述
1.2 設置 groupId和artifactId 及maven配置
在這裏插入圖片描述
1.3 選擇項目文件夾
在這裏插入圖片描述
1.4 項目新建完成,目錄結構如下
在這裏插入圖片描述
1.5 pom中添加 RabbitMQ 客戶端依賴

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

RabbitMQ 五種 Queue隊列

1.簡單隊列

簡單隊列就是 1對1, 1個生產者對應1個消費者
在這裏插入圖片描述

簡單隊列上代碼

1.1 connect 工具類
package com.jzj.mq.conn;

import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**
 * 當前描述:
 *
 * @author: jiazijie
 * @since: 2020/6/10 下午11:12
 */
public class MqConnectUtil {
    public static Connection getConnectionDefault() throws Exception {
        //定義連接工廠
        ConnectionFactory factory = new ConnectionFactory();
        //設置服務地址
        factory.setHost("127.0.0.1");
        //端口
        factory.setPort(5672);
        //設置賬號信息,用戶名、密碼、vhost
        factory.setVirtualHost("/");
        factory.setUsername("admin");
        factory.setPassword("admin");
        // 通過工程獲取連接
        Connection connection = factory.newConnection();
        return connection;
    }


    public static Connection getConnectionJzj() throws Exception {
        //定義連接工廠
        ConnectionFactory factory = new ConnectionFactory();
        //設置服務地址
        factory.setHost("127.0.0.1");
        //端口
        factory.setPort(5672);
        //設置賬號信息,用戶名、密碼、vhost
        factory.setVirtualHost("jzj");
        factory.setUsername("admin");
        factory.setPassword("admin");
        // 通過工程獲取連接
        Connection connection = factory.newConnection();
        return connection;
    }
}

1.2 Producer 生產者-消息產生->發送到交換機->轉發到隊列存着
package com.jzj.mq.produce;

import com.jzj.mq.conn.MqConnectUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

/**
 * 當前描述:生產者
 *
 * @author: jiazijie
 * @since: 2020/6/10 下午11:14
 */
public class Producer {
    private final static String QUEUE_NAME = "queue_test";

    public static void main(String[] argv) throws Exception {
        // 獲取到連接以及mq通道
        Connection connection = MqConnectUtil.getConnectionDefault();
        // 從連接中創建通道
        Channel channel = connection.createChannel();

        /* 聲明(創建)隊列  queueDeclare( String queue, boolean durable, boolean exclusive, boolean autoDelete,  Map<String, Object> arguments)
         * queue - 隊列名
         * durable - 是否是持久化隊列, 隊列的聲明默認是存放到內存中的,如果rabbitmq重啓會丟失
         * exclusie - 是否排外的,僅限於當前隊列使用
         * autoDelete - 是否自動刪除隊列,當最後一個消費者斷開連接之後隊列是否自動被刪除,可以通過界面 查看某個隊列的消費者數量,當consumers = 0時隊列就會自動刪除
         * arguments - 隊列攜帶的參數 比如 ttl-生命週期,x-dead-letter 死信隊列等等
         */
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        // 消息內容
        String message = "Hello World!";

        /* 發送消息 String exchange, String routingKey, BasicProperties props, byte[] body
         * exchange - 交換機 ,"" 空時候指定的是 獲取的virtualHost 虛擬服務器的 默認的exchang,每個virtualHost都有一個AMQP default type:direct 直接轉發
         * queuename - 隊列信息
         * props - 參數信息
         * message 消息體 byte[]類型
         */
        channel.basicPublish("", QUEUE_NAME, null, message.getBytes());

        System.out.println(" **** Producer  Sent Message: '" + message + "'");
        //關閉通道和連接
        channel.close();
        connection.close();
    }
}
1.3 消費者->監聽隊列,有消息就從隊列中取出來消息進行消費
package com.jzj.mq.consumer;

import com.jzj.mq.conn.MqConnectUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;

/**
 * 當前描述:消費者
 *
 * @author: jiazijie
 * @since: 2020/6/10 下午11:30
 */
public class Consumer {
    private final static String QUEUE_NAME = "queue_test";

    public static void main(String[] argv) throws Exception {
        Connection connection = MqConnectUtil.getConnectionDefault();
        Channel channel = connection.createChannel();

        /*確保這裏的隊列是存在的*/
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        System.out.println(" **** Consumer Waiting for messages. To exit press CTRL+C");


        QueueingConsumer consumer = new QueueingConsumer(channel);

        /* 消息確認機制
         * autoAck true:表示自動確認,只要消息從隊列中獲取,無論消費者獲取到消息後是否成功消費,都會認爲消息已經成功消費
         * autoAck false:表示手動確認,消費者獲取消息後,服務器會將該消息標記爲不可用狀態,等待消費者的反饋,如果消費者一直沒有反饋,那麼該消息將一直處於不可用狀態
         *          並且服務器會認爲該消費者已經掛掉,不會再給其發送消息,直到該消費者反饋
         */
        channel.basicConsume(QUEUE_NAME, true, consumer);

        while (true) {
            QueueingConsumer.Delivery delivery = consumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" **** Consumer Received '" + message + "'");
        }
    }

}

1.4 執行結果:

在這裏插入圖片描述
可以看到,Producer生產者生產一條消息,Consumer 就能夠消費一條消息

!!!!!!注意 我們在Producer中並沒有指定 exchange,傳入的exchange也是字符串,它使用的是每一個VirtualHost 下面默認的AMQP default exchange

如下圖:
在這裏插入圖片描述

下一篇 我們介紹 工作隊列 work模式

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