RabbitMQ 之topics (通配符)篇 初学
官网地址:https://www.rabbitmq.com/getstarted.html
一、RabbitMQ简介
MQ全称为Message Queue,即消息队列, RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message
Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开
发中应用非常广泛。
二、开发中消息队列通常有如下应用场景:
1、任务异步处理。
将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间。
2、应用程序解耦合
MQ相当于一个中介,生产方通过MQ与消费方交互,它将应用程序进行解耦合。
市场上还有哪些消息队列?
ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ、Redis。
三、为什么使用RabbitMQ呢?
1、使得简单,功能强大。
2、基于AMQP协议。
3、社区活跃,文档完善。
4、高并发性能好,这主要得益于Erlang语言。
5、Spring Boot默认已集成RabbitMQ
四、RabbitMQ的所有模式(以下截图都是官方链接里面的)
五、代码举例Topics实现
准备工作:下载RabbitMQ客户端: http://www.rabbitmq.com/download.html
下载erlang,因为RabbitMQ是erlang语言开发的,所以需要下载: http://erlang.org/download/otp_win64_20.3.exe
下载好以后进行安装。安装完成后进行开发测出:
1、首先第一步需要导入RabbitMQ的java客户端,我这里是创建的maven项目,所以直接导入依赖,如下:
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.1.2</version>
<scope>test</scope>
</dependency>
注意:通配符有两个:
1. # :代表没有或一个或多个单词(单词与单词之间用“.”分割);
2. * :代表一个零个或一个单词;
例如:
aa.#.bb.* :
匹配的: aa.HH.CC.bb 、 aa.bb 、aa.bb.cc
不匹配: aa.cc 、 aa.bb.cc.dd
2、创建工程项目以及生产者P和消费者C1与C2(假设C1是短信SMS接收者,C2是邮件Email接收者)
3、编写生产者P类:
package com.test.rabbitmq;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class P {
//队列名称
private static final String QUEUE_INFORM_EMAIL = "queue_inform_email";
private static final String QUEUE_INFORM_SMS = "queue_inform_sms";
//交换机名称
private static final String EXCHANGE_TOPICS_INFORM = "exchange_topics_inform";
public static void main(String[] args) {
Connection connection = null;
Channel channel = null;
//创建连接工厂
try {
//创建一个与MQ的连接
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("127.0.0.1");
//创建一个tcp连接
connection = factory.newConnection();
//通过连接创建一个通道,每个通道代表一个会话
channel = connection.createChannel();
/**
* 声明交换机:参数如下
* 1、交换机名称
* 2、交换机类型,fanout、topic、direct、headers
*/
channel.exchangeDeclare(EXCHANGE_TOPICS_INFORM, BuiltinExchangeType.TOPIC);
/**
* 声明队列:参数如下:
* 1、队列名称
* 2、是否持久化
* 3、是否独占此队列
* 4、队列不用是否自动删除
* 5、参数
*/
channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, false, null);
channel.queueDeclare(QUEUE_INFORM_SMS, true, false, false, null);
//发送邮件Email消息
for (int i = 0; i < 10; i++) {
String message = "email inform to user : " + i;
/**
* 向交换机发送消息 :参数明细
* 1、交换机名称,不指令使用默认交换机名称 Default Exchange
* 2、routingKey(路由key),根据key名称将消息转发到具体的队列,这里填写队列名称表示消息将发到此队列
* 3、消息属性
* 4、消息内容
*/
channel.basicPublish(EXCHANGE_TOPICS_INFORM, "inform.email", null, message.getBytes());
System.out.println("Send Message is:'" + message + "'");
}
//发送短信消息
for (int i = 0; i < 10; i++) {
String message = "sms inform to user : " + i;
channel.basicPublish(EXCHANGE_TOPICS_INFORM, "inform.sms", null, message.getBytes());
System.out.println("Send Message is:'" + message + "'");
}
//发送短信和邮件消息
for (int i = 0; i < 10; i++) {
String message = "sms and email inform to user" + i;
channel.basicPublish(EXCHANGE_TOPICS_INFORM, "inform.sms.email", null, message.getBytes());
System.out.println("Send Message is:'" + message + "'");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
4.编写消费者C1类:email接受者
package com.test.rabbitmq;
import com.rabbitmq.client.*;
public class C1 {
//队列名称
private static final String QUEUE_INFORM_EMAIL = "queue_inform_email";
//交换机名称
private static final String EXCHANGE_TOPICS_INFORM = "exchange_topics_inform";
public static void main(String[] args) {
Connection connection = null;
Channel channel = null;
try {
//创建一个与MQ的连接
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("127.0.0.1");
//创建一个tcp连接
connection = factory.newConnection();
//通过连接创建一个通道,每个通道代表一个会话
channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_TOPICS_INFORM, BuiltinExchangeType.TOPIC);
channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, false, null);
//绑定email通知队列
channel.queueBind(QUEUE_INFORM_EMAIL, EXCHANGE_TOPICS_INFORM, "inform.#.email.#");
//消费消息
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println(" [x] Received Email:'" +
delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");
};
channel.basicConsume(QUEUE_INFORM_EMAIL, true, deliverCallback, consumerTag -> {
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
5.编写消费者C2类 SMS接收者
package com.test.rabbitmq;
import com.rabbitmq.client.*;
public class C2 {
//队列名称
private static final String QUEUE_INFORM_SMS = "queue_inform_sms";
//交换机名称
private static final String EXCHANGE_TOPICS_INFORM = "exchange_topics_inform";
public static void main(String[] args) {
Connection connection = null;
Channel channel = null;
try {
//创建一个与MQ的连接
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("127.0.0.1");
//创建一个tcp连接
connection = factory.newConnection();
//通过连接创建一个通道,每个通道代表一个会话
channel = connection.createChannel();
channel.exchangeDeclare(EXCHANGE_TOPICS_INFORM, BuiltinExchangeType.TOPIC);
channel.queueDeclare(QUEUE_INFORM_SMS, true, false, false, null);
//绑定email通知队列
channel.queueBind(QUEUE_INFORM_SMS, EXCHANGE_TOPICS_INFORM, "inform.#.sms.#");
//消费消息
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println(" [x] Received SMS:'" +
delivery.getEnvelope().getRoutingKey() + "':'" + message + "'");
};
channel.basicConsume(QUEUE_INFORM_SMS, true, deliverCallback, consumerTag -> {
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
6.测试:
启动全部服务:先发送ssm消息:
同时生成ssm消息和email消息并发送:
测试结果:

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现