应用场景
点对点式:消息发送到队列,只要消息被接收者获取,就移除队列,其他接收者再获取不到这个消息
发布式:消息发送到主题,谁订阅了,那么所有的消息都可以接收,不会出现已读消息的清除
RabbitMQ
运行机制
安装
安装带web管理界面的rabbitmq
下载镜像
[root@localhost ~]# docker pull rabbitmq:3-management
运行
[root@localhost ~]# docker run -d -p 5672:5672 -p 15672:15672 --name myrabbitmq 95bc78c8d15d
5672是客户端和MQ通信的端口,15672是访问web管理界面的端口
访问web管理界面
用户密码都是guest
导入依赖
通过web管理页面绑定路由规则
创建交换器
添加消息队列
队列与交换器关联绑定
配置连接rabbitmq
spring.rabbitmq.host=x.x.x.x
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
#spring.rabbitmq.virtual-host=/
#端口默认5672
#spring.rabbitmq.port=5672
测试单播:点对点
@SpringBootTest
class Springboot02AmqpApplicationTests {
@Autowired
RabbitTemplate rabbitTemplate;
@Test
void contextLoads() {
Map<String, Object> map = new HashMap<>();
map.put("msg", "第一个消息");
map.put("data", Arrays.asList("hello", 123, true));
//对象默认当成消息体,只需要传入要发送的对象,自动序列化发送给rabbitmq
//对象被默认序列化后发送出去
rabbitTemplate.convertAndSend("exchange.direct", "atguigu.news", new Book("西游记","吴承恩"));
}
//获取消息
@Test
public void receive(){
Object o = rabbitTemplate.receiveAndConvert("atguigu.news");
System.out.println(o.getClass());
System.out.println(o);
}
//广播
@Test
public void sendMsg(){
rabbitTemplate.convertAndSend("exchange.fanout", "", new Book("三国演义", "罗贯中"));
}
}
由于消息默认会使用java序列化工具进行转换,然后发送出去,消息不易阅读
自定义将消息转换成json数据发送出去
@Configuration
public class MyAmqpConfig {
//自定义将数据转换为json发送出去
@Bean
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
}
这样消息就会以json的形式存在于队列
应用场景
开启监听
监听某个消息队列
还可以通过Message获取消息头信息
编码创建交换器等
@Test
public void createExchange(){
//创建交换器
// amqpAdmin.declareExchange(new DirectExchange("amqpadmin.exchange"));
// System.out.println("创建完成");
//创建队列
// amqpAdmin.declareQueue(new Queue("amqpadmin.queue", true));
//创建绑定规则
amqpAdmin.declareBinding(new Binding("amqpadmin.queue", Binding.DestinationType.QUEUE,
"amqpadmin.exchange", "amqp.haha", null));
}