RabbitMQ Topics 通配符工作模式案例

RabbitMQ Topics 通配符工作模式案例

说明: Topic 工作模式可以实现 Pub/Sub 发布与订阅模式和 Routing 路由模式的功能,只是 Topic在配置routing key的时候可以使用通配符,显得更加灵活。

  1. Routing key 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert
  2. 通配符规则:# 匹配一个或多个词,* 只能匹配1个词,例如:item.# 能够匹配 item.insert.abc 或者 item.insert。 item.* 只能匹配 item.insert

1. 创建rabbitMQ的生产者

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 创建rabbitMQ的生产者
 * Topics 通配符模式
 * Topic 工作模式可以实现 Pub/Sub 发布与订阅模式和 Routing 路由模式的功能,只是 Topic 在配置routing key的时候可以使用通配符,显得更加灵活。
 * Routing key 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert
 * 通配符规则:# 匹配一个或多个词,* 只能匹配1个词,例如:item.# 能够匹配 item.insert.abc 或者 item.insert。 item.* 只能匹配 item.insert
 */
public class ProducerTopics {
    public static void main(String[] args) throws IOException, TimeoutException {
        // 1. 创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        // 2. 设置连接参数
        factory.setHost("192.168.192.137");  // 设置ip地址,默认为localhost
        factory.setPort(5672);  // 设置端口,默认为5672
        factory.setVirtualHost("/qmh"); // 设置连接的虚拟机,默认为/
        factory.setUsername("qmh"); // 设置用户名,默认为guest
        factory.setPassword("qmh"); // 设置密码,默认为guest
        // 3. 创建连接
        Connection connection = factory.newConnection();
        // 4. 创建Channel
        Channel channel = connection.createChannel();
        /**
         * 5. 创建交换机 exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete, boolean internal, Map<String, Object> arguments)
         * exchange     交换机名称
         * type         交换机类型
         *  --          DIRECT("direct")    定向,把消息交给符合指定routing key 的队列
         *  --          FANOUT("fanout")    广播,将消息交给所有绑定到交换机的队列
         *  --          TOPIC("topic")      通配符,把消息交给符合routing pattern(路由模式) 的队列
         *  --          HEADERS("headers")  参数匹配
         *  durable     是否持久化
         *  autoDelete  自动删除
         *  internal    内部使用,RabbitMQ原生语言Erlang内部使用插件,默认false
         *  arguments   参数
         */
        String exchangeName = "test_topic";
        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.TOPIC,true,false,false,null);
        /**
         * 6. 创建队列  queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
         * queue        队列名称,如果没有该队列,自动创建
         * durable      是否持久化, 如果true,数据写进rabbitMQ的数据库中
         * exclusive    1. 是否独占,只能有一个消费者监听该队列  2. 当Connection删除时,是否删除队列
         * autoDelete   是否自动删除,当没有消费者时,自动删除
         * arguments    参数
         */
        String queueOneName = "test_topic_queue_one";
        String queueTwoName = "test_topic_queue_two";
        channel.queueDeclare(queueOneName,true,false,false,null);
        channel.queueDeclare(queueTwoName,true,false,false,null);
        /**
         * 绑定队列和交换机  queueBind(String queue, String exchange, String routingKey)
         * queue        队列名称
         * exchange     交换机名称
         * routingKey   路由键,绑定规则
         * -- 如果交换机类型为fanout, routingKey设置为""
         * -- 如果交换机类型为direct, 自定义消息的 RoutingKey
         * -- 如果交换机类型为TOPIC, 使用通配符自定义
         */
        channel.queueBind(queueOneName,exchangeName,"#.error");
        channel.queueBind(queueOneName,exchangeName,"order.*");
        channel.queueBind(queueTwoName,exchangeName,"*.*");
        /**
         * 6. 发送消息   basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
         * exchange     交换机名称,简单模式交换机默认为 ""
         * routingKey   路由名称
         * -- 简单模式下的路由名称和队列名称保持一致
         * -- 如果交换机类型为fanout, routingKey设置为""
         * -- 如果交换机类型为direct, 指定消息的 RoutingKey
         * props        配置信息
         * body         发送消息数据
         */
        String body = "日志信息: qmh用户调用了... ! 日志级别: info";
        String bodyCopy = "日志信息: qmh用户删除了一条信息... ! 日志级别: error";
        String bodyTwo = "日志信息: qmh用户查询了一条信息... ! 日志级别: error";
        channel.basicPublish(exchangeName,"order.info",null,body.getBytes());
        channel.basicPublish(exchangeName,"delete.error",null,bodyCopy.getBytes());
        channel.basicPublish(exchangeName,"goods.info",null,bodyTwo.getBytes());
        // 7. 释放资源
        channel.close();
        connection.close();
    }

}

