ActiveMQ----->如何保证消息可靠性
作者:互联网
一 持久化
1.1 API设置
java
默认是持久化的
1.2 Topic持久化
默认
情况下,topic发布时,如果订阅者不在线。消息就会丢失
但我们可以用持久化Topic来解决这个问题。
先启动订阅在启动生产
生产者
package com.ww.activemqdemo.consumer;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
/**
* @ClassName JmsProduce
* @Description TODO
* @Author DuanYueFeng
* @Version 1.0
**/
public class JmsProduce_Topic_p {
public static final String URL = "tcp://192.168.196.4:61616";
public static final String topic_name = "topic_p";
public static void main(String[] args) throws JMSException {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(URL);
Connection connection = factory.createConnection();
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic(topic_name);
MessageProducer producer = session.createProducer(topic);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
connection.start();//start放后面
for (int i = 1; i <=3; i++) {
TextMessage textMessage = session.createTextMessage("Topic mag..." + i);
producer.send(textMessage);
}
producer.close();
session.close();
connection.close();
System.out.println("完成....");
}
}
订阅者
package com.ww.activemqdemo.consumer;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.io.IOException;
/**
* @ClassName JmsConsumer
* @Description TODO
* @Author DuanYueFeng
* @Version 1.0
**/
public class JmsConsumer_Topic_p {
public static final String URL = "tcp://192.168.196.4:61616";
public static final String topic_name = "topic_p";
public static void main(String[] args) throws JMSException, IOException, InterruptedException {
System.out.println("我是3号消费者。。。");
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(URL);
Connection connection = factory.createConnection();
connection.setClientID("z3");//订阅者的客户端id
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic(topic_name);
TopicSubscriber durableSubscriber = session.createDurableSubscriber(topic, "remark..");//后面是订阅者的名称
connection.start();//start也要延后
Message message = durableSubscriber.receive();
while (null!=message){
TextMessage textMessage = (TextMessage)message;
System.out.println("收到的持久化:"+textMessage.getText());
message = durableSubscriber.receive(1000L);
}
System.in.read();
// Thread.sleep(1000);
session.close();
connection.close();
System.out.println("完成....");
}
}
二 事务
事务偏生产者
2.1 生产者事务
事务的配置优先度高于应答模式(签收)
//第一个参数是是否创建session,第二个参数表示应答模式
Session session = connection.createSession(true,Session.AUTO_ACKNOWLEDGE);
不开启事务时
只要执行send就进入到队列中
开启事务后
需要在最后使用session.commit();
,某一条异常也可以用session.rollback();
2.2 消费者事务
不开启事务时
消息拿到就算作被消费了
开启事务时
没有commit
,消息就不会算作被消费。会有重复消费的
可能
三 签收
签收偏消费者
3.1 非事务模式
自动签收(默认)
Session.AUTO_ACKNOWLEDGE
手动签收
Session.CLIENT_ACKNOWLEDGE
客户端调用acknowledge
方法手动签收
允许重复消息
Session.DUPS_OK_ACKNOWLEDGE
消息可重复确认,意思是此模式下,可能会出现重复消息,并不是一条消息需要发送多次ACK才行。它是一种潜在的"AUTO_ACK"确认机制,为批量确认而生,而且具有“延迟”确认的特点。对于开发者而言,这种模式下的代码结构和AUTO_ACKNOWLEDGE一样,不需要像CLIENT_ACKNOWLEDGE那样调用acknowledge()方法来确认消息。
3.2 事务模式下
消费者事务开启,只有commit后才能将全部消息变为已消费,写ack没有作用,即使写了签收也不会签收出队
3.3 和事务的联系
在事务性会话中,当一个事务被成功提交则消息被自动签收。如果事务回滚,则消息会被再次传送
非事务会话中,消息何时被确认取决于创建会话时的应答模式(acknowledgement)
总结:在ActiveMQ保证消息可靠性的四种方式
1)进行消息的持久化:queue默认为持久化,topic模式下需要手动设置
2)开启消息的事务
3)在消费者的非事务状态下要开启消息手动签收功能
4)集群搭建实现高可用
标签:事务,可靠性,Session,签收,topic,connection,session,-----,ActiveMQ 来源: https://blog.csdn.net/m0_46405589/article/details/115078495