activemq-artemis/docs/user-manual/zh/send-guarantees.xml

103 lines
9.2 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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 AttributionShare 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="send-guarantees">
<title>发送与提交的保证</title>
<section>
<title>事务保证</title>
<para>在提交或回滚事务时HornetQ将提交或回滚的请求发送到服务器客户端阻塞等待服务器的响应。</para>
<para>当服务器端收到提交或回滚的请求时它将事务信息记录到日志journal中。然后向客户端发回
响应。参数<literal>journal-sync-transactional</literal>控制着如何向客户端发回响应。
如果它的值是<literal>false</literal>,服务器向客户端发回响应时事务的处理結果不一定已经被
保存到磁盘中。可能会在之后的某个时间保存。如果期间服务器发生故障那么事务的处理信息可能丢失。
当它的值是<literal>true</literal>时,服务器将保证在向客户端发回响应时,事务的处理信息
已经被保存到了磁盘中。默认值是<literal>true</literal></para>
<para>显然将这个参数设为<literal>false</literal>可以提高性能,但是要以牺牲事务的持久性为代价。</para>
<para>这个参数在 <literal>hornetq-configuration.xml</literal>文件中。</para>
</section>
<section id="non-transactional-sends">
<title>非事务性消息发送的保证</title>
<para>使用非事务性会话发送消息时经过适当配置HornetQ客户端在发送后以阻塞的方式等待直到确认发出
的消息已经到达服务器后再返回。可以对持久化或非持久化的消息分别配置,具体参数如下:</para>
<itemizedlist>
<listitem>
<para><literal>BlockOnDurableSend</literal>。如果设为<literal>true</literal>则通过
非事务性会话发送持久消息时,每次发送都将阻塞直到消息到达服务器并返回通知为止。默认值是
<literal>true</literal>
</para>
</listitem>
<listitem>
<para><literal>BlockOnNonDurableSend</literal>。如果设为<literal>true</literal>
则通过非事务性会话发送非持久消息时,每次发送都将阻塞直到消息到达服务器并返回通知为止。默认值是
<literal>false</literal></para>
</listitem>
</itemizedlist>
<para>将发送设置为阻塞方式会降低程序的效率。因为每次发送都需要一次网络往返的过程,然后才可以进行下次发送。
这样发送消息的速度将受网络往返时间RTT的限制。这样你的网络带宽就可能没有被充分利用。为了提高效率我们
建议采用事务来批量发送消息。因为在事务中只有在提交或回滚时阻塞。另外你还可以利用HornetQ高级的
<emphasis>异步发送通知功能</emphasis>。这一功能在<xref linkend="asynchronous-send-acknowledgements"/>
进行了描述。</para>
<para>使用JMS时如果JMS的连接工厂是在服务器端被注册到JNDI服务你需要配置
<literal>hornetq-jms.xml</literal>文件中的<literal>block-on-durable-send</literal>
<literal>block-on-non-durable-send</literal>。如果不使用JNDI可以调用
<literal>HornetQConnectionFactory</literal>相应的设置方法进行配置。</para>
<para>如果你使用的是内核服务,你可以直接在<literal
>ClientSessionFactory</literal>上用相关的方法设置相应的参数。</para>
<para>当服务器从一个非事务性的会话收到一个消息时,如果这个消息是持久的并且此消息被路由到至少一个持久的队列中,
则该消息会被持久化到永久存贮介质中。如果日志journal的参数<literal
>journal-sync-non-transactional</literal>设为<literal>true</literal>,服务器在向客户
发送响应时,它能保证消息已经被持久化到磁盘中。默认值是<literal>true</literal></para>
</section>
<section id="send-guarantees.nontrans.acks">
<title>非事务性通知的保证</title>
<para>当客户端使用非事务性会话向服务器通知消息收到时可以配置HornetQ使得客户端的通知阻塞直到服务器收到
了通知并返回为止。其相应的配置参数是<literal>BlockOnAcknowledge</literal>。如果该参数设为
<literal>true</literal>则所有的通过非事务会话的消息通知都是阻塞式的。如果你想要的消息传递策略是
<emphasis>最多一次</emphasis>的话,那么你需要将此参数设为。默认值是<literal>false</literal></para>
</section>
<section id="asynchronous-send-acknowledgements">
<title>异步发送通知</title>
<para>如果你使用的是非事务会话来发送消息并且希望保证每个发送出去的消息都到达服务器的话你可以将HornetQ配置
成阻塞的方式,如<xref linkend="non-transactional-sends"/>讨论的那样。这样做的一个缺点是性能的降低。
因为这样每发送一个消息就需要一次网络的往返通信。如果网络时延越长,消息发送的效率就越低。同时网络的带宽对消息
的发送没有影响。</para>
<para>我们来做一个简单的计算。假设有一个1Gib的网络客户端与服务器间往返时间为0.25ms。</para>
<para>这样,在阻塞方式的情况下,客户端<emphasis>最大</emphasis>的消息发送速度为 1000/ 0.25 =
4000 消息每秒。</para>
<para>如果每个消息的大小&lt; 1500字节而且网络的最大传输单元MTU是1500字节。那么理论上1GiB的网络
最大的传输速率是 (1024 * 1024 * 1024 / 8) / 1500 = 89478 消息每秒!尽管这不是一个精确的工程计算但
你可以看出阻塞式的发送对性能的影响会有多大。</para>
<para>为了解决这个问题HornetQ提供了一种新的功能称为<emphasis>异步发送通知</emphasis>
它允许消息以非阻塞的方式发送,同时从另一个连接流中异步地接收服务器的通知。这样就使得消息的发送与通知分开来,
避免了阻塞方式带来的缺点。在保证消息可行发送到服务器的同时提高了呑吐量。</para>
<para>参数用来定义消息发送通知的窗口大小。它属于连接工厂或客户会话工厂。参见<xref linkend="client-reconnection"/>
以获取更多的相关信息。</para>
<section>
<title>异步发送通知</title>
<para>如果使用核心API你需要实现<literal
>org.hornetq.api.core.client.SendAcknowledgementHandler</literal>接口并将一个实例设置到
<literal>ClientSession</literal>中。</para>
<para>然后使用这个<literal>ClientSession</literal>发送消息。当消息到达服务器后,服务器向客户端异步地发送通知,
并在客户端调用你的SendAcknowledgementHandler实例的<literal
>sendAcknowledged(ClientMessage message)</literal>方法。其中传入的参数就是发送的消息的引用。</para>
<para>为了使异步发送通知正常工作你必须确保<literal>confirmation-window-size</literal>的值为一个正整数,例如 10MiB</para>
<para>相关的例子请参见 <xref linkend="asynchronous-send-acknowledgements-example"/></para>
</section>
</section>
</chapter>