2. 创建rabbitMQ的消费者

  • 消费者一号
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 创建rabbitMQ的消费者
 */
public class ConsumerTopicOne {
    public static void main(String[] args) throws IOException, TimeoutException {
        // 1. 创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        // 2. 设置连接参数
        factory.setHost("192.168.192.137");  // 设置ip地址,默认为localhost
        factory.setPort(5672);  // 设置端口,默认为5672
        factory.setVirtualHost("/qmh"); // 设置连接的虚拟机,默认为/
        factory.setUsername("qmh"); // 设置用户名,默认为guest
        factory.setPassword("qmh"); // 设置密码,默认为guest
        // 3. 创建连接
        Connection connection = factory.newConnection();
        // 4. 创建Channel
        Channel channel = connection.createChannel();
        /**
         * 5. 获取对应的队列名称
         */
        String queueOneName = "test_topic_queue_one";
        /**
         * 6. 接收消息   basicConsume(String queue, boolean autoAck, Consumer callback)
         * queue        队列名称
         * autoAck      是否自动确认,当消费者接收到信息后,自动确认
         * callback     回调
         */
        Consumer consumer = new DefaultConsumer(channel){
            /**
             * 回调方法,当收到消息后执行该方法
             * @param consumerTag   消息标识
             * @param envelope      获取信息,比如交换机信息,路由key...
             * @param properties    配置信息
             * @param body          数据
             * @throws IOException
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("body:" + new String(body));
                System.out.println("消费者一号已经接收信息,并且保存进数据库 ! ");
            }
        };
        channel.basicConsume(queueOneName,true,consumer);
    }
}

  • 消费者二号
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 创建rabbitMQ的消费者
 */
public class ConsumerTopicTwo {
    public static void main(String[] args) throws IOException, TimeoutException {
        // 1. 创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        // 2. 设置连接参数
        factory.setHost("192.168.192.137");  // 设置ip地址,默认为localhost
        factory.setPort(5672);  // 设置端口,默认为5672
        factory.setVirtualHost("/qmh"); // 设置连接的虚拟机,默认为/
        factory.setUsername("qmh"); // 设置用户名,默认为guest
        factory.setPassword("qmh"); // 设置密码,默认为guest
        // 3. 创建连接
        Connection connection = factory.newConnection();
        // 4. 创建Channel
        Channel channel = connection.createChannel();
        /**
         * 5. 获取对应的队列名称
         */
        String queueOneName = "test_topic_queue_two";
        /**
         * 6. 接收消息   basicConsume(String queue, boolean autoAck, Consumer callback)
         * queue        队列名称
         * autoAck      是否自动确认,当消费者接收到信息后,自动确认
         * callback     回调
         */
        Consumer consumer = new DefaultConsumer(channel){
            /**
             * 回调方法,当收到消息后执行该方法
             * @param consumerTag   消息标识
             * @param envelope      获取信息,比如交换机信息,路由key...
             * @param properties    配置信息
             * @param body          数据
             * @throws IOException
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("body:" + new String(body));
                System.out.println("消费者一号已经接收信息 ! ");
            }
        };
        channel.basicConsume(queueOneName,true,consumer);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值