119 lines
8.1 KiB
XML
119 lines
8.1 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!-- ============================================================================= -->
|
||
<!-- Copyright © 2009 Red Hat, Inc. and others. -->
|
||
<!-- -->
|
||
<!-- The text of and illustrations in this document are licensed by Red Hat under -->
|
||
<!-- a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). -->
|
||
<!-- -->
|
||
<!-- An explanation of CC-BY-SA is available at -->
|
||
<!-- -->
|
||
<!-- http://creativecommons.org/licenses/by-sa/3.0/. -->
|
||
<!-- -->
|
||
<!-- In accordance with CC-BY-SA, if you distribute this document or an adaptation -->
|
||
<!-- of it, you must provide the URL for the original version. -->
|
||
<!-- -->
|
||
<!-- Red Hat, as the licensor of this document, waives the right to enforce, -->
|
||
<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent -->
|
||
<!-- permitted by applicable law. -->
|
||
<!-- ============================================================================= -->
|
||
<chapter id="undelivered-messages">
|
||
<title>消息再传递及未传递的消息</title>
|
||
<para>消息有可能传递失败(比如相关的事务发生回滚)。失败的消息将退回到队列中准备重新传递。这样就会出现
|
||
一种情况,就是同一个消息会被反复的传递而总不成功,以至于使系统处于忙的状态。</para>
|
||
<para>对于这样的消息我们有两种处理方法:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>延迟再传递</para>
|
||
<para>这种方法是让消息再次传递时有一定的时间延迟,这样客户端就有机会从故障中恢复,同时网络连接和CPU资源
|
||
也不致于被过度占用。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>死信(Dead Letter)地址</para>
|
||
<para>这种方法是规定一个死信地址,如果消息再被反复传递达到一定次数时,就会从原有队列中删除,转到这个
|
||
死信地址中。这样消息就不会永远地重复传递了。</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<para>以上两种方法可以合理搭配使用,使解决方案更加灵活。</para>
|
||
<section>
|
||
<title>延迟再传递</title>
|
||
<para>延迟再传递对于时常出现故障或回滚的客户端十分有用。如果没有延迟,整个系统可能会处于一种”疯狂“的状态。
|
||
就是消息被传递、回滚、再传递,这样反复不间断地进行着,将宝贵的CPU和网络资源占用。</para>
|
||
<section id="undelivered-messages.delay">
|
||
<title>延迟再传递的配置</title>
|
||
<para>延迟再传递的配置在地址设定内(address-setting):</para>
|
||
<programlisting>
|
||
<!-- delay redelivery of messages for 5s -->
|
||
<address-setting match="jms.queue.exampleQueue">
|
||
<redelivery-delay>5000</redelivery-delay>
|
||
</address-setting>
|
||
</programlisting>
|
||
<para>如果定义了<literal>redelivery-delay</literal>,ActiveMQ在再传递之前等待所定义的时间。</para>
|
||
<para>默认是没有延时的(即<literal>redelivery-delay</literal>的值是0)。</para>
|
||
<para>可以使用通配符为一组地址定义再传递的延迟(参见<xref linkend="wildcard-syntax"/>)。
|
||
</para>
|
||
</section>
|
||
<section>
|
||
<title>例子</title>
|
||
<para>参见 <xref linkend="examples.delayed-redelivery"/>。这是一个JMS应用中配置延迟再传递的例子。</para>
|
||
</section>
|
||
</section>
|
||
<section>
|
||
<title>死信地址</title>
|
||
<para>通过定义一个<emphasis role="italic">死信地址</emphasis>也可以防止同一个消息被无休止地传递:
|
||
当一个消息被重复传递一定次数后,就会从队列中删除并传递到定义好的死信地址中。</para>
|
||
<para>这些死信中的消息之后可以转发到某个队列中,以供系统管理员分析处理。</para>
|
||
<para>每个ActiveMQ的地址可以有一个死信地址。当一个消息被反复传递达一定次数时,它就会被从队列中删除并送到
|
||
死信地址。这些<emphasis>死信</emphasis>消息可以被接收进行分析处理。</para>
|
||
<section id="undelivered-messages.configuring">
|
||
<title>配置死信地址</title>
|
||
<para>死信地址定义在地址设定中(address-setting):</para>
|
||
<programlisting>
|
||
<!-- undelivered messages in exampleQueue will be sent to the dead letter address
|
||
deadLetterQueue after 3 unsuccessful delivery attempts
|
||
-->
|
||
<address-setting match="jms.queue.exampleQueue">
|
||
<dead-letter-address>jms.queue.deadLetterQueue</dead-letter-address>
|
||
<max-delivery-attempts>3</max-delivery-attempts>
|
||
</address-setting>
|
||
</programlisting>
|
||
<para>如果没有定义<literal>dead-letter-address</literal>,消息在经过
|
||
<literal>max-delivery-attempts</literal>次重复传递后被删除。</para>
|
||
<para>默认的重复传递次数为10。将<literal>max-delivery-attempts</literal>设定为-1
|
||
表示无限次重复传递。</para>
|
||
<para>例如,对一组地址设置了一个通用的死信地址后,再将其中某个地址的<literal>max-delivery-attempts</literal>
|
||
设定为-1时,那么只有这个地址的再传递次数是无限的。</para>
|
||
<para>可以使用通配符对一组地址设定死信地址(参见<xref linkend="wildcard-syntax"/>)。</para>
|
||
</section>
|
||
<section>
|
||
<title>死信的属性</title>
|
||
<para>从死信地址接收到的消息有以下属性:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>_HQ_ORIG_ADDRESS</literal></para>
|
||
<para>这是一个字符串属性,它是该死信消息的<emphasis>原始地址</emphasis>。</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
<section>
|
||
<title>例子</title>
|
||
<para>参见<xref linkend="examples.dead-letter"/>。这个例子给出了在JMS应用中死信的配置与使用。</para>
|
||
</section>
|
||
</section>
|
||
<section id="configuring.delivery.count.persistence">
|
||
<title>传递计数的持久化</title>
|
||
<para>通常情况下ActiveMQ在一个消息被回滚之前并不更新持久的传递计数(即在消息传递到接收者之前不会更新传递计数)。
|
||
大多数情况下消息被接收、通知、然后被忘掉。这样对<emphasis>每一个消息</emphasis>的传递都要更新一次持久的
|
||
传递计数,会显著降低系统的性能。</para>
|
||
<para>介是如果在消息传递之前不进行持久传递计数的更新,服务器一旦发生故障而崩溃,就会造成消息可能被传递出去而传递
|
||
计数却没有正确反映出传递的結果。在恢复阶段,服务器将错误地将该消息的<literal>redelivered</literal>设为
|
||
<literal>false</literal>而不是<literal>true</literal>。 </para>
|
||
<para>这样是不符合严格的JMS要求的。因此ActiveMQ允许在消息传递前更新传递计数。但是默认不这样做,目的是优先考虑
|
||
了它对性能的影响。</para>
|
||
<para>要想打开传递计数更新功能,将<literal>activemq-configuration.xml</literal>文件中的
|
||
<literal>persist-delivery-count-before-delivery</literal>设为<literal>true</literal>即可:</para>
|
||
<programlisting>
|
||
<persist-delivery-count-before-delivery>true</persist-delivery-count-before-delivery>
|
||
</programlisting>
|
||
</section>
|
||
</chapter>
|