1.异步发送
http://activemq.apache.org/async-sends
ActiveMQ支持以同步或异步模式将消息发送到代理。使用的模式对发送呼叫的延迟有很大的影响。由于延迟通常是生产者可以实现的吞吐量的重要因素,因此使用异步发送可以显着提高系统的性能。
好消息是,在某些情况下,ActiveMQ默认情况下以异步模式发送消息。只有在JMS规范要求使用同步发送的情况下,我们才默认使用同步发送。我们被迫以同步模式发送的情况是在事务外部发送持久性消息时。
如果您没有使用事务并正在发送持久消息,则每次发送都将同步并阻塞,直到代理将已将消息安全地持久保存到磁盘的确认发送回生产者为止。此ack保证了消息不会丢失,但是由于客户端被阻止,因此还付出了巨大的等待时间。
许多高性能应用程序旨在承受故障情况下的少量消息丢失。如果您的应用程序是按照这种方式设计的,则即使使用持久性消息,也可以启用异步发送来提高吞吐量。
异步发送怎么确认消息不丢失?
设置异步发送配置后,回调
2.延时投递和定时投递
http://activemq.apache.org/delay-and-schedule-message-delivery
5.4版的ActiveMQ在ActiveMQ消息代理中内置了一个可选的持久性调度程序。通过在“ Xml配置”中将broker schedulerSupport属性设置为true 可以启用此功能。ActiveMQ客户端可以通过使用以下消息属性来利用延迟传递:
属性名称 | 类型 | 描述 |
---|---|---|
AMQ_SCHEDULED_DELAY | 长 | 在代理计划将消息传递之前,消息将等待的时间(以毫秒为单位) |
AMQ_SCHEDULED_PERIOD | 长 | 在开始时间之后再等待调度消息之前要等待的毫秒数 |
AMQ_SCHEDULED_REPEAT | 整型 | 重复安排邮件传递的次数 |
AMQ_SCHEDULED_CRON | 串 | 使用Cron条目设置时间表 |
为了使Java JMS客户端方便,在org.apache.activemq.ScheduledMessage上有一个带有用于调度的属性名称的接口。
例如,要安排在60秒内发送邮件-您需要设置AMQ_SCHEDULED_DELAY属性:
MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("test msg");
long time = 60 * 1000;
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, time);
producer.send(message);
您可以设置一条消息以等待初始延迟,然后重复发送10次,每次重新发送之间等待10秒:
MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("test msg");
long delay = 30 * 1000;
long period = 10 * 1000;
int repeat = 9;
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay);
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, period);
message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, repeat);
producer.send(message);
您还可以使用CRON安排邮件的时间,例如,如果希望将邮件安排为每小时发送一次,则需要将CRON条目设置为0 * * * *
--例如
MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("test msg");
message.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_CRON, "0 * * * *");
producer.send(message);
CRON调度优先于使用消息延迟-但是,如果为CRON条目设置了重复和周期,则ActiveMQ调度程序将在每次CRON条目触发时调度消息的传递。用一个例子更容易解释。假设您希望传递一条消息10次,每条消息之间有一秒钟的延迟-并且您希望每小时进行一次-您可以这样做:
MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("test msg");
message.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_CRON, "0 * * * *");
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 1000);
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, 1000);
message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, 9);
producer.send(message);
消息重发机制
http://activemq.apache.org/redelivery-policy
死信队列
可用属性
属性 | 默认值 | 描述 |
---|---|---|
backOffMultiplier | 5 | 后退乘数。 |
collisionAvoidanceFactor | 0.15 | 避免碰撞的范围百分比(如果启用)。 |
initialRedeliveryDelay | 1000L | 初始重新交付延迟(以毫秒为单位)。 |
maximumRedeliveries | 6 | 设置在将邮件视为中毒药丸并返回给代理之前,该邮件将被重新发送的最大次数,这样它就可以进入“死信队列”。设置-1 为无限交付。 |
maximumRedeliveryDelay | -1 | 设置如果useExponentialBackOff 设置了该选项,将应用的最大传送延迟 。(使用值 -1 定义不应用最大值)(v5.5)。 |
redeliveryDelay | 1000L | 交付延迟时间为 initialRedeliveryDelay=0 (v5.4)。 |
useCollisionAvoidance | false | 重新交付策略是否应使用冲突避免。 |
useExponentialBackOff | false | 应该使用指数补偿,即以指数方式增加超时。 |
每个目的地的RedeliveryPolicy
从ActiveMQ v5.7.0开始,您现在可以基于每个目标配置RedeliveryPolicy。ActiveMQConnection
现在, 工厂类公开了RedeliveryPolicyMap属性,该属性允许使用命名目标或目标通配符来分配RedeliveryPolicy。下面的代码片段显示了如何为主题和队列配置不同的RedeliveryPolicy。
ActiveMQConnection connection ... // Create a connection
RedeliveryPolicy queuePolicy = new RedeliveryPolicy();
queuePolicy.setInitialRedeliveryDelay(0);
queuePolicy.setRedeliveryDelay(1000);
queuePolicy.setUseExponentialBackOff(false);
queuePolicy.setMaximumRedeliveries(2);
RedeliveryPolicy topicPolicy = new RedeliveryPolicy();
topicPolicy.setInitialRedeliveryDelay(0);
topicPolicy.setRedeliveryDelay(1000);
topicPolicy.setUseExponentialBackOff(false);
topicPolicy.setMaximumRedeliveries(3);
// Receive a message with the JMS API
RedeliveryPolicyMap map = connection.getRedeliveryPolicyMap();
map.put(new ActiveMQTopic(">"), topicPolicy);
map.put(new ActiveMQQueue(">"), queuePolicy);
spring整合
死信队列
http://activemq.apache.org/message-redelivery-and-dlq-handling
各自独立的死信队列
ActiveMQ中的默认死信队列称为ActiveMQ.DLQ
;所有无法传递的消息都将发送到此队列,这可能很难管理。因此,您可以individualDeadLetterStrategy
在activemq.xml
配置文件的目标策略映射中设置一个 ,它允许您为给定队列或主题指定特定的死信队列前缀。您可以根据需要使用通配符来应用此策略,以便所有队列都具有自己的死信队列,如下例所示。
<broker>
<destinationPolicy>
<policyMap>
<policyEntries>
<!-- Set the following policy on all queues using the '>' wildcard -->
<policyEntry queue=">">
<deadLetterStrategy>
<!--
Use the prefix 'DLQ.' for the destination name, and make
the DLQ a queue rather than a topic
-->
<individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true"/>
</deadLetterStrategy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
</broker>
自动删除过期消息
有些人只需要将过期的消息丢弃而不是发送到DLQ,即完全跳过DLQ。这简化了DLQ的管理,因此您无需筛选大量已过期的邮件来查找存在实际问题的邮件。要告诉ActiveMQ仅丢弃过期的消息,请processExpired
在死信策略中将该属性配置为false:
<broker>
<destinationPolicy>
<policyMap>
<policyEntries>
<!-- Set the following policy on all queues using the '>' wildcard -->
<policyEntry queue=">">
<!--
Tell the dead letter strategy not to process expired messages
so that they will just be discarded instead of being sent to
the DLQ
-->
<deadLetterStrategy>
<sharedDeadLetterStrategy processExpired="false" />
</deadLetterStrategy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
</broker>
将非持久性消息放入死信队列
默认情况下,ActiveMQ不会将无法传递的非持久消息放置在死信队列中。此行为的基本原理是,如果应用程序不太在乎消息的持久性,那么记录消息无法传递就没有任何价值。如果确实要将非持久消息放在死信队列中,则应设置processNonPersistent="true"
死信策略。
<broker>
<destinationPolicy>
<policyMap>
<policyEntries>
<!-- Set the following policy on all queues using the '>' wildcard -->
<policyEntry queue=">">
<!--
Tell the dead letter strategy to also place non-persisted messages
onto the dead-letter queue if they can't be delivered.
-->
<deadLetterStrategy>
<sharedDeadLetterStrategy processNonPersistent="true" />
</deadLetterStrategy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
</broker>