RabbitMQ的Topics 通配符模式(Topic)

RabbitMQ的Topics 通配符模式(Topic)

  • 模式说明

    1. Topic 类型与 Direct 相比,都是可以根据 RoutingKey 把消息路由到不同的队列。只不过 Topic 类型Exchange 可以让队列在绑定 Routing key 的时候使用通配符
    2. Routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert
    3. 通配符规则:# 匹配一个或多个词,* 匹配不多不少恰好1个词,例如:item.# 能够匹配 item.insert.abc 或者 item.insert,item.* 只能匹配 item.inser
  • Topics 通配符模式的图片
    RabbitMQ的Topics 通配符模式(Topic)_第1张图片

RabbitMQ的Topics 通配符模式(Topic)_第2张图片

  • 图解:
    1. 红色 Queue:绑定的是 usa.# ,因此凡是以 usa. 开头的 routing key 都会被匹配到
    2. 黄色 Queue:绑定的是 #.news ,因此凡是以 .news 结尾的 routing key 都会被匹配

  • 其实这个Topics 通配符模式是Exchange常见类型之一的Topic

  • 代码编写生产者(Topic模式)步骤

    1. 创建工厂
    2. 设置参数
    3. 创建连接
    4. 创建channel(管道)
    5. 创建队列(这里只创建两个)
    6. 创建交换机
    7. 绑定队列和队列
    8. 发送消息
    9. 关闭连接
package com.yang;

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;

public class Producer_Topics {
    public static void main(String[] args) throws IOException, TimeoutException {
        //1. 创建工厂
        ConnectionFactory factory = new ConnectionFactory();
        //2. 设置参数
        factory.setHost("192.168.20.146");
        factory.setPort(5672);
        factory.setUsername("test");
        factory.setPassword("test");
        factory.setVirtualHost("/test");
        //3. 创建连接
        Connection connection = factory.newConnection();
        //4. 创建管道
        Channel channel = connection.createChannel();
        //5. 创建队列
        String queueName1 = "test_topic_queue1";
        String queueName2 = "test_topic_queue2";
        channel.queueDeclare(queueName1,true,false,false,null);
        channel.queueDeclare(queueName2,true,false,false,null);
        //6. 创建交换机
        String  exchangeName = "";
        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.TOPIC,true,false,false,null);
        //7. 绑定队列和交换机
        /*
        queueBind(String queue, String exchange, String routingKey)
        参数:
            1. queue:队列名称
            2. exchange:交换机名称
            3. routingKey:路由键,绑定规则
                如果交换机的类型为fanout ,routingKey设置为""
         */

        // routing key  系统的名称.日志的级别。
        //需求: 所有error级别的日志存入数据库,所有order系统的日志存入数据库
        channel.queueBind(queueName1, exchangeName, "#.error");
        channel.queueBind(queueName2, exchangeName, "order.*");


        //8. 发送消息
        String body = "日志信息:张三调用了findAll方法...日志级别:info...";
        channel.basicPublish(exchangeName, "order.ss", null, body.getBytes());
        
        //9. 释放资源
        channel.close();
        connection.close();
    }
}

  • 尝试执行之后(只有queueName2有,因为只有order.*符合)
    在这里插入图片描述
  • 发送别的消息
 //8. 发送消息
        String body = "日志信息:张三调用了delete方法...发生错误...error...";
        channel.basicPublish(exchangeName, "order.error", null, body.getBytes());
        
  • 尝试执行之后(只有queueName1和2都符合)
    在这里插入图片描述

  • 代码编写消费者(Topic模式)步骤(其实不管什么模式消费者基本都这样写,就改改一个地方而已)
    1. 创建工厂
    2. 设置参数
    3. 创建连接
    4. 创建管道channel
    5. 接收消息
package com.yang;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Consumer_Topics1 {
    public static void main(String[] args) throws IOException, TimeoutException {
//        1.  创建工厂
        ConnectionFactory factory = new ConnectionFactory();
//        2. 设置参数
        factory.setHost("192.168.20.146");
        factory.setPort(5672);
        factory.setUsername("test");
        factory.setPassword("test");
        factory.setVirtualHost("/test");
          //3. 创建连接
        Connection connection = factory.newConnection();
//        //4. 创建管道
        Channel channel = connection.createChannel();
//        5. 接收消息
        String queueName = "test_topic_queue1";
        Consumer consumer = new DefaultConsumer(channel){
            @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(queueName,true,consumer);
    }
}

  • 第二个队列只需要队列名改一下就行了!
String queueName = "test_topic_queue2";
  • 两个的执行结果
    1. Consumer_Topics1(队列:test_topic_queue1)
      RabbitMQ的Topics 通配符模式(Topic)_第3张图片

    2. Consumer_Topics2(队列:test_topic_queue2)
      RabbitMQ的Topics 通配符模式(Topic)_第4张图片

  • 和我们的需求一样: 所有error级别的日志存入数据库,所有order系统的日志存入数据库

  • 小结

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

以上就是Topics 通配符模式的全部内容

你可能感兴趣的:(消息队列,Rabbitmq,Topic模式,RoutingKey,Topic)