目录
1.简单队列模式
说明:
一个生产者对应一个消费者
代码:
1.配置文件
spring:
rabbitmq:
host: ip
port: 5672
username: username
password: password
virtual-host: test
2.生产者代码
@Test
public void basipushmessage(){
// 声明存入消息的队列
String queueName = "basicmessage";
// 发送消息
rabbitTemplate.convertAndSend(queueName, "hello basicMessage");
}
3.消费者代码
//监听器模式
@RabbitListener(queues = "basicmessage")
public void listenSimpleQueueMessage(String message){
System.out.println("spring 消费者接收到消息:【" + message + "】");
}
2.工作模式
说明:
1.一个生产者对应多个消费者
2.当消费者在消费信息的时候,生产者可能频繁的生产消息,消费者如果处理不过来,会导致消息挤压,无法及时处理,所以可以选择工作模式,由多个消费者进行消息处理
3.多个消费者绑定到一个队列,同一条消息只会被一个消费者处理
代码:
1.生产者生产消息
@Test
public void workquenePushmessage() throws InterruptedException {
// 队列名称
String queueName = "workquene";
// 消息
String message = "rabbitmq工作模式";
for (int i = 0; i < 50; i++) {
// 发送消息
rabbitTemplate.convertAndSend(queueName, message + i);
Thread.sleep(20);
}
}
2.消费者消费消息
@RabbitListener(queues = "workquene")
public void listenworkqueneQueueMessage(String message) throws InterruptedException {
System.out.println("spring 消费者1接收到消息:【" + message + "】");
Thread.sleep(20);
}
@RabbitListener(queues = "workquene")
public void listenworkqueneQueueMessage2(String message) throws InterruptedException {
System.out.println("spring 消费者2接收到消息:【" + message + "】");
Thread.sleep(200);
}
3.发布/订阅
说明:
1.在发布/订阅模式中,多了一个exchange交换机
2.exchange:交换机
- 接受生产者的消息
- 通过exchange进行不同的消息处理:
- Fanout:广播,将消息交给所有绑定到交换机的队列
- Direct:定向,把消息交给符合指定routing key 的队列
- Topic:通配符,把消息交给符合routing pattern(路由模式) 的队列
3.Exchange(交换机)只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与Exchange绑定,或者没有符合路由规则的队列,那么消息会丢失
3.1Fanout广播模式
代码:
1.生产者代码
@Test
public void fanoutMessage(){
// 队列名称
String exchangeName = "test.fanout";
// 消息
String message = "hello, fanout广播模式!";
rabbitTemplate.convertAndSend(exchangeName, "", message);
}
2.消费者代码
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "fanout.queue1"),
exchange = @Exchange(name = "test.fanout", type = ExchangeTypes.FANOUT)
))
public void listenFanoutQueue1(String msg) {
System.out.println("消费者1接收到Fanout消息:【" + msg + "】");
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "fanout.queue2"),
exchange = @Exchange(name = "test.fanout", type = ExchangeTypes.FANOUT)
))
public void listenFanoutQueue2(String msg) {
System.out.println("消费者2接收到Fanout消息:【" + msg + "】");
}
3.2direct定向模式
说明:
- 队列与交换机的绑定,不能是任意绑定了,而是要指定一个
RoutingKey
(路由key) -
消息的发送方在 向 Exchange发送消息时,也必须指定消息的
RoutingKey
。 -
Exchange不再把消息交给每一个绑定的队列,而是根据消息的
Routing Key
进行判断,只有队列的Routingkey
与消息的Routing key
完全一致,才会接收到消息
代码:
1.生产者代码
@Test
public void directMessage(){
// 队列名称
String exchangeName = "test.direct";
// 消息
String message = "hello, direct定向模式!";
rabbitTemplate.convertAndSend(exchangeName, "yellow", message);
}
2.消费者代码
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "direct.queue1"),
exchange = @Exchange(name = "test.direct", type = ExchangeTypes.DIRECT),
key = {"red", "blue"}
))
public void listenDirectQueue1(String msg){
System.out.println("消费者接收到direct.queue1的消息:【" + msg + "】");
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "direct.queue2"),
exchange = @Exchange(name = "test.direct", type = ExchangeTypes.DIRECT),
key = {"red", "yellow"}
))
public void listenDirectQueue2(String msg){
System.out.println("消费者接收到direct.queue2的消息:【" + msg + "】");
}
3.3通配符模式
说明:
#
:匹配一个或多个词
*
:匹配不多不少恰好1个词
Queue1:绑定的是china.#
,因此凡是以 china.
开头的routing key
都会被匹配到。包括china.news和china.weather
Queue2:绑定的是#.news
,因此凡是以 .news
结尾的 routing key
都会被匹配。包括china.news和japan.news
代码:
1.生产者代码
@Test
public void topicmessage(){
// 队列名称
String exchangeName = "test.topic";
// 消息
String message = "hello, topic通配符模式!";
rabbitTemplate.convertAndSend(exchangeName, "test.news", message);
}
2.消费者代码
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "topic.queue1"),
exchange = @Exchange(name = "test.topic", type = ExchangeTypes.TOPIC),
key = "test.#"
))
public void listentopicQueue1(String msg){
System.out.println("消费者接收到topic.queue1的消息:【" + msg + "】");
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "topic.queue2"),
exchange = @Exchange(name = "test.topic", type = ExchangeTypes.TOPIC),
key = "test.*"
))
public void listentopicQueue2(String msg){
System.out.println("消费者接收到topic.queue2的消息:【" + msg + "】");
}