activemq使用
[toc]
1.延迟处理
需要修改activeMq的服务器中的conf/activemq.xml的配置
<broker xmlns="http://activemq.apache.org/schema/core" schedulerSupport="true" brokerName="localhost" dataDirectory="${activemq.data}">
2. 确认机制,可以手工确认
prefetchSize暂时为1,optimizeACK不开启, 确认模式:CLIENT_ACKNOWLEDGE= 2 客户端手动确认 确认类型: STANDARD_ACK_TYPE = 2 标准类型(成功确认) REDELIVERED_ACK_TYPE = 3 消息需"重发",需配合重试设置
consumer的session必须是配置acknowledege producer的session无需设置
如果是多个consumer,使用不同的session
当前可以确认:
不同consumer如果使用同一个session(配置手动确认),不会重新接收到该条消息。
不同consumer如果使用不同session(配置手动确认),可以重新接收到该条消息,并可以手工确认。
不同consumer使用的session(没有配置手工确认),接收到没有被手工确认的消息会以自动确认接受
待解决的问题:
不同consumer 接受消息之间的时间间隔如果设置,从而确保消息不会被多次消费
【备注1】一个tomcat容器在spring中如果没有配置使用同一个jmsSession,在多listerner的情况下会出现上述问题
【备注2】在多个tomcat容器共享队列中,不同容器之间的listerner会导致出现上述
3. 持久化
配置文件中
<persistenceAdapter>
<kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>
程序是决定是否持久化的根本
@Test
public void persistent() throws JMSException {
//消息生产者
MessageProducer producer=session.createProducer(destination);
TextMessage message=session.createTextMessage("测试手动确认");
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
producer.send(message);
System.out.println("消息发送成功");
}
- 程序不配置任何的DeliveryMode(配送模式)
- activemq.xml中配置persistenceAdapter -----> 持久化
- kill 之后,重启,数据没有丢失
- stop之后,重启,数据没有丢失
- activemq.xml中无persistenceAdapter配置 ---> 不持久化
- restart 数据丢失
- 程序配置DeliveryMode为PERSISTENT (producer.setDeliveryMode(DeliveryMode.PERSISTENT);) 持久化
- activemq.xml中配置persistenceAdapter -----> 持久化
- activemq.xml中无persistenceAdapter配置 ---> 持久化
- 程序配置DeliveryMode为NON_PERSISTENT (producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);)
- activemq.xml中配置persistenceAdapter -----> 不持久化
- restart 数据丢失
- activemq.xml中无persistenceAdapter配置 ---> 不持久化
- restart 数据丢失
设置activemq.xml中的broker为:
<broker xmlns="http://activemq.apache.org/schema/core" schedulerSupport="true" persistent="false" brokerName="localhost" dataDirectory="${activemq.data}">
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
restart 数据丢失
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
restart 数据丢失
3.1 处理持久化机制,采用storeCursor,处理设置阀值---内存大小
4.死信
如果不做任何说明,是不会启用死信队列的,测试了重试12次,依然
下面测试需要增加死信的配置
@Before
public void deathInit() throws JMSException {
RedeliveryPolicy queuePolicy=((ActiveMQConnection)connection).getRedeliveryPolicy();
//设置默认的重发,之间的时间间隔,这个有望解决我代码中对于acknowledegement的问题,这块默认的时间是1s(1000ms)
queuePolicy.setInitialRedeliveryDelay(0);
// 设置重发延迟时间,如果InitialRedeliveryDelay=0,即生效
queuePolicy.setRedeliveryDelay(2000);
// 指数退避算法的 乘数
queuePolicy.setBackOffMultiplier(5);
// 是否启用指数退避算法 -指数增加超时时间
queuePolicy.setUseExponentialBackOff(false);
//设置最大的重试次数
queuePolicy.setMaximumRedeliveries(2);
connection=factory.createConnection();
connection.start();
//创建会话
session=connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
//创建队列
destination=session.createQueue("TestLater");
}
重试多次,仍然没有生效
然后在代码中增加
session.recover();
方才出现死信队列,即在正常情况下是不存在死信队列的。
在这里配置的RedeliveryPolicy ,在不同session中,仍然在第一时间收到
不过这里设置的那个重试次数有效了,当重试2次就会放入死信队列中