部署
配置
POM 文件添加依赖
<!--rabbitmq-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
application.yml 添加配置
rabbitmq:
host: 192.168.140.0
port: 30006
username: admin
password: xxx123456
virtual-host: /
WORK 模型
消息只能有一个被消费,会造成消息竞争
controller
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RabbitMqController {
@Autowired
private RabbitTemplate rabbitTemplate;
@RequestMapping("/rabbitmq/sendWork")
public Object sendWork() {
for (int i = 0; i < 10; i++) {
rabbitTemplate.convertAndSend("queue_work", "obj-" + i);
}
return "发送成功...";
}
}
监听者
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class RabbitMqConsumer {
// 创建队列 queue_work
@Bean
public Queue queueWork() {
return new Queue("queue_work");
}
// 创建监听者,监听 queue_work 队列
@RabbitListener(queues = "queue_work")
public void receiveMessage1(String msg, Channel channel, Message message) {
log.info("1---- msg:{}, channel:{}, message:{}", msg, channel, message);
}
// 创建监听者,监听 queue_work 队列
@RabbitListener(queues = "queue_work")
public void receiveMessage2(Object obj, Channel channel, Message message) {
log.info("2---- obj:{}, channel:{}, message:{}", obj, channel, message);
}
}
发布订阅模式
生产者将消息给交换机,交换机根据自身的类型(fanout)将会把所有消息复制同步到所有与其绑定的队列,每个队列可以有一个消费者接收消息进行消费逻辑
controller
使用 convertSendAndReceive 方法时的结果:按照一定的顺序,只有确定消费者接收到消息,才会发送下一条信息,每条消息之间会有间隔时间
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RabbitMqController {
@Autowired
private RabbitTemplate rabbitTemplate;
@RequestMapping("/rabbitmq/sendPublish")
public String sendPublish() {
for (int i = 0; i < 100; i++) {
//rabbitTemplate.convertAndSend("exchange_fanout", "", "测试发布订阅模型:" + i);
rabbitTemplate.convertSendAndReceive("exchange_fanout", "", "测试发布订阅模型:" + i);
}
return "发送成功...";
}
监听者
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class RabbitMqConsumer {
// 创建队列 queue_fanout1
@Bean
public Queue queueFanout1() {
return new Queue("queue_fanout1");
}
// 创建队列 queue_fanout2
@Bean
public Queue queueFanout2() {
return new Queue("queue_fanout2");
}
// 创建交换机 exchange_fanout
@Bean
public FanoutExchange exchangeFanout() {
return new FanoutExchange("exchange_fanout");
}
// 把交换机 exchange_fanout 和队列 queue_fanout1 绑定
@Bean
public Binding bindingExchange1() {
return BindingBuilder.bind(queueFanout1()).to(exchangeFanout());
}
// 把交换机 exchange_fanout 和队列 queue_fanout2 绑定
@Bean
public Binding bindingExchange2() {
return BindingBuilder.bind(queueFanout2()).to(exchangeFanout());
}
// 监听队列 queue_fanout1
@RabbitListener(queues = "queue_fanout1")
public void receiveMsg1(String msg) {
System.out.println("队列1接收到消息:" + msg);
}
// 监听队列 queue_fanout2
@RabbitListener(queues = "queue_fanout2")
public void receiveMsg2(String msg) {
System.out.println("队列2接收到消息:" + msg);
}
}
TOPIC 模式
生产者发送消息,消息中带有具体的路由 key,交换机的类型是 topic,队列绑定交换机不在使用具体的路由key而是一个范围值
其中 * 表示一个字符串(不能携带特殊字符)#表示任意
controller
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RabbitMqController {
@Autowired
private RabbitTemplate rabbitTemplate;
@RequestMapping("/rabbitmq/sendTopic")
public String sendTopic() {
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
rabbitTemplate.convertAndSend("exchange_topic", "topic.fat.topic", "测试发布订阅模型:" + i);
} else {
rabbitTemplate.convertAndSend("exchange_topic", "topic.fat", "测试发布订阅模型:" + i);
}
}
return "发送成功...";
}
}
监听者
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class RabbitMqConsumer {
// 创建队列1
@Bean
public Queue queueTopic1() {
return new Queue("queue_topic1");
}
// 创建队列2
@Bean
public Queue queueTopic2() {
return new Queue("queue_topic2");
}
// 创建交换机 exchange_topic
@Bean
public TopicExchange exchangeTopic() {
return new TopicExchange("exchange_topic");
}
// 绑定交换机和队列1,并设置队列1的 topic 匹配范围
@Bean
public Binding bindingTopic1() {
return BindingBuilder.bind(queueTopic1()).to(exchangeTopic()).with("topic.#");
}
// 绑定交换机和队列2,并设置队列2的 topic 匹配范围
@Bean
public Binding bindingTopic2() {
return BindingBuilder.bind(queueTopic2()).to(exchangeTopic()).with("topic.*");
}
// 监听队列1
@RabbitListener(queues = "queue_topic1")
public void receiveMsgTopic1(String msg) {
System.out.println("消费者1接收到:" + msg);
}
// 监听队列2
@RabbitListener(queues = "queue_topic2")
public void receiveMsgTopic2(String msg) {
System.out.println("消费者2接收到:" + msg);
}
}