目录
二. rabbitmq多种模型在springboot中的应用
maven依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
一. springboot集成rabbitmq方式要点:
springboot通过启动程序启动时,会自动根据配置文件注册RabbitTemplate类,通过操作该类完成rabbitmq的操作。
①配置文件配置连接信息:
rabbit:
mq:
host: 124.71.112.168
port: 5672
virtualHost: method1
user: method1
pwd: admin
server:
port: 8081
②相关注解使用解释:
@RabbitListener(queuesToDeclare = @Queue(value = "hello_method1", durable = "false", exclusive = "false", autoDelete = "false")) 声明一个类或者某个方法(如果是声明在方法上,则不再需要@RabbitHandler声明回调方法可以直接回调队列中的消息) ,声明这是一个消费者,并且绑定了队列,以及队列的属性配置
@RabbitListener(bindings = { //次注解是将队列与交换机完成绑定 @QueueBinding( value = @Queue, //创建一个临时队列,如果@Queue("queueName")则为指定一个显式队列 exchange = @Exchange(value = "fanouts", type = "fanout"), //声明交换机以及交换机的类型 key = {"info","error"} //可以指定交换机的一个或者多个路由 ) }) 在某个方法或者类上使用,表示将该消费者的队列与交换机完成绑定,并且声明交换机的类型
@RabbitHandler:该注解是表明某个方法对队列中获取到消息的回调处理
二. rabbitmq多种模型在springboot中的应用
1. 直连模式
直连模式是直接将消息发送至指定的队列中。消费者绑定队列完成消息的消费。springboot中对该种模式做个注解式的使用
生产者:
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void sendMsg() {
Map<String, String> map = new HashMap<>();
map.put("msg", "我是一个map类型的消息");
rabbitTemplate.convertAndSend("hello_method1", "this is a method1 message");
rabbitTemplate.convertAndSend("hello_method1", map);
}
消费者:消费者端可以针对不同参数类型的消息进行接收处理
@Component
/**
* 该注解是表明这是个消费者,并创建一个队列,@queue带边创建一个队列对象
* 其中的参数为:value是队列名,durable为是否持久化默认为true,exclusive为是否独占通道默认为false,autodelete为是都自动删除队列默认为false等设置
*/
@RabbitListener(queuesToDeclare = @Queue(value = "hello_method1", durable = "false", exclusive = "false", autoDelete = "false"))
public class Method1Consumer {
//次注解代表进行处理消息的回调方法
//主要参数的类型需要与发送消息的消息类型一致,否则接收不到消息
@RabbitHandler
public void getStringMessage(String message) {
System.out.println("消费者接收到消息:" + message);
}
@RabbitHandler
public void getMapMessage(Map<String, String> message) {
System.out.println("消费者接收到消息:" + message.get("msg"));
}
}
2. work模型
work模型为多个消费者绑定同一个队列,一起消费生产者发送的消息
生产者:
/**
* work模型,多个消费者绑定同一个队列,默认是公平调度的
*/
@Test
public void sendMsgWork() {
for (int i = 0; i < 10; i++) {
rabbitTemplate.convertAndSend("work", "this is a work message" + i);
}
}
消费者:
/**
* work模型中多个消费者绑定同一个队列消费消息
*/
@Component
public class WorkQueueConsumer {
@RabbitListener(queuesToDeclare = @Queue(value = "work", durable = "false", autoDelete = "false"))
public void getMessage1(String msg) {
System.out.println("consumer1接收到的消息:" + msg);
}
@RabbitListener(queuesToDeclare = @Queue(value = "work", durable = "false", autoDelete = "false"))
public void getMessage2(String msg) {
System.out.println("consumer2接收到的消息:" + msg);
}
}
3. fanout模型(广播订阅模型)
交换机的类型为:fanout
fanout模型为:生产者将消息投递在交换机中,消费者通过创建临时队列与交换机绑定,进行消费消息。fanout为广播模式,即所有绑定该交换机的队列均会收到消息。
生产者:
/**
* fanout模型,广播模式
*/
@Test
public void sendMsgFanout() {
//参数1:交换机名 参数2:路由,该类型不需要路由 参数3:消息
rabbitTemplate.convertAndSend("fanouts", "", "this is a fanout message");
}
消费者:需要对队列与交换机完成绑定,以下模拟两个消费者绑定该交换机处理消息
Component
public class FanoutConsumer {
@RabbitListener(bindings = {
//次注解是将队列与交换机完成绑定
@QueueBinding(
value = @Queue, //创建一个临时队列,如果@Queue("queueName")则为指定一个显式队列
exchange = @Exchange(value = "fanouts", type = "fanout") //声明交换机以及交换机的类型
)
})
public void getMessage1(String message) {
System.out.println("consumer1:" + message);
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue,
exchange = @Exchange(value = "fanouts", type = "fanout")
)
})
public void getMessage2(String message) {
System.out.println("consumer2:" + message);
}
}
4. direct模型(路由订阅模式)
交换机的类型为:direct
该模式为生产者发布消息时,通过指定交换机并且指定路由的方式发布消息
消费者在接收消息时,绑定交换机和队列,同时指定接收的是什么路由的消息。
从而消息会发送给绑定了相同交换机以及匹配路由的队列
生产者:
/**
* direct订阅模型
*/
@Test
public void getMsgDirect() {
rabbitTemplate.convertAndSend("direct", "error", "这是一个error路由消息");
}
消费者:
@Component
public class DirectConsumer {
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue, //创建临时队列
exchange = @Exchange(value = "direct", type = "direct"), //声明交换机以及交换机类型
key = {"error", "warning", "info"} //绑定交换机的路由为指定类型
)
})
public void getMessage1(String message) {
System.out.println("message1=" + message);
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue, //创建临时队列
exchange = @Exchange(value = "direct", type = "direct"), //声明交换机以及交换机类型
key = {"error"} //绑定交换机的路由为指定类型
)
})
public void getMessage2(String message) {
System.out.println("message2=" + message);
}
}
5. topic模型(动态路由订阅模型)
交换机类型为:topic
topic模型中:基于direct模型,添加了动态路由的概念,路由可以通过*/#来完成通配
生产者:
/**
* topic动态订阅模型
*/
@Test
public void getMsgTopic() {
String key = "user.add.add";
rabbitTemplate.convertAndSend("topic", key, "this is " + key + "message");
}
消费者:
@Component
public class TopiConsumer {
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue, //创建临时队列
exchange = @Exchange(value = "topic", type = "topic"),
key = {"user.*"} //动态路由的匹配规则
)
})
public void getMessage1(String message) {
System.out.println("message1=" + message);
}
@RabbitListener(bindings = {
@QueueBinding(
value = @Queue, //创建临时队列
exchange = @Exchange(value = "topic", type = "topic"),
key = {"user.#", "order.#"}
)
})
public void getMessage2(String message) {
System.out.println("message2=" + message);
}
}
三. rabbitmq的应用场景
rabbitmq的应用场景非常之多,常用的场景包括但不限于业务的异步处理、应用系统之间的解耦、消减业务尖峰值等