建议看官网的Spring AMQP,需要快速入门可以看这篇文章
rabbitmq官网队列
https://www.rabbitmq.com/getstarted.html
配置就不写了,直接上SpringBoot使用rabbitmq,有人看在补配置
rabbitmq常用的6种工作模式
1.简单模式
2.工作模式
3.发布/订阅模式(广播模式)
4.路由模式
5.主题模式
6.RPC模式
7.出版商确认模式(此篇文章没有该内容)
rabbitmq使用的常量
队列,交换机,路由都用一个类定义
package com.rabbit.demo.constant;
/**
* @className: QueueConstant
* @description: 队列常量
* @createDate: 2021年06月15日 10:38:53
* @author: ns
*/
public class QueueConstant {
//简单队列
public final static String SIMPLE_QUEUE = "simple_queue";
//工作队列
public final static String WORK_QUEUE = "work_queue";
//发布交换机
public final static String RELEASE_FANOUT_EXCHANGE = "release_fanout_exchange";
//路由
public final static String DIRECT = "direct";
}
队列控制层
因为是springboot集成rabbitmq就直接使用RabbitTemplate
package com.rabbit.demo.controller;
import com.rabbit.demo.constant.QueueConstant;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @className: QueueController
* @description:
* @createDate: 2021年05月28日 16:14:29
* @author: ns
*/
@RestController
public class QueueController {
@Autowired
private RabbitTemplate rabbitTemplate;
//简单队列
@GetMapping("/simple/queue")
public void simpleQueue(){
System.out.println("简单队列发送");
rabbitTemplate.convertAndSend(QueueConstant.WORK_QUEUE,"简单队列消费完成");
}
//工作队列
@GetMapping("/work/queue")
public void workQueue() {
System.out.println("老板开始派发任务");
for (int i = 0; i < 10; i++) {
rabbitTemplate.convertAndSend(QueueConstant.WORK_QUEUE, "搬第" + i + "块砖");
}
}
//发布订阅模式
@GetMapping("/publish/subscribe/queue")
public void publishSubscribe() {
System.out.println("老板开始派发任务");
for (int i = 0; i < 5; i++) {
rabbitTemplate.convertAndSend(QueueConstant.RELEASE_FANOUT_EXCHANGE, "", "开始工作");
}
}
//路由模式
@GetMapping("/queue/route")
public void routeMode() {
System.out.println("程序开始运行");
String[] strings = new String[]{"error", "info", "warring"};
for (String string : strings) {
rabbitTemplate.convertAndSend(QueueConstant.DIRECT, string, string);
}
}
//主题模式
@GetMapping("/queue/topic")
public void topicQueue() {
System.out.println("主题模式开始运行");
String[] strings = {"quick.orange.rabbit", "lazy.orange.elephant", "quick.orange.fox",
"lazy.brown.fox", "lazy.pink.rabbit", "quick.brown.fox"};
for (String string : strings) {
rabbitTemplate.convertAndSend(QueueConstant.TOPIC_EXCHANGE, string, string);
}
}
}
简单模式
作用:一对一发送接收,一个生产者,一个消费者
常用于异步处理业务
例如用户注册之后发送邮件,用户注册和邮件发送不用同时执行,可以使用rabbitmq将其分开异步执行,增加用户体验感
package com.rabbit.demo.consumer;
import com.rabbit.demo.constant.QueueConstant;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @className: SimpleQueueConsumer
* @description:
* @createDate: 2021年05月28日 16:05:22
* @author: ns
*/
@Component
@RabbitListener(queuesToDeclare = @Queue(QueueConstant.SIMPLE_QUEUE))
public class SimpleQueueConsumer {
//简单队列
@RabbitHandler
public void workQueues(String s){
System.out.println("简单队列开始消费");
System.out.println(s);
}
}
工作模式
作用:多个队列处理任务,增加任务完成的效率
场景:当有一个任务,需要被自动尽快处理时,增加消费者数量处理
PS:一个消息只能被处理一次,即使有多个队列处理这个任务
当队列大于1个的时候,监听方法上需要写@RabbitHandler,不然发送的消息找不到处理的
搬砖工一号
package com.rabbit.demo.consumer;
import com.rabbit.demo.constant.QueueConstant;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @className: WorkQueueConsumer
* @description: 工作队列消费
* @createDate: 2021年06月15日 16:47:18
* @author: ns
*/
@Component
@RabbitListener(queuesToDeclare = @Queue(QueueConstant.WORK_QUEUE))
public class WorkQueueConsumer {
@RabbitHandler
public void String(String s) {
System.out.println("搬砖工一号开始" + s);
}
}
搬砖工二号
package com.rabbit.demo.consumer;
import com.rabbit.demo.constant.QueueConstant;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @className: WorkQueueConsumer
* @description: 工作队列消费
* @createDate: 2021年06月15日 16:47:18
* @author: ns
*/
@Component
@RabbitListener(queuesToDeclare = @Queue(QueueConstant.WORK_QUEUE))
class WorkQueueConsumer1 {
@RabbitHandler
public void String(String s) {
System.out.println("搬砖工二号开始" + s);
}
}
运行效果
发布/订阅模式(广播模式)
作用:将一条消息发送给交换机,然后交换机再发送给与其绑定的队列
应用场景:当新员工入职时,调用发邮件的队列和加入流程的队列
配置文件
AnonymousQueue匿名队列在断开连接后会自动删除
这里也可以为设置固定的队列名以供使用
package com.rabbit.demo.config;
import com.rabbit.demo.constant.QueueConstant;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @className: RabbitConfig
* @description:
* @createDate: 2021年06月15日 18:42:48
* @author: ns
*/
@Configuration
public class RabbitConfig {
/**
* 创建匿名队列1
*/
@Bean
public Queue queue1() {
return new AnonymousQueue();
}
/**
* 创建匿名队列2
*/
@Bean
public Queue queue2() {
return new AnonymousQueue();
}
/**
* 创建广播交换机
*/
@Bean
public FanoutExchange fanoutExchange() {
return new FanoutExchange(QueueConstant.RELEASE_FANOUT_EXCHANGE);
}
/**
* 交换机与队列1绑定
*/
@Bean
public Binding bindingQueue1(Queue queue1, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(queue1).to(fanoutExchange);
}
/**
* 交换机与队列2绑定
*/
@Bean
public Binding bindingQueue2(Queue queue2, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(queue2).to(fanoutExchange);
}
}
package com.rabbit.demo.consumer;
import com.rabbit.demo.constant.QueueConstant;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @className: PublishSubscribeConsumer
* @description: 发布订阅
* @createDate: 2021年06月16日 10:54:17
* @author: ns
*/
@Component
public class PublishSubscribeConsumer {
@RabbitHandler
@RabbitListener(queues = "#{queue1.name}")
public void consumer(String s) {
System.out.println("前端" + s);
}
@RabbitHandler
@RabbitListener(queues = "#{queue2.name}")
public void consume1r(String s) {
System.out.println("后端" + s);
}
}
运行结果
路由模式
作用:路由模式用于区分执行,当达成某个条件时,可由对应消费者进行消费
场景:不同的日志进行不同的处理
路由模式配置文件
package com.rabbit.demo.config;
import com.rabbit.demo.constant.QueueConstant;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @className: RabbitDirectConfig
* @description: 路由模式配置
* @createDate: 2021年06月21日 16:17:49
* @author: ns
*/
@Configuration
public class RabbitDirectConfig {
/**
* 创建路由交换机
*/
@Bean
public DirectExchange direct(){
return new DirectExchange(QueueConstant.DIRECT);
}
/**
* 创建匿名队列1
*/
@Bean
public Queue autoDeleteQueue1(){
return new AnonymousQueue();
}
/**
* 创建匿名队列2
*/
@Bean
public Queue autoDeleteQueue2(){
return new AnonymousQueue();
}
/**
* 绑定错误级别日志
*/
@Bean
public Binding binding1(DirectExchange direct,Queue autoDeleteQueue1){
return BindingBuilder.bind(autoDeleteQueue1)
.to(direct)
.with("error");
}
/**
* 绑定警告级别日志
*/
@Bean
public Binding binding2(DirectExchange direct,Queue autoDeleteQueue2){
return BindingBuilder.bind(autoDeleteQueue2)
.to(direct)
.with("warring");
}
/**
* 绑定显示级别日志
*/
@Bean
public Binding binding3(DirectExchange direct,Queue autoDeleteQueue2){
return BindingBuilder.bind(autoDeleteQueue2)
.to(direct)
.with("info");
}
/**
* 绑定错误级别日志
*/
@Bean
public Binding binding4(DirectExchange direct,Queue autoDeleteQueue2){
return BindingBuilder.bind(autoDeleteQueue2)
.to(direct)
.with("error");
}
}
路由模式消费者
package com.rabbit.demo.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @className: DirectModeConsumer
* @description: 路由模式消费者
* @createDate: 2021年06月21日 16:25:50
* @author: ns
*/
@Component
public class DirectModeConsumer {
@RabbitListener(queues = "#{autoDeleteQueue1.name}")
public void receive1(String s) {
System.out.println(s + "开始处理报警");
}
@RabbitListener(queues = "#{autoDeleteQueue2.name}")
public void receive2(String s) {
System.out.println(s + "开始处理闲置不动");
}
}
运行结果
主题模式
作用:主题模式相当于在路由模式的基础上增加了一个通配符的功能
当队列与“ # ”(散列)绑定键绑定时——它将接收所有消息,而不管路由键——就像在扇出交换中一样。
当绑定中不使用特殊字符“ * ”(星号)和“ # ”(散列)时,主题交换的行为就像直接交换一样。
详细请查看官网介绍
https://www.rabbitmq.com/tutorials/tutorial-five-spring-amqp.html
场景:需要通配路径时使用
主题模式配置文件
package com.rabbit.demo.config;
import com.rabbit.demo.constant.QueueConstant;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @className: RabbitTopicConfig
* @description: 主题配置
* @createDate: 2021年06月23日 15:35:21
* @author: ns
*/
@Configuration
public class RabbitTopicConfig {
/**
* 主题交换机
*/
@Bean
public TopicExchange topicExchange() {
return new TopicExchange(QueueConstant.TOPIC_EXCHANGE);
}
/**
* 匿名队列1
*/
@Bean
public Queue topicQueue1() {
return new AnonymousQueue();
}
/**
* 匿名队列2
*/
@Bean
public Queue topicQueue2() {
return new AnonymousQueue();
}
/**
* 绑定主题交换机与队列和路由关键字
*/
@Bean
public Binding binding1(TopicExchange topicExchange, Queue topicQueue1) {
return BindingBuilder.bind(topicQueue1)
.to(topicExchange)
.with("*.orange.*");
}
/**
* 绑定主题交换机与队列和路由关键字
*/
@Bean
public Binding binding2(TopicExchange topicExchange, Queue topicQueue2) {
return BindingBuilder.bind(topicQueue2)
.to(topicExchange)
.with("*.*.rabbit");
}
/**
* 绑定主题交换机与队列和路由关键字
*/
@Bean
public Binding binding3(TopicExchange topicExchange, Queue topicQueue2) {
return BindingBuilder.bind(topicQueue2)
.to(topicExchange)
.with("lazy.#");
}
}
主题模式消费者
package com.rabbit.demo.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @className: TopicModeConsumer
* @description: 主题模式消费者
* @createDate: 2021年06月23日 15:59:39
* @author: ns
*/
@Component
public class TopicModeConsumer {
@RabbitListener(queues = "#{topicQueue1.name}")
public void receive(String s) {
System.out.println(s + ",属于:*.orange.*");
}
@RabbitListener(queues = "#{topicQueue2.name}")
public void receive1(String s) {
System.out.println(s + ",属于:lazy.#或*.*.rabbit");
}
}
运行结果
RPC模式
作用:内部服务调用
优点:可以实现分布式事务
建议:使用Spring Cloud框架可以使用Openg Fegin进行内部的RPC调用
这里就不细讲了