work工作模式(資源的競爭)

å¨è¿éæå¥å¾çæè¿°

功能:一個生產者,多個消費者,每個消費者獲取到的消息唯一,多個消費者只有一個隊列

  1. 消息產生者將消息放入隊列消費者可以有多個,消費者1 ,消費者2 , 同時監聽同一個隊列,消息被消費?    C1 C2共同爭搶當前的消息隊列內容,誰先拿到誰負責消費消息(隱患,高併發情況下,默認會產生某一個消息被多個消費者共同使用,可以設置一個開關(syncronize,與同步鎖的性能不一樣) 保證一條消息只能被一個消費者使用)
  2. 應用場景:紅包;大項目中的資源調度(任務分配系統不需知道哪一個任務執行系統在空閒,直接將任務扔到消息隊列中,空閒的系統自動爭搶)

生產者實現思路:

創建連接工廠ConnectionFactory,設置服務地址127.0.0.1,端口號5672,設置用戶名、密碼、virtual host,從連接工廠中獲取連接connection,使用連接創建通道channel,使用通道channel創建隊列queue,使用通道channel向隊列中發送消息,2條消息之間間隔一定時間,關閉通道和連接。

public class Send {

    private final static String QUEUE_NAME = "test_queue_work";

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

        // 聲明隊列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        for (int i = 0; i < 100; i++) {
            // 消息內容
            String message = "" + i;
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
            System.out.println(" [x] Sent '" + message + "'");

            Thread.sleep(i * 10);
        }

        channel.close();
        connection.close();
    }
}

消費者實現思路:

創建連接工廠ConnectionFactory,設置服務地址127.0.0.1,端口號5672,設置用戶名、密碼、virtual host,從連接工廠中獲取連接connection,使用連接創建通道channel,使用通道channel創建隊列queue,創建消費者C1並監聽隊列,獲取消息並暫停10ms,另外一個消費者C2暫停1000ms,由於消費者C1消費速度快,所以C1可以執行更多的任務。

注意:如果 同一時刻服務器只會發一條消息給消費者,就能保證快的消費者拿的多,慢的消費者拿的少。保證資源的合理利用

Recv1:

public class Recv {

    private final static String QUEUE_NAME = "test_queue_work";

    public static void main(String[] argv) throws Exception {

        // 獲取到連接以及mq通道
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();

        // 聲明隊列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        // 同一時刻服務器只會發一條消息給消費者,
        // 保證快的消費者拿的多,慢的消費者拿的少
        channel.basicQos(1);

        // 定義隊列的消費者
        QueueingConsumer consumer = new QueueingConsumer(channel);
        // 監聽隊列,手動返回完成
        channel.basicConsume(QUEUE_NAME, false, consumer);

        // 獲取消息
        while (true) {
            QueueingConsumer.Delivery delivery = consumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" [x] Received '" + message + "'");
            //休眠
            Thread.sleep(10);
            // 返回確認狀態
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
        }
    }
}

Recv2:

public class Recv2 {

    private final static String QUEUE_NAME = "test_queue_work";

    public static void main(String[] argv) throws Exception {

        // 獲取到連接以及mq通道
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();

        // 聲明隊列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        // 同一時刻服務器只會發一條消息給消費者,
        // 保證快的消費者拿的多,慢的消費者拿的少
        channel.basicQos(1);

        // 定義隊列的消費者
        QueueingConsumer consumer = new QueueingConsumer(channel);
        // 監聽隊列,手動返回完成狀態
        channel.basicConsume(QUEUE_NAME, false, consumer);

        // 獲取消息
        while (true) {
            QueueingConsumer.Delivery delivery = consumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" [x] Received '" + message + "'");
            // 休眠1秒
            Thread.sleep(1000);

            channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
        }
    }
}

 

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