RabbitMQ的路由(即Routing)模式示例代碼

1、RabbitMQ官網路由(即Routing)模式的架構圖

在這裏插入圖片描述

2、pom文件需要引入有關MQ的2個依賴包

 <dependency>
   <groupId>org.springframework.amqp</groupId>
     <artifactId>spring-rabbit</artifactId>
     <version>1.4.0.RELEASE</version>
 </dependency>
 <dependency>
     <groupId>com.rabbitmq</groupId>
     <artifactId>amqp-client</artifactId>
     <version>3.4.1</version>
 </dependency>

3、MQ獲取連接工具類代碼如下:

package com.rf.rabiitmq.util;

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

/**
 * @description: mq連接工具類
 * @author: xiaozhi
 * @create: 2020-04-21 09:03
 */
public class ConnectionUtil {
    /** 
    * @Description: 獲取mq連接方法
    * @Param: [] 
    * @Author: xz  
    * @return: com.rabbitmq.client.Connection
    * @Date: 2020/4/21 9:19
    */ 
    public static Connection getConnection() throws Exception {
        //定義連接工廠
        ConnectionFactory connectionFactory=new ConnectionFactory();
        //以下信息,在安裝mq後,登錄mq客戶端進行配置的信息
        connectionFactory.setHost("localhost");//設置服務地址
        connectionFactory.setPort(5672);//設置端口
        connectionFactory.setVirtualHost("xzVirtualHosts");//設置虛擬主機名稱
        connectionFactory.setUsername("xz");//設置用戶名
        connectionFactory.setPassword("xz");//設置密碼
        //通過連接工廠獲取連接
        Connection connection = connectionFactory.newConnection();
        return connection;
    }
}

4、消息發送者,即服務端代碼如下:

package com.rf.rabiitmq.routing;
import com.rabbitmq.client.Connection;
import com.rf.rabiitmq.util.ConnectionUtil;
import com.rabbitmq.client.Channel;

/**
 * @description: 路由模式   發佈消息
 * @author: xiaozhi
 * @create: 2020-04-21 15:40
 */
public class RoutSend {
    private final static String EXCHANGE_NAME = "routing_exchange_name";
    public static void main(String[] argv) throws Exception {
        // 獲取到連接以及mq通道
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        /**
         * 聲明exchange
         * @param1 交換交換的名字
         * @param2 輸入交換類型
         * */
        channel.exchangeDeclare(EXCHANGE_NAME, "direct");
        // 消息內容
        String message = "刪除用戶id=10的用戶信息。";
        /**
         * @param1 交換機名稱
         * @param2 指定路由key
         * @param3 其他屬性
         * @param4 body消息體
         * */
        channel.basicPublish(EXCHANGE_NAME, "delete", null, message.getBytes());
        System.out.println(" 後臺系統發佈消息:'" + message + "'");
        channel.close();
        connection.close();
    }
}

5、消息接收者,即客戶端1代碼如下:

package com.rf.rabiitmq.routing;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.rf.rabiitmq.util.ConnectionUtil;
import com.rabbitmq.client.Channel;
/**
 * @description: 客戶端1
 * @author: xiaozhi
 * @create: 2020-04-21 17:11
 */
public class RoutRescv1 {
    private final static String QUEUE_NAME = "routing_queue_name1";
    private final static String EXCHANGE_NAME = "routing_exchange_name";
    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);
        // 綁定隊列到交換機,並指定路由key
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "select");
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "insert");
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "update");
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "delete");
        // 同一時刻服務器只會發一條消息給消費者
        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("客戶端1接收消息: '" + message + "'");
            Thread.sleep(10);

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

6、消息接收者,即客戶端2代碼如下:

package com.rf.rabiitmq.routing;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.rf.rabiitmq.util.ConnectionUtil;

/**
 * @description: 客戶端2
 * @author: xiaozhi
 * @create: 2020-04-21 17:12
 */
public class RoutRescv2 {
    private final static String QUEUE_NAME = "routing_queue_name2";
    private final static String EXCHANGE_NAME = "routing_exchange_name";
    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);
        // 綁定隊列到交換機,並指定路由key
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "select");
        channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "update");
        // 同一時刻服務器只會發一條消息給消費者
        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("客戶端2接收消息: '" + message + "'");
            Thread.sleep(10);

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

7、先啓動服務端、客戶端1和客戶端2代碼程序,之後關閉服務端、客戶端1和客戶端2代碼程序

  • 原因:爲了先創建隊列和交換機
    在這裏插入圖片描述在這裏插入圖片描述

8、啓動客戶端代碼程序:

1)、啓動消息接收者,即客戶端1代碼程序。輸出如下圖:
在這裏插入圖片描述
2)、啓動消息接收者,即客戶端2代碼程序。輸出如下圖:
在這裏插入圖片描述

9、啓動服務端代碼程序

1)、啓動消息發送者,即服務端的代碼程序。控制檯輸出如下圖:
在這裏插入圖片描述2)查看客戶端1即(消費者1)客戶端2(即消費者2)的控制檯輸出如下:
在這裏插入圖片描述在這裏插入圖片描述

10、結論

  • 客戶端1即(消費者1)接收到消息
  • 客戶端2即(消費者2)未接收到消息

11、結論的原因

1)、客戶端1即(消費者1)綁定隊列到交換機中路由key指定了select、insert、update、delete 4種方式,如下圖:
在這裏插入圖片描述2)、客戶端2即(消費者2)綁定隊列到交換機中路由key指定了select、update 2種方式,如下圖:
在這裏插入圖片描述
3)服務端程序代碼發送消息時綁定路由key是delete,所以匹配到了客戶端1中綁定的路由key是delete,而客戶端2只有select和update,所以客戶端1接收到了消息,如下圖:
在這裏插入圖片描述

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