rabbitmq--通配符模式Topics

topic模式也称为主题模式,其实他相对于routing模式最大的好处就是他多了一种匹配模式的路由,怎么理解匹配呢,其实就相当于我们之前正则的.*这种,不过他的匹配机制可能不是这种(其实除了匹配规则外,他的作用就和routing模式一样 ),而他的工作流程图如下:

OK! 先说一下他的匹配规则:

绑定键binding key也必须是这种形式。以特定路由键发送的消息将会发送到所有绑定键与之匹配的队列中。但绑定键有两种特殊的情况: 
①*(星号)仅代表一个单词 
②#(井号)代表任意个单词

示例:

以上图为例:

*.orange.* :  匹配以 任意一个单词字符开头中间包含 .orange. 以任意一个单词字符结尾 的字符串。比如 a.orange.b, sdfsd.orange.fdsfsdf 等(注意是一个单词)。

lay.# :只要一lay.开头的都匹配,他可以匹配lay.a, lay.a.b, lay.b.c等。

这样是不是很方便,比如我们想将log的发给q1队列,其他的发给q2,那么我们只需要定义log.#、或者log.*,那么你发送给q1队列的数据就是log日志的消息。

 package com.maozw.mq.topic;

 import com.maozw.mq.config.RabbitConfig;
import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.Connection;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import java.io.IOException;
import java.util.concurrent.TimeoutException; import static org.apache.log4j.varia.ExternallyRolledFileAppender.OK; /**
* work 模式
* 两种分发: 轮询分发 + 公平分发
* 轮询分发:消费端:自动确认消息;boolean autoAck = true;
* 公平分发: 消费端:手动确认消息 boolean autoAck = false; channel.basicAck(envelope.getDeliveryTag(),false);
*
* @author MAOZW
* @Description: 商品
* @date 2018/11/26 15:06
*/
@RestController
@RequestMapping("/topic")
public class TopicProducer {
private static final Logger LOGGER = LoggerFactory.getLogger(TopicProducer.class);
@Autowired
RabbitConfig rabbitConfig; public static final String EXCHANGE_TOPIC = "EXCHANGE_TOPIC";
private static final String[] routingKeys = {"commodity.add", "commodity.update", "commodity.select", "commodity.delete"}; @RequestMapping("/send")
public String send() throws IOException, TimeoutException {
Connection connection = null;
Channel channel = null;
try {
ConnectionFactory connectionFactory = rabbitConfig.connectionFactory();
connection = connectionFactory.createConnection();
channel = connection.createChannel(false); /**
* 申明交换机 以及type
*/
channel.exchangeDeclare(EXCHANGE_TOPIC, "topic");
/**
* 发送消息
* 每个消费者 发送确认消息之前,消息队列不会发送下一个消息给消费者,一次只处理一个消息
* 自动模式无需设置下面设置
*/
int prefetchCount = 1;
channel.basicQos(prefetchCount); String Hello = ">>>> Hello EXCHANGE_TOPIC <<<<";
String message = Hello;
for (String routingKey : routingKeys) {
channel.basicPublish(EXCHANGE_TOPIC, routingKey, null, message.getBytes());
}
LOGGER.info("生产消息: " + message);
return "OK";
} catch (Exception e) { } finally {
connection.close();
channel.close();
return OK;
}
}
}
 package com.maozw.mq.topic;

 import com.maozw.mq.config.RabbitConfig;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.Connection;
import org.springframework.amqp.rabbit.connection.ConnectionFactory; import java.io.IOException; /**
* @author MAOZW
* @Description: ${todo}
* @date 2018/11/26 15:06
*/ public class TopicConsumer {
private static final Logger LOGGER = LoggerFactory.getLogger(TopicConsumer.class);
public static final String EXCHANGE_TOPIC = "EXCHANGE_TOPIC";
private static final String[] routingKeys = {"commodity.add", "commodity.update", "commodity.delete"}; public static void main(String[] args) throws IOException {
ConnectionFactory connectionFactory = RabbitConfig.getConnectionFactory();
Connection connection = connectionFactory.createConnection();
Channel channel = connection.createChannel(false);
/**
* 创建队列申明
*/
boolean durable = true;
channel.queueDeclare(RabbitConfig.QUEUE_TOPIC, durable, false, false, null);
/**
* 绑定队列到交换机
*/
channel.queueBind(RabbitConfig.QUEUE_TOPIC, EXCHANGE_TOPIC, "commodity.add"); /**
* 改变分发规则
*/
channel.basicQos(1);
DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
super.handleDelivery(consumerTag, envelope, properties, body);
System.out.println("[1] 接口数据 : " + new String(body, "utf-8"));
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("[1] done!");
//消息应答:手动回执,手动确认消息
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
//监听队列
/**
* autoAck 消息应答
* 默认轮询分发打开:true :这种模式一旦rabbitmq将消息发送给消费者,就会从内存中删除该消息,不关心客户端是否消费正常。
* 使用公平分发需要关闭autoAck:false 需要手动发送回执
*/
boolean autoAck = false;
channel.basicConsume(RabbitConfig.QUEUE_TOPIC, autoAck, consumer);
} }
 package com.maozw.mq.topic;

 import com.maozw.mq.config.RabbitConfig;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.Connection;
import org.springframework.amqp.rabbit.connection.ConnectionFactory; import java.io.IOException; /**
* @author MAOZW
* @Description: ${todo}
* @date 2018/11/26 15:06
*/ public class TopicConsumer2 {
private static final Logger LOGGER = LoggerFactory.getLogger(TopicConsumer2.class);
public static final String EXCHANGE_TOPIC = "EXCHANGE_TOPIC";
private static final String[] routingKeys = {"commodity.add", "commodity.update", "commodity.delete", "commodity.select"}; public static void main(String[] args) throws IOException {
ConnectionFactory connectionFactory = RabbitConfig.getConnectionFactory();
Connection connection = connectionFactory.createConnection();
Channel channel = connection.createChannel(false);
/**
* 创建队列申明
*/
boolean durable = true;
channel.queueDeclare(RabbitConfig.QUEUE_TOPIC2, durable, false, false, null); /**
* 绑定队列到交换机
*/
channel.queueBind(RabbitConfig.QUEUE_TOPIC2, EXCHANGE_TOPIC, "commodity.*"); /**
* 改变分发规则
*/
channel.basicQos(1);
DefaultConsumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
super.handleDelivery(consumerTag, envelope, properties, body);
System.out.println("[2] 接口数据 : " + new String(body, "utf-8"));
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("[2] done! ");
//消息应答:手动回执,手动确认消息
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
//监听队列
/**
* autoAck 消息应答
* 默认轮询分发打开:true :这种模式一旦rabbitmq将消息发送给消费者,就会从内存中删除该消息,不关心客户端是否消费正常。
* 使用公平分发需要关闭autoAck:false 需要手动发送回执
*/
boolean autoAck = false;
channel.basicConsume(RabbitConfig.QUEUE_TOPIC2, autoAck, consumer);
}
}

5.rabbitmq--通配符模式Topics的更多相关文章

  1. 干货!基于SpringBoot的RabbitMQ多种模式队列实战

    目录 环境准备 安装RabbitMQ 依赖 连接配置 五种队列模式实现 1 点对点的队列 2 工作队列模式Work Queue 3 路由模式Routing 4 发布/订阅模式Publish/Subsc ...

  2. 【RabbitMQ】4、三种Exchange模式——订阅、路由、通配符模式

    前两篇博客介绍了两种队列模式,这篇博客介绍订阅.路由和通配符模式,之所以放在一起介绍,是因为这三种模式都是用了Exchange交换机,消息没有直接发送到队列,而是发送到了交换机,经过队列绑定交换机到达 ...

  3. RabbitMQ 一二事(5) - 通配符模式应用

    之前的路由模式是通过key相等来匹配 而通配符,顾名思义,符合条件,则进行消息匹配发送 将路由键和某模式进行匹配.此时队列需要绑定要一个模式上. 符号“#”匹配一个或多个词,符号“*”匹配不多不少一个 ...

  4. RabbitMQ工作模式

    ------------恢复内容开始------------ RabbitMQ基本概念: Producer:生产者(消息的提供者) Consumer:消费者(消息的使用者) Message:消息(程序 ...

  5. rabbitMQ tipic 模式

    RabbitMQ消息队列(八)-通过Topic主题模式分发消息(.Net Core版) 前两章我们讲了RabbitMQ的direct模式和fanout模式,本章介绍topic主题模式的应用.如果对di ...

  6. 1.RabbitMq - Work 模式

    RabbitMq - Work 模式 一.什么是Work模式 如果有几个消息都需要处理,且每个消息的处理时间很长,仅有一个消费者,那么当它在处理一个消息的时候,其他消息就只有等待. 等待有时候是好的, ...

  7. 【c#】RabbitMQ学习文档(五)Topic(主题。通配符模式)

    (本实例都是使用的Net的客户端,使用C#编写),说明,中文方括号[]表示名词. 在上一个教程中,我们改进了我们的日志记录系统. 没有使用只能够进行虚拟广播的[Fanout]交换机,而是使用了[Dir ...

  8. RabbitMQ之Exchange Topics模式

    说明:此模式实在路由key模式的基础上,使用了通配符来管理消费者接收消息.生产者P发送消息到交换机X,type=topic,交换机根据绑定队列的routing key的值进行通配符匹配: 符号#:匹配 ...

  9. 【RabbitMQ】三种Exchange模式——订阅、路由、通配符模式

    https://blog.csdn.net/ww130929/article/details/72842234

随机推荐

  1. spark application调度机制(spreadOutApps,oneExecutorPerWorker 算法)

    1.要想明白spark application调度机制,需要回答一下几个问题: 1.谁来调度? 2.为谁调度? 3.调度什么? 3.何时调度? 4.调度算法 前四个问题可以用如下一句话里来回答:每当集 ...

  2. arcgis js之地图分屏同步

    arcgis js之地图分屏同步 原理: 新建两个map两个view或者一个map两个view.对地图进行移动事件绑定,在地图移动时同步地图方位 代码: views.forEach((view) =& ...

  3. jmeter连接mysql数据库进行多条语句查询

    前提工作: 1.在jmeter官网下载jmeter包(官网地址:https://jmeter.apache.org/).此外还需下载mysql驱动包,如:mysql-connector-java-5. ...

  4. 解决织梦5.7添加新变量出现:Request var not allow!的办法

    找到:根目录->include->common.inc.phpif( strlen($svar)>0 && preg_match('#^(cfg_|GLOBALS|_ ...

  5. linux驱动程序与菜单关联

  6. Django安装和介绍

    在CMD和pycharm的安装方法. 先说CMD的安装方法 1,使用pip3 install django 2,进入c:python\Scripts 3,django-admin.exe startp ...

  7. QT学习之路DAY1之初学QT的小项目

    以下所有代码均利用软件QT5编写 项目一:Hello world! 利用QTcreator创建项目 修改main.cpp代码为 #include "mainwindow.h" #i ...

  8. 不创建父窗体的情况下他其他窗体的信息显示在第一个打开的窗体!(winfrom)

    公司使用vs2008做的东西,用vs2017都打不开了(编译错误) 叫我更新一下,我看了一下,08的项目 和 winform 差不多  如何就用winfrom来做了 (winform  很久没碰了,, ...

  9. DATASNAP双缓存下载文件

    原文链接:http://www.cnblogs.com/hnxxcxg/archive/2012/12/29/2839358.html procedure TFrmMain.btnUpdateFile ...

  10. Shell 语法报错记录

    sh: missing ] if 条件语句 “或”多个条件并行时 执行then命令 变量a等于aa且变量b等于bb 或者 变量c等于cc且变量d等于dd 这样的条件成立的话,输出success if ...