//@[TOC](SpringBoot +RabbitMQ)
准备工作
pom.xml导入rabbitmq依赖
<!-- rabbitmq依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
全局配置文件(application.properties)
##配置RabbitMQ连接信息
#主机ip地址
spring.rabbitmq.host=127.0.0.1
#主机端口号
spring.rabbitmq.port=5672
#用户名
spring.rabbitmq.username=user
#用户密码
spring.rabbitmq.password=123456
一、简单模式
图解
注解:
p:消息的生成者,代码连接时,将需要传递的消息,放入一个固定的名称的队列中;
c:消息的消费者,异步监听队列,一旦发现任何新的消息,获取消息消费
应用场景:短信消息、QQ
创建队列
案例:
//生产者
@Autowired
RabbitTemplate rbbitTemplate;
@RequestMapping("/message")
@ResponseBody
public void produce() {
String message=new Date()+"shenzhen";
System.out.println("生产者生产消息===="+message);
rbbitTemplate.convertAndSend("rabbitmq_queue",message);
}
//消费者
@Component
@RabbitListener(queues = "rabbitmq_queue")
public class Consumer1 {
@RabbitHandler
public void showMessage(String message) {
System.out.println("Consumer1接受到消息:"+message);
}
}
控制台打印如下:
二、工作模式(资源竞争)
图解
注解:
生产者p将消息发送到队列
队列被多个消息消费者监听,一旦发现新的消息生成,就会根据自己的能力(性能、资源空闲率);
应用场景:秒杀、抢红包、大型项目的资源调度
创建队列:
案例:
//生产者
@Autowired
RabbitTemplate rbbitTemplate;
@RequestMapping("/message")
@ResponseBody
public void produce() {
String message=new Date()+"shenzhen";
System.out.println("生产者生产消息===="+message);
rbbitTemplate.convertAndSend("rabbitmq_queue",message);
}
//多个消费者(以两个举例)
@Component
@RabbitListener(queues = "rabbitmq_queue")
public class Consumer1 {
@RabbitHandler
public void showMessage(String message) {
System.out.println("Consumer1接受到消息:"+message);
}
}
@Component
@RabbitListener(queues = "rabbitmq_queue")
public class Consumer2 {
@RabbitHandler
public void showMessage(String message) {
System.out.println("Consumer2接受到消息:"+message);
}
}
多运行几次测试方法在看看控制台打印结果
控制台打印如下:
会发现他是轮询得到的
三、发布/订阅模式(publish/fanout共享资源)
图解
注解:
x:代表rabbitmq一种核心组件交换机
p:生产者不在直接将消息发送到队列中
交换机分发消息性能更高,是基于erlang语言开发的一条消息,在交换机中,被复制同时发送到多个队列;
应用场景:群发、广告
创建交换机
创建队列
将交换机和刚刚创建的两个队列进行绑定
案例:
//生产者
@Autowired
RabbitTemplate rbbitTemplate;
@RequestMapping("/message/test")
@ResponseBody
public void messageTest() {
rbbitTemplate.convertAndSend("test","","RabbitMQ:发布/订阅模式Publish/direct");
}
//消费者(以两个举例)
@Component
@RabbitListener(queues="testDY")
public class Subscriber {
@RabbitHandler
public void showMessage(String message) {
System.out.println("testDY接受到消息:"+message);
}
}
@Component
@RabbitListener(queues="testJD")
public class Subscriber2 {
@RabbitHandler
public void showMessage(String message) {
System.out.println("testJD接受到消息:"+message);
}
}
控制台打印如下:
四、路由模式
图解
生产者发送消息,
x交换机,根据消息携带的路由key,匹配具有相同路由key的queue队列
使用场景:错误消息的监听;
创建交换机(修改类型为direct)
创建队列
将交换机和刚刚创建创建的路由进行绑定
将route1的Routing key 的值为message.log,绑定成功后效果图如下:
将route2的Routing key 的值为error.log,绑定成功后效果图如下:
案例:
//生产者
@Autowired
RabbitTemplate rbbitTemplate;
@RequestMapping("/message/route")
@ResponseBody
public void messageRouteTest() {
rbbitTemplate.convertAndSend("route","error.log","RabbitMQ:使用路由模式发送了消息:error.log");
}
//消费者(以两个举例)
@Component
@RabbitListener(queues="route1")
public class Route {
@RabbitHandler
public void showMessage(String message) {
System.out.println("route1接受到消息:"+message);
}
}
@Component
@RabbitListener(queues="route2")
public class Route2 {
@RabbitHandler
public void showMessage(String message) {
System.out.println("route2接受到消息:"+message);
}
}
控制台打印如下:
五、主题模式
图解
生产者发送携带具体的路由key的消息
应用场景:转发路由过程中,携带的信息非常具体,可以将信息分类处理
创建交换机(新建一个交换机subject(注意:(Type)类型一定要改为topic))
创建队列
将交换机和刚刚创建的队列进行绑定
将这三个队列与交换机subject进行绑定并设置Routing key的值
将subject1的Routing key 的值为error.log,绑定成功后效果图如下:
将subject2的Routing key 的值为error.,绑定成功后效果图如下:
将subject3的Routing key 的值为.log,绑定成功后效果图如下:
注意:符号 # 匹配一个或多个词,符号 * 匹配不多不少一个
词。因此 usa.# 能够匹配到 usa.news.xxx,但是 usa.* 只会匹配到 usa.xxx
绑定完之后效果图如下:
案例:
//生产者
@Autowired
RabbitTemplate rbbitTemplate;
@RequestMapping("/message/subject")
@ResponseBody
public void messageSubject() {
rbbitTemplate.convertAndSend("subject","error.log","RabbitMQ:使用主题模式发送了消息:error.log");
}
//消费者(以三个举例)
@Component
@RabbitListener(queues = "subject1")
public class Subject {
@RabbitHandler
public void showMessage(String message) {
System.out.println("subject1接受到消息:"+message);
}
}
@Component
@RabbitListener(queues = "subject2")
public class Subject2 {
@RabbitHandler
public void showMessage(String message) {
System.out.println("subject2接受到消息:"+message);
}
}
@Component
@RabbitListener(queues = "subject3")
public class Subject3 {
@RabbitHandler
public void showMessage(String message) {
System.out.println("subject3接受到消息:"+message);
}
}