ActiveMQ(一) -- 基础
MQ的作用
削峰:如秒杀业务在某一段时间访问量剧增,导致服务器压力过大。使用了MQ后,服务接收到请求发送到mq,然后直接结束。
解耦:A服务需要调用B和C服务,哪天新增了D服务,则A服务还需要改动,这样很麻烦。使用MQ,则A服务只需要把请求发给MQ, BCD服务订阅A服务的请求即可。
异步:A需要调用B、C、D服务都是50毫秒, 但B调B1需要2秒,最后A的调用时间也超过了2秒。使用MQ则A发请求给MQ然后就结束了,返回时间50毫秒左右。
消息消费方式
阻塞式:MessageConsumer.receive() 方法阻塞接收,receive方法在能接收到消息之前(或超时之前)将一直阻塞。
MessageConsumer consumer = session.createConsumer(queue); while (true) { // reveive() 一直等待接收消息,在能够接收到消息之前将一直阻塞。是同步阻塞方式 。 TextMessage textMessage = (TextMessage) consumer.receive(); if (textMessage != null) { System.out.println("消费者收到的消息:" + textMessage.getText()); } else { break; } }
异步非阻塞方式:MessageConsumer.setMessageListener()监听,当消息到达之后,系统会自动调用监听器MessageListener的onMessage(Message message)方法。
MessageConsumer consumer = session.createConsumer(queue); /* 通过监听的方式来消费消息,是异步非阻塞的方式消费消息。 通过messageConsumer 的setMessageListener 注册一个监听器,当有消息发送来时,系统自动调用MessageListener 的 onMessage 方法处理消息 */ consumer.setMessageListener(new javax.jms.MessageListener() { public void onMessage(Message message) { // instanceof 判断是否A对象是否是B类的子类 if (message != null && message instanceof TextMessage) { TextMessage textMessage = (TextMessage) message; try { System.out.println("消费者的消息:" + textMessage.getText()); } catch (JMSException e) { e.printStackTrace(); } } } });
Queue队列消息传递特点
1. 消息生产者和消费者一对一
2. 生产者和消费者无关联,生产者生产完消息发给mq即可,不需要关注消息是否消费。消费者有消息直接消费即可,不需要关注生产者是否正常。
3. 消息消费后不再存储
Topic发布订阅消息
1. 生产者和订阅者是1对N的关系
2. 生产者和订阅者是有强关联的,订阅者不能订阅开启之前的消息。
3. 生产者生产的消息如果没有订阅者,将是一条废弃的消息。所以一般打开订阅者再开始生产消息。
Queue和Topic区别
参考:https://blog.csdn.net/qq_42372017/article/details/109686719?spm=1001.2014.3001.5501