1. springboot框架中activemq手动连接处理
2. activemq事务性分析
记录一个最近使用activemq的使用总结,场景是activemq异步处理一个高访问量的接口,不能实时入库,而改用定时处理消息,隔断时间触发处理。
- 手动建立MQ连接
上图已经对activemq进行过实体配置了,因此,下面部分代码,是直接取用的ActiveMQConnectionFactory工厂,也可以再次使用用户名密码,建立连接,这里不贴代码了,网上一搜一大堆
/**直接引用 ActiveMQConnectionFactory工厂建立连接**/
@Autowired
private ActiveMQConnectionFactory activeMQConnectionFactory;
public void receiveQueue(){
Connection connection = null;
Session session = null;
try {
// 通过工厂创建一个连接
connection = activeMQConnectionFactory.createConnection();
// 启动连接
connection.start();
// 创建一个session会话
session = connection.createSession(Boolean.TRUE, Session.CLIENT_ACKNOWLEDGE);
// 创建一个消息队列(你自己的)
Destination destination = session.createQueue(ActiceMqConstant.COMMODITY_ACTION_DATA_COLLECT);
// 创建消费者
MessageConsumer consumer = session.createConsumer(destination);
//读取队列中的消息,直至结束
while (true) {
//队列中的消息读完之后,break退出循环
Message receive = consumer.receive();
if (receive == null) {
break;
}
TextMessage textMessage = (TextMessage) receive;
if (textMessage == null) {
break;
}
String msg = textMessage.getText();
JSONObject jsonObject = JSONObject.parseObject(msg);
// 告诉MQ这调消息已经消费
textMessage.acknowledge();
//session回话提交通知 ps:session不存在事务统一提交,需要逐条进行提交,这里等下分析
session.commit();
}
} catch (JMSException e) {
//消息重发
session.recover();
e.printStackTrace();
} finally {
if (connection != null) {
try {
//关闭连接,会话
connection.close();
session.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
-
activemq事务性分析
在自己测验中发现,activemq的事务是针对单条消息而言,而不是一个队列中的所有消息。包括官网给出的调用session的commit提交事务,调用rollback进行事务回滚的方法。
session.rollback()回滚,与session.recover()最终效果是一样的,都是让当前处理的这条消息回归队列,进行消息重发。话不多说上图:
在处理到第四条消息时,这里手动抛出的Exception异常,捕捉后,进行进行了session.rollback()操作
这里打印输出了四个消息,然而队列中显示却只是消费了三个
继续消费,发现第一个消费的消息,就是上图最后一个打印的消息,也就是说在第四个消息打印后,抛出了异常后,进行的回滚操作,将最后一条消息回滚会了队列中,等待重发
PS:
以下是使用@JmsListener MQ监听的测试方法截图,同样,Session.rollback将当前条消息进行队列回滚,等待下次重发,并跳过当前消息,继续分发下一条消息。
这里要说明的是session.rollback()与session.recover()达到的效果是一样的,而MQ的事务性呢,只是针对单条消息而言的,而不是整个队列的消息。