JBoss hornetq SVN: r9204 - branches/HnetQ_323_cn/docs/user-manual/zh.
by do-not-reply@jboss.org
Author: gaohoward
Date: 2010-05-06 11:45:35 -0400 (Thu, 06 May 2010)
New Revision: 9204
Modified:
branches/HnetQ_323_cn/docs/user-manual/zh/perf-tuning.xml
Log:
done
Modified: branches/HnetQ_323_cn/docs/user-manual/zh/perf-tuning.xml
===================================================================
--- branches/HnetQ_323_cn/docs/user-manual/zh/perf-tuning.xml 2010-05-06 12:55:31 UTC (rev 9203)
+++ branches/HnetQ_323_cn/docs/user-manual/zh/perf-tuning.xml 2010-05-06 15:45:35 UTC (rev 9204)
@@ -17,278 +17,209 @@
<!-- permitted by applicable law. -->
<!-- ============================================================================= -->
<chapter id="perf-tuning">
- <title>Performance Tuning</title>
- <para>In this chapter we'll discuss how to tune HornetQ for optimum performance.</para>
+ <title>性能调优</title>
+ <para>本章讲述如何优化HornetQ的性能</para>
<section>
- <title>Tuning persistence</title>
+ <title>持久层的优化</title>
<itemizedlist>
<listitem>
- <para>Put the message journal on its own physical volume. If the disk is shared with
- other processes e.g. transaction co-ordinator, database or other journals which
- are also reading and writing from it, then this may greatly reduce performance
- since the disk head may be skipping all over the place between the different
- files. One of the advantages of an append only journal is that disk head
- movement is minimised - this advantage is destroyed if the disk is shared. If
- you're using paging or large messages make sure they're ideally put on separate
- volumes too.</para>
+ <para>将消息日志放到单独的物理卷上。如果与其它数据共享,例如事务管理、数据库或其它日志等,那么就会
+ 增加读写的负担,磁头会在多个不同文件之间频繁地移动,极大地降低性能。我们的日志系统采用的是只
+ 添加的模式,目的就是最大程度減少磁头的移动。如果磁盘被共享,那么这一目的将不能达到。另外如果
+ 你使用分页转存或大消息功能时,你最好分别将它们放到各自的独立卷中。</para>
</listitem>
<listitem>
- <para>Minimum number of journal files. Set <literal>journal-min-files</literal> to a
- number of files that would fit your average sustainable rate. If you see new
- files being created on the journal data directory too often, i.e. lots of data
- is being persisted, you need to increase the minimal number of files, this way
- the journal would reuse more files instead of creating new data files.</para>
+ <para>尽量减少日志文件的数量。<literal>journal-min-files</literal>参数的设置应以满足平均
+ 运行需要为准。如果你发现系统中经常有新的日志文件被创建,这说明持久的数据量很大,你需要适当增加
+ 这个参数的值,以使HornetQ更多时候是在重用文件,而不是创建新文件。</para>
</listitem>
<listitem>
- <para>Journal file size. The journal file size should be aligned to the capacity of
- a cylinder on the disk. The default value 10MiB should be enough on most
- systems.</para>
+ <para>日志文件的大小。日志文件的大小最好要与磁盘的一个柱面的容量对齐。默认值是10MiB,它在绝大多数
+ 的系统中能够满足需要。</para>
</listitem>
<listitem>
- <para>Use AIO journal. If using Linux, try to keep your journal type as AIO. AIO
- will scale better than Java NIO.</para>
+ <para>使用AIO日志。在Linux下,尽量使用AIO型的日志。AIO的可扩展性要好于Java的NIO。</para>
</listitem>
<listitem>
- <para>Tune <literal>journal-buffer-timeout</literal>. The timeout can be increased
- to increase throughput at the expense of latency.</para>
+ <para>优化 <literal>journal-buffer-timeout</literal>。如果增加它的值,吞吐量会增加,但是
+ 延迟也会增加。</para>
</listitem>
<listitem>
- <para>If you're running AIO you might be able to get some better performance by
- increasing <literal>journal-max-io</literal>. DO NOT change this parameter if
- you are running NIO.</para>
+ <para>如果使用AIO,适当增加<literal>journal-max-io</literal>可能会提高性能。如果使用的是NIO,
+ 请不要改变这个参数。</para>
</listitem>
</itemizedlist>
</section>
<section>
- <title>Tuning JMS</title>
- <para>There are a few areas where some tweaks can be done if you are using the JMS
- API</para>
+ <title>优化JMS</title>
+ <para>如果使用JMS接口,有以下几个方面可以改进性能。</para>
<itemizedlist>
<listitem>
- <para>Disable message id. Use the <literal>setDisableMessageID()</literal> method on
- the <literal>MessageProducer</literal> class to disable message ids if you don't
- need them. This decreases the size of the message and also avoids the overhead
- of creating a unique ID.</para>
+ <para>关闭消息id。如果你不需要这个id,用<literal>MessageProducer</literal>的
+ <literal>setDisableMessageID()</literal>方法可以关闭它。这可以减少消息的大小并且
+ 省去了创建唯一ID的时间。</para>
</listitem>
<listitem>
- <para>Disable message timestamp. Use the <literal
- >setDisableMessageTimeStamp()</literal> method on the <literal
- >MessageProducer</literal> class to disable message timestamps if you don't
- need them.</para>
+ <para>关闭消息的时间戳。如果不需要时间戳,用<literal
+ >MessageProducer</literal>的<literal
+ >setDisableMessageTimeStamp()</literal>方法将其关闭。</para>
</listitem>
<listitem>
- <para>Avoid <literal>ObjectMessage</literal>. <literal>ObjectMessage</literal> is
- convenient but it comes at a cost. The body of a <literal
- >ObjectMessage</literal> uses Java serialization to serialize it to bytes.
- The Java serialized form of even small objects is very verbose so takes up a lot
- of space on the wire, also Java serialization is slow compared to custom
- marshalling techniques. Only use <literal>ObjectMessage</literal> if you really
- can't use one of the other message types, i.e. if you really don't know the type
- of the payload until run-time.</para>
+ <para>尽量避免使用<literal>ObjectMessage</literal>。<literal>ObjectMessage</literal>会带
+ 来额外的开销。<literal>ObjectMessage</literal>使用Java的序列化将它序列化为字节流。在对小的对象
+ 进行序列化会占用大量的空间,使传输的数据量加大。另外,Java的序列化与其它定制的技术相比要慢。只有在不得
+ 以的情况下才使用它。比如当你在运行时不知道对象的具体类型时,可以用ObjectMessage。</para>
</listitem>
<listitem>
- <para>Avoid <literal>AUTO_ACKNOWLEDGE</literal>. <literal>AUTO_ACKNOWLEDGE</literal>
- mode requires an acknowledgement to be sent from the server for each message
- received on the client, this means more traffic on the network. If you can, use
- <literal>DUPS_OK_ACKNOWLEDGE</literal> or use <literal
- >CLIENT_ACKNOWLEDGE</literal> or a transacted session and batch up many
- acknowledgements with one acknowledge/commit. </para>
+ <para>避免使用<literal>AUTO_ACKNOWLEDGE</literal>。 <literal>AUTO_ACKNOWLEDGE</literal>
+ 使得每收到一个消息就要向服务器发送一个通知--这样增加的网络传输的负担。如果可能,尽量使用
+ <literal>DUPS_OK_ACKNOWLEDGE</literal>或者<literal
+ >CLIENT_ACKNOWLEDGE</literal>。或者使用事务性会话,将通知在提交时批量完成。</para>
</listitem>
<listitem>
- <para>Avoid durable messages. By default JMS messages are durable. If you don't
- really need durable messages then set them to be non-durable. Durable messages
- incur a lot more overhead in persisting them to storage.</para>
+ <para>避免持久化消息。默认情况下JMS消息是持久的。如果你不需要持久消息,则将其设定为非持久。
+ 持久消息都会被写到磁盘中,这给系统带来了明显的负担。</para>
</listitem>
</itemizedlist>
</section>
<section>
- <title>Other Tunings</title>
- <para>There are various other places in HornetQ where we can perform some tuning:</para>
+ <title>其它优化</title>
+ <para>在HornetQ中还有其它一些地方可以优化:</para>
<itemizedlist>
<listitem>
- <para>Use Asynchronous Send Acknowledgements. If you need to send durable messages
- non transactionally and you need a guarantee that they have reached the server
- by the time the call to send() returns, don't set durable messages to be sent
- blocking, instead use asynchronous send acknowledgements to get your
- acknowledgements of send back in a separate stream, see <xref
- linkend="send-guarantees"/> for more information on this.</para>
+ <para>使用异步发送通知。如果你在非事务条件下发送持久的消息,并且要保证在send()返回时持久消息已经到达服
+ 务器,不要使用阻塞式发送的方式,应该使用异步发送通知的方式。参见<xref
+ linkend="send-guarantees"/>中的说明。</para>
</listitem>
<listitem>
- <para>Use pre-acknowledge mode. With pre-acknowledge mode, messages are acknowledged
- <literal>before</literal> they are sent to the client. This reduces the
- amount of acknowledgement traffic on the wire. For more information on this, see
- <xref linkend="pre-acknowledge"/>.</para>
+ <para>使用预先通知模式。预先通知就是在消息发往客户端<literal>之前</literal>进行通知。它节省了正常
+ 的消息通知所占用的通迅时间。详细的解释请参见
+ <xref linkend="pre-acknowledge"/>。</para>
</listitem>
<listitem>
- <para>Disable security. You may get a small performance boost by disabling security
- by setting the <literal>security-enabled</literal> parameter to <literal
- >false</literal> in <literal>hornetq-configuration.xml</literal>.</para>
+ <para>关闭安全。将<literal>hornetq-configuration.xml</literal>文件中的<literal>security-enabled</literal>
+ 参数设为<literal>false</literal>以关闭安全。这可以带来一些性能的提高。</para>
</listitem>
<listitem>
- <para>Disable persistence. If you don't need message persistence, turn it off
- altogether by setting <literal>persistence-enabled</literal> to false in
- <literal>hornetq-configuration.xml</literal>.</para>
+ <para>关闭持久化。如果不你不需要消息持久化,可以将<literal>hornetq-configuration.xml</literal>
+ 文件中的<literal>persistence-enabled</literal>参数设为false来完全关闭持久功能。</para>
</listitem>
<listitem>
- <para>Sync transactions lazily. Setting <literal
- >journal-sync-transactional</literal> to <literal>false</literal> in
- <literal>hornetq-configuration.xml</literal> can give you better
- transactional persistent performance at the expense of some possibility of loss
- of transactions on failure. See <xref linkend="send-guarantees"/> for more
- information.</para>
+ <para>采用延迟方式事务同步。将<literal>hornetq-configuration.xml</literal>文件中的<literal
+ >journal-sync-transactional</literal>参数设为<literal>false</literal>可以得到
+ 更好的事务持久化的性能。但是这样做可能会造成在发生故障时事务的丢失。有关详细的说明参见
+ <xref linkend="send-guarantees"/>。</para>
</listitem>
<listitem>
- <para>Sync non transactional lazily. Setting <literal
- >journal-sync-non-transactional</literal> to <literal>false</literal> in
- <literal>hornetq-configuration.xml</literal> can give you better
- non-transactional persistent performance at the expense of some possibility of
- loss of durable messages on failure. See <xref linkend="send-guarantees"/> for
- more information.</para>
+ <para>采用延迟方式非事务同步。将<literal>hornetq-configuration.xml</literal>文件中的<literal
+ >journal-sync-non-transactional</literal>参数设为<literal>false</literal>可以得到
+ 更好的非事务持久化的性能。但是这样做可能会造成在发生故障时持久消息的丢失。有关详细的说明参见
+ <xref linkend="send-guarantees"/>。</para>
</listitem>
<listitem>
- <para>Send messages non blocking. Setting <literal>block-on-durable-send</literal>
- and <literal>block-on-non-durable-send</literal> to <literal>false</literal> in
- <literal>hornetq-jms.xml</literal> (if you're using JMS and JNDI) or
- directly on the ClientSessionFactory. This means you don't have to wait a whole
- network round trip for every message sent. See <xref linkend="send-guarantees"/>
- for more information.</para>
+ <para>采用非阻塞方式发送消息。将文件<literal>hornetq-jms.xml</literal>中的参数
+ <literal>block-on-non-durable-send</literal>设为<literal>false</literal>
+ (使用JMS和JNDI时)或者直接在上进行相应的设置,可以使
+ 消息发送时不阻塞等待服务器的响应。参见 <xref linkend="send-guarantees"/>。</para>
</listitem>
<listitem>
- <para>Socket NIO vs Socket Old IO. By default HornetQ uses Socket NIO on the server
- and old (blocking) IO on the client side (see the chapter on configuring
- transports for more information <xref linkend="configuring-transports"/>). NIO
- is much more scalable but can give you some latency hit compared to old blocking
- IO. If you expect to be able to service many thousands of connections on the
- server, then continue to use NIO on the server. However, if don't expect many
- thousands of connections on the server you can configure the server acceptors to
- use old IO, and might get a small performance advantage.</para>
+ <para>套接字NIO与旧的IO对比。默认情况下HornetQ在服务器端使用套接字NIO技术,而在客户端则使用旧的(阻塞)
+ IO(参见传输配置一章<xref linkend="configuring-transports"/>)。NIO比旧的阻塞式IO有更
+ 强的可扩展性,但是也会带来一些延时。如果你的服务器要同时有数千个连接,使用NIO效果比较好。但是如果
+ 连接数并没有这么多,你可以配置接收器使用旧的IO还提高性能。</para>
</listitem>
<listitem>
- <para>Use the core API not JMS. Using the JMS API you will have slightly lower
- performance than using the core API, since all JMS operations need to be
- translated into core operations before the server can handle them. If using the
- core API try to use methods that take <literal>SimpleString</literal> as much as
- possible. <literal>SimpleString</literal>, unlike java.lang.String does not
- require copying before it is written to the wire, so if you re-use <literal
- >SimpleString</literal> instances between calls then you can avoid some
- unnecessary copying.</para>
+ <para>尽量使用核心接口而不用JMS。使用JMS接口会稍微比使用核心接口性能要低些。这是因为所有JMS操作
+ 实际上要转化为核心的操作才能为服务器所处理。在使用核心接口时,尽量使用带有
+ <literal>SimpleString</literal>类型参数的方法。<literal>SimpleString</literal>与
+ java.lang.String不同,它在写入传输层时不需要拷贝。所以你如果在调用中重用<literal
+ >SimpleString</literal>对象可以避免不必要的拷贝。</para>
</listitem>
</itemizedlist>
</section>
<section>
- <title>Tuning Transport Settings</title>
+ <title>传输层的优化</title>
<itemizedlist>
<listitem>
- <para>Enable <ulink url="http://en.wikipedia.org/wiki/Nagle's_algorithm">Nagle's
- algorithm</ulink>. If you are sending many small messages, such that more
- than one can fit in a single IP packet thus providing better performance. This
- is done by setting <literal>tcp-no-delay</literal> to false with the Netty
- transports. See <xref linkend="configuring-transports"/> for more information on
- this. </para>
- <para>Enabling Nagle's algorithm can make a very big difference in performance and
- is highly recommended if you're sending a lot of asynchronous traffice.</para>
+ <para>使用<ulink url="http://en.wikipedia.org/wiki/Nagle's_algorithm">Nagle's
+ 算法</ulink>。如果发送的是许多小的消息,多个消息可以在一个IP包中发送,因此性能可以提高。
+ 这需要将Netty传输中的<literal>tcp-no-delay</literal>设为false。参见
+ <xref linkend="configuring-transports"/>中的详细说明。</para>
+ <para>采用Nagle算法可以显著提高性能,如果应用程序有很多异步的发送,强烈推荐使用它。</para>
</listitem>
<listitem>
- <para>TCP buffer sizes. If you have a fast network and fast machines you may get a
- performance boost by increasing the TCP send and receive buffer sizes. See the
- <xref linkend="configuring-transports"/> for more information on this.
+ <para>TCP缓存大小。如果你的网络速度很快,并且你的主机也很快,你可以通过增加TCP的发送和接收缓存
+ 来提高性能。参见<xref linkend="configuring-transports"/>中的详细说明。
</para>
</listitem>
<listitem>
- <para>Increase limit on file handles on the server. If you expect a lot of
- concurrent connections on your servers, or if clients are rapidly opening and
- closing connections, you should make sure the user running the server has
- permission to create sufficient file handles.</para>
- <para>This varies from operating system to operating system. On Linux systems you
- can increase the number of allowable open file handles in the file <literal
- >/etc/security/limits.conf</literal> e.g. add the lines
+ <para>增加服务器中文件句柄数量限制。如果你的服务器将要处理很多并行的连接,或者客户端在快速不停地
+ 打开和关闭连接,你要确保在服务器端有足够的文件句柄以供使用。</para>
+ <para>这个限制在不同平台有不同的方法。在Linux系统中,你可以编辑文件<literal
+ >/etc/security/limits.conf</literal>,增加以下内容:
<programlisting>
serveruser soft nofile 20000
serveruser hard nofile 20000
</programlisting>
- This would allow up to 20000 file handles to be open by the user <literal
- >serveruser</literal>. </para>
+ 它设置了用户<literal>serveruser</literal>可以最多打开20000个文件句柄。</para>
</listitem>
</itemizedlist>
</section>
<section>
- <title>Tuning the VM</title>
- <para>We highly recommend you use the latest Java 6 JVM, especially in the area of
- networking, many improvements have been made since Java 5. We test internally using the
- Sun JVM, so some of these tunings won't apply to JDKs from other providers (e.g. IBM or
- JRockit)</para>
+ <title>优化虚拟机</title>
+ <para>我们强烈建议你使用最新的Java 6虚拟机。它在很多方面对以前Java 5的虚拟机进行了改进,特别是在网络功能方面。
+ 这是根据我们内部使用Sun的实现测试的結果,可能不适用于其它的Java实现(例如IBM或JRockit)。</para>
<itemizedlist>
<listitem>
- <para>Garbage collection. For smooth server operation we recommend using a parallel
- garbage collection algorithm, e.g. using the JVM argument <literal
- >-XX:+UseParallelGC</literal> on Sun JDKs.</para>
+ <para>拉圾回收。为了使服务器的运行比较平滑,我们建议使用并行拉圾回收的算法。例如在Sun的JDK使用
+ JVM选项<literal>-XX:+UseParallelGC</literal>.</para>
</listitem>
<listitem id="perf-tuning.memory">
- <para>Memory settings. Give as much memory as you can to the server. HornetQ can run
- in low memory by using paging (described in <xref linkend="paging"/>) but if it
- can run with all queues in RAM this will improve performance. The amount of
- memory you require will depend on the size and number of your queues and the
- size and number of your messages. Use the JVM arguments <literal>-Xms</literal>
- and <literal>-Xmx</literal> to set server available RAM. We recommend setting
- them to the same high value.</para>
- <para>HornetQ will regularly sample JVM memory and reports if the available memory
- is below a configurable threshold. Use this information to properly set JVM
- memory and paging. The sample is disabled by default. To enabled it, configure
- the sample frequency by setting <literal>memory-measure-interval</literal> in
- <literal>hornetq-configuration.xml</literal> (in milliseconds). When the
- available memory goes below the configured threshold, a warning is logged. The
- threshold can be also configured by setting <literal
- >memory-warning-threshold</literal> in <literal
- >hornetq-configuration.xml</literal> (default is 25%).</para>
+ <para>内存设置。尽量为服务器分配更多的内存。HornetQ利用其分页转存技术可以在很少的内存下运行(在
+ <xref linkend="paging"/>中有说明)。但是如果所有队列都在内存运行,性能将会很好。具体需要
+ 多少内存要由你的队列的大小和数量以及消息的大小和数量决定。使用JVM参数<literal>-Xms</literal>
+ 和<literal>-Xmx</literal>来为你的服务器分配内存。我们建议两个参数的设为相同的值。</para>
+ <para>HornetQ可以定期地检测JVM的内存并报告是否可用内存低于指定的值。参考这个报告的值可以对JVM的内存
+ 及分页转存进行合理的设定。这个检测功能默认是关闭的。如要使用,需要配置
+ <literal>hornetq-configuration.xml</literal>文件中的参数
+ <literal>memory-measure-interval</literal>,它表示检测的频度(单位毫秒)。
+ 当可用内存低于指定的值时,在日志会输出一个警告。这个指定的内存值也在文件<literal
+ >hornetq-configuration.xml</literal>中定义,参数名为<literal
+ >memory-warning-threshold</literal>(默认值25%)。</para>
</listitem>
<listitem>
- <para>Aggressive options. Different JVMs provide different sets of JVM tuning
- parameters, for the Sun Hotspot JVM the full list of options is available <ulink
+ <para>主动选项(Aggressive options)。不同JVM有不同的JVM优化参数。对于Sun的Hotspot JVM,在<ulink
url="http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp"
- >here</ulink>. We recommend at least using <literal
- >-XX:+AggressiveOpts</literal> and<literal>
- -XX:+UseFastAccessorMethods</literal>. You may get some mileage with the
- other tuning parameters depending on your OS platform and application usage
- patterns.</para>
+ >这里</ulink>有一个完整的参数列表。我们建议至少要使用 <literal
+ >-XX:+AggressiveOpts</literal> 和<literal>
+ -XX:+UseFastAccessorMethods</literal>选项。根据不同的平台,可能还有其它一些参数供你使用,
+ 以提高JVM的性能。</para>
</listitem>
</itemizedlist>
</section>
<section>
- <title>Avoiding Anti-Patterns</title>
+ <title>避免违背设计模式</title>
<itemizedlist>
<listitem>
- <para>Re-use connections / sessions / consumers / producers. Probably the most
- common messaging anti-pattern we see is users who create a new
- connection/session/producer for every message they send or every message they
- consume. This is a poor use of resources. These objects take time to create and
- may involve several network round trips. Always re-use them.</para>
+ <para>重用连接/会话/接收者/发送者。最常见的错误恐怕就是每发送/接收一个消息都要创建一个新的连接
+ /会话/发送者或接收者。这样非常浪费资源。这些对象的创建要占用时间和网络带宽。它们应该进行重用。</para>
<note>
- <para>Some popular libraries such as the Spring JMS Template are known to use
- these anti-patterns. If you're using Spring JMS Template and you're getting
- poor performance you know why. Don't blame HornetQ!</para>
+ <para>有些常用的框架如Spring JMS Template在使用JMS时违背了设计模式。如果你使用了它,性能
+ 就会受到影响。这不是HornetQ的原因!</para>
</note>
</listitem>
<listitem>
- <para>Avoid fat messages. Verbose formats such as XML take up a lot of space on the
- wire and performance will suffer as result. Avoid XML in message bodies if you
- can.</para>
+ <para>避免使用繁锁的消息格式。如XML,它会使数据量变大进而降低性能。所以应该尽量避免在消息体中使用XML。</para>
</listitem>
<listitem>
- <para>Don't create temporary queues for each request. This common anti-pattern
- involves the temporary queue request-response pattern. With the temporary queue
- request-response pattern a message is sent to a target and a reply-to header is
- set with the address of a local temporary queue. When the recipient receives the
- message they process it then send back a response to the address specified in
- the reply-to. A common mistake made with this pattern is to create a new
- temporary queue on each message sent. This will drastically reduce performance.
- Instead the temporary queue should be re-used for many requests.</para>
+ <para>不要为每个请求都创建新的临时队列。临时队列通常用于请求-响应模式的消息应用。在这个模式中消息被发往
+ 一个目的,它带有一个reply-to的头属性指向一个本地的临时队列的地址。当消息被收到后,接收方将响应做为消息发
+ 往那个reply-to指定的临时的地址。如果每发一个消息都创建一个临时队列,那么性能将会受很大影响。正确的
+ 作法是在发送消息时重用临时队列。</para>
</listitem>
<listitem>
- <para>Don't use Message-Driven Beans for the sake of it. As soon as you start using
- MDBs you are greatly increasing the codepath for each message received compared
- to a straightforward message consumer, since a lot of extra application server
- code is executed. Ask yourself do you really need MDBs? Can you accomplish the
- same task using just a normal message consumer?</para>
+ <para>尽量不要使用MDB。使用MDB,消息的接收过程要比直接接收复杂得多,要执行很多应用服务器内部的代码。
+ 在设计应用时要问一下是否真的需要MDB?可不可以直接使用消息接收者完成同样的任务?</para>
</listitem>
</itemizedlist>
</section>
14 years, 10 months
JBoss hornetq SVN: r9203 - branches/HnetQ_323_cn/docs/user-manual/zh.
by do-not-reply@jboss.org
Author: gaohoward
Date: 2010-05-06 08:55:31 -0400 (Thu, 06 May 2010)
New Revision: 9203
Modified:
branches/HnetQ_323_cn/docs/user-manual/zh/interoperability.xml
Log:
done
Modified: branches/HnetQ_323_cn/docs/user-manual/zh/interoperability.xml
===================================================================
--- branches/HnetQ_323_cn/docs/user-manual/zh/interoperability.xml 2010-05-06 08:19:30 UTC (rev 9202)
+++ branches/HnetQ_323_cn/docs/user-manual/zh/interoperability.xml 2010-05-06 12:55:31 UTC (rev 9203)
@@ -17,18 +17,17 @@
<!-- permitted by applicable law. -->
<!-- ============================================================================= -->
<chapter id="interoperability">
- <title>Interoperability</title>
+ <title>互操作性</title>
<section id="stomp">
<title>Stomp</title>
- <para><ulink url="http://stomp.codehaus.org/">Stomp</ulink> is a text-orientated wire protocol that allows
- Stomp clients to communicate with Stomp Brokers.</para>
- <para><ulink url="http://stomp.codehaus.org/Clients">Stomp clients</ulink> are available for
- several languages and platforms making it a good choice for interoperability.</para>
+ <para><ulink url="http://stomp.codehaus.org/">Stomp</ulink>是一个基于文本的协议。使用Stomp协议的
+ 客户端可以与Stomp的代理(broker)进行通迅。</para>
+ <para><ulink url="http://stomp.codehaus.org/Clients">Stomp客户端</ulink>支持多种语言和平台,因此
+ 它有着很好的互操作性。</para>
<section id="stomp.native">
- <title>Native Stomp support</title>
- <para>HornetQ provides native support for Stomp. To be able to send and receive Stomp messages,
- you must configure a <literal>NettyAcceptor</literal> with a <literal>protocol</literal>
- parameter set to <literal>stomp</literal>:</para>
+ <title>内建Stomp支持</title>
+ <para>HornetQ内建支持Stomp功能。要使用Stomp发送与接收消息,必须配置一个<literal>NettyAcceptor</literal>,
+ 其中的<literal>protocol</literal>参数值应设为<literal>stomp</literal>:</para>
<programlisting>
<acceptor name="stomp-acceptor">
<factory-class>org.hornetq.integration.transports.netty.NettyAcceptorFactory</factory-class>
@@ -36,53 +35,47 @@
<param key="port" value="61613"/>
</acceptor>
</programlisting>
- <para>With this configuration, HornetQ will accept Stomp connections on
- the port <literal>61613</literal> (which is the default port of the Stomp brokers).</para>
- <para>See the <literal>stomp</literal> example which shows how to configure a HornetQ server with Stomp.</para>
+ <para>有了上述的配置,HornetQ就可以在端口<literal>61613</literal>(这是Stomp代理的默认端口)接受Stomp连接了。</para>
+ <para><literal>stomp</literal>例子展示了如何在HornetQ中配置Stomp。</para>
<section>
- <title>Limitations</title>
- <para>Message acknowledgements are not transactional. The ACK frame can not be part of a transaction
- (it will be ignored if its <literal>transaction</literal> header is set).</para>
+ <title>限制</title>
+ <para>消息的通知不是事务性的。ACK信号不能作为事务的一部分来传输(如果设置了<literal>transaction</literal>
+ 属性,它将被忽略)。</para>
</section>
</section>
<section id="stompconnect">
<title>StompConnect</title>
- <para><ulink url="http://stomp.codehaus.org/StompConnect">StompConnect</ulink> is a server that
- can act as a Stomp broker and proxy the Stomp protocol to the standard JMS API.
- Consequently, using StompConnect it is possible to turn HornetQ into a Stomp Broker and
- use any of the available stomp clients. These include clients written in C, C++, c# and
- .net etc.</para>
- <para>To run StompConnect first start the HornetQ server and make sure that it is using
- JNDI.</para>
- <para>Stomp requires the file <literal>jndi.properties</literal> to be available on the
- classpath. This should look something like:</para>
+ <para><ulink url="http://stomp.codehaus.org/StompConnect">StompConnect</ulink>是一个Stomp代理服务器,
+ 它可以将Stomp协议转换为标准的JMS接口调用。因此,通过StompConnect的作用HornetQ可以作为一个Stomp代理,
+ 与任何一个Stomp客户端通迅。这些客户端可以由C、C++、C#及.net等语言实现。</para>
+ <para>要运行StompConnect首先要启动HornetQ服务以及JNDI服务。</para>
+ <para>Stomp需要<literal>jndi.properties</literal>文件要在classpath中。该文件
+ 应有如下类似的内容:</para>
<programlisting>java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://localhost:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces</programlisting>
- <para>Make sure this file is in the classpath along with the StompConnect jar and the
- HornetQ jars and simply run <literal>java org.codehaus.stomp.jms.Main</literal>.</para>
+ <para>要确保该文件与StompConnect的jar包以及HornetQ的jar文件都在classpath中。最后,运行
+ <literal>java org.codehaus.stomp.jms.Main</literal>。</para>
</section>
<section>
- <title>Mapping Stomp destinations to HornetQ addresses and queues</title>
- <para>Stomp clients deals with <emphasis>destinations</emphasis> when sending messages and subscribing.
- Destination names are simply strings which are mapped to some form of destination on the
- server - how the server translates these is left to the server implementation.</para>
- <para>In HornetQ, these destinations are mapped to <emphasis>addresses</emphasis> and <emphasis>queues</emphasis>.
- When a Stomp client sends a message (using a <literal>SEND</literal> frame), the specified destination is mapped
- to an address.
- When a Stomp client subscribes (or unsubscribes) for a destination (using a <literal>SUBSCRIBE</literal>
- or <literal>UNSUBSCRIBE</literal> frame), the destination is mapped to a HornetQ queue.</para>
+ <title>Stomp目标与HornetQ的地址和队列的映射</title>
+ <para>Stomp客户端在消息发送和订阅中使用的是<emphasis>目标(destination)</emphasis>。目标名称是简单的字符串,对应的是服务
+ 器端的目的地。不同服务器对这种映射有着不同的实现。</para>
+ <para>在HornetQ中这些目标被映射为<emphasis>地址</emphasis>和<emphasis>队列</emphasis>。
+ 当一个Stomp客户端发送一个消息(使用<literal>SEND</literal>信号)到一个目标时,这个目标被映射到一个地址。
+ 如果一个Stomp客户端订阅(或解除订阅)一个目标时(使用<literal>SUBSCRIBE</literal>或
+ <literal>UNSUBSCRIBE</literal>),这个目标被映射到一个HornetQ的队列。</para>
</section>
<section>
- <title>Stomp and JMS interoperabilty</title>
+ <title>Stomp与JMS的互操作性</title>
<section>
- <title>Using JMS destinations</title>
- <para>As explained in <xref linkend="jms-core-mapping" />, JMS destinations are also mapped to HornetQ addresses and queues.
- If you want to use Stomp to send messages to JMS destinations, the Stomp destinations must follow the same convention:</para>
+ <title>使用JMS目标</title>
+ <para>正如<xref linkend="jms-core-mapping" />解释的那样,JMS的目标同样映射到HornetQ的地址与队列。如果你使用
+ Stomp向JMS的目标发送消息,那么Stomp的目标必须要遵照相同的命名规则:</para>
<itemizedlist>
<listitem>
- <para>send or subscribe to a JMS <emphasis>Queue</emphasis> by prepending the queue name by <literal>jms.queue.</literal>.</para>
- <para>For example, to send a message to the <literal>orders</literal> JMS Queue, the Stomp client must send the frame:</para>
+ <para>如果向JMS<emphasis>队列</emphasis>发送数据或订阅它,则队列的名称前缀必须是<literal>jms.queue.</literal>。</para>
+ <para>例如,如果向名为<literal>orders</literal>的JMS队列发送消息,Stomp客户端必须发送以下信息:</para>
<programlisting>
SEND
destination:jms.queue.orders
@@ -92,8 +85,8 @@
</programlisting>
</listitem>
<listitem>
- <para>send or subscribe to a JMS <emphasis>Topic</emphasis> by prepending the topic name by <literal>jms.topic.</literal>.</para>
- <para>For example to subscribe to the <literal>stocks</literal> JMS Topic, the Stomp client must send the frame:</para>
+ <para>如果向JMS <emphasis>话题(topic)</emphasis>发送或订阅消息,话题名称前缀必须是<literal>jms.topic.</literal>。</para>
+ <para>例如,如果订阅名为 <literal>stocks</literal>的JMS话题,Stomp客户端必须发送以下信息:</para>
<programlisting>
SUBSCRIBE
destination:jms.topic.stocks
@@ -105,17 +98,16 @@
</section>
<section>
- <title>Send and consuming Stomp message from JMS</title>
- <para>Stomp messages can be sent and consumed from a JMS Destination by using <literal>BytesMessage</literal> where
- the Stomp message body is stored in the JMS BytesMessage body.</para>
- <para>If the Stomp message contained a UTF-8 String, the corresponding code to read the string from a JMS BytesMessage is:</para>
+ <title>使用Stomp通过JMS发送和接收Stomp消息</title>
+ <para>如果要通过JMS目标来传送Stomp消息,可以使用<literal>BytesMessage</literal>将Stomp的消息封装后进行传送。</para>
+ <para>如果Stomp消息中含有UTF-8字符串,则可以用以下代码将其读入到JMS的BytesMessage:</para>
<programlisting>
BytesMessage message = (BytesMessage)consumer.receive();
byte[] data = new byte[1024];
int size = message.readBytes(data);
String text = new String(data, 0, size, "UTF-8");
</programlisting>
- <para>Conversely, to send a JMS BytesMessage destined to be consumed by Stomp as a UTF-8 String, the code is:</para>
+ <para>相反地,要将一个UTF-8字符串的消息发给Stomp客户端,可以作用以下代码:</para>
<programlisting>
String text = ...
BytesMessage message = session.createBytesMessage();
@@ -127,10 +119,10 @@
</section>
<section>
<title>REST</title>
- <para>REST support coming soon!</para>
+ <para>HornetQ即将支持REST!</para>
</section>
<section>
<title>AMQP</title>
- <para>AMQP support coming soon!</para>
+ <para>HornetQ即将支持AMQP!</para>
</section>
</chapter>
14 years, 10 months
JBoss hornetq SVN: r9202 - branches/HnetQ_323_cn/docs/user-manual/zh.
by do-not-reply@jboss.org
Author: gaohoward
Date: 2010-05-06 04:19:30 -0400 (Thu, 06 May 2010)
New Revision: 9202
Modified:
branches/HnetQ_323_cn/docs/user-manual/zh/intercepting-operations.xml
Log:
done
Modified: branches/HnetQ_323_cn/docs/user-manual/zh/intercepting-operations.xml
===================================================================
--- branches/HnetQ_323_cn/docs/user-manual/zh/intercepting-operations.xml 2010-05-06 07:19:38 UTC (rev 9201)
+++ branches/HnetQ_323_cn/docs/user-manual/zh/intercepting-operations.xml 2010-05-06 08:19:30 UTC (rev 9202)
@@ -19,14 +19,13 @@
<!-- ============================================================================= -->
<chapter id="intercepting-operations">
- <title>Intercepting Operations</title>
- <para>HornetQ supports <emphasis>interceptors</emphasis> to intercept packets entering
- the server. Any supplied interceptors would be called for any packet entering
- the server, this allows custom code to be executed, e.g. for auditing packets,
- filtering or other reasons. Interceptors can change the packets they intercept.</para>
+ <title>拦截操作</title>
+ <para>HornetQ支持<emphasis>拦截器</emphasis>。拦截器可以拦截进入服务器的数据包。每进入服务器
+ 一个数据包,拦截器就被调用一次,允许一些特殊和处理,例如对包的审计、过滤等。拦截器可以对数据包
+ 进行改动。</para>
<section>
- <title>Implementing The Interceptors</title>
- <para>A interceptor must implement the <literal>Interceptor interface</literal>:</para>
+ <title>实现拦截器</title>
+ <para>拦截器必须要实现<literal>Interceptor接口</literal>:</para>
<programlisting>
package org.hornetq.api.core.interceptor;
@@ -36,41 +35,37 @@
throws HornetQException;
}
</programlisting>
- <para>The returned boolean value is important:</para>
+ <para>它的方法的返回值是很重要的:</para>
<itemizedlist>
<listitem>
- <para>if <literal>true</literal> is returned, the process continues normally</para>
+ <para>如果返回<literal>true</literal>,处理正常进行下去。</para>
</listitem>
<listitem>
- <para>if <literal>false</literal> is returned, the process is aborted, no other
- interceptors will be called and the packet will not be handled by the server at
- all.</para>
+ <para>如果返回<literal>false</literal>,则处理被中断,其它的拦截器将不会被调用,数据包将不会
+ 被服务器所处理。</para>
</listitem>
</itemizedlist>
</section>
<section>
- <title>Configuring The Interceptors</title>
- <para>The interceptors are configured in <literal>hornetq-configuration.xml</literal>:</para>
+ <title>配置拦截器</title>
+ <para>拦截器的配置在<literal>hornetq-configuration.xml</literal>文件中:</para>
<programlisting>
<remoting-interceptors>
<class-name>org.hornetq.jms.example.LoginInterceptor</class-name>
<class-name>org.hornetq.jms.example.AdditionalPropertyInterceptor</class-name>
</remoting-interceptors>
</programlisting>
- <para>The interceptors classes (and their dependencies) must be added to the server classpath
- to be properly instantiated and called.</para>
+ <para>拦截器的类(以及它们依赖的类)必须要在服务器的classpath中,否则不能被正常初始化及调用。</para>
</section>
<section>
- <title>Interceptors on the Client Side</title>
- <para>The interceptors can also be run on the client side to intercept packets
- <emphasis>sent by the server</emphasis> by adding the interceptor to the <code>ClientSessionFactory</code>
- with the <code>addInterceptor()</code> method.</para>
- <para>The interceptors classes (and their dependencies) must be added to the client classpath
- to be properly instantiated and called from the client side.</para>
+ <title>客户端拦截器</title>
+ <para>在客户端也可以有拦截器来拦截<emphasis>来自服务器</emphasis>的数据包。<code>ClientSessionFactory</code>
+ 的<code>addInterceptor()</code>方法可以用来添加拦截器。</para>
+ <para>同样拦截器的类(以及它们依赖的类)必须要在客户端的classpath中,否则它们不能被正常初始化及调用。</para>
</section>
<section>
- <title>Example</title>
- <para>See <xref linkend="examples.interceptor" /> for an example which
- shows how to use interceptors to add properties to a message on the server.</para>
+ <title>例子</title>
+ <para>参见<xref linkend="examples.interceptor" />。这个例子中展示了如何使用拦截器向发往服务器的消息中
+ 添加属性。</para>
</section>
</chapter>
14 years, 10 months
JBoss hornetq SVN: r9201 - branches/HnetQ_323_cn/docs/user-manual/zh.
by do-not-reply@jboss.org
Author: gaohoward
Date: 2010-05-06 03:19:38 -0400 (Thu, 06 May 2010)
New Revision: 9201
Modified:
branches/HnetQ_323_cn/docs/user-manual/zh/embedding-hornetq.xml
Log:
done
Modified: branches/HnetQ_323_cn/docs/user-manual/zh/embedding-hornetq.xml
===================================================================
--- branches/HnetQ_323_cn/docs/user-manual/zh/embedding-hornetq.xml 2010-05-05 08:24:45 UTC (rev 9200)
+++ branches/HnetQ_323_cn/docs/user-manual/zh/embedding-hornetq.xml 2010-05-06 07:19:38 UTC (rev 9201)
@@ -17,25 +17,20 @@
<!-- permitted by applicable law. -->
<!-- ============================================================================= -->
<chapter id="embedding-hornetq">
- <title>Embedding HornetQ</title>
- <para>HornetQ is designed as set of simple Plain Old Java Objects (POJOs). This means HornetQ
- can be instantiated and run in any dependency injection framework such as JBoss
- Microcontainer, Spring or Google Guice. It also means that if you have an application that
- could use messaging functionality internally, then it can <emphasis>directly
- instantiate</emphasis> HornetQ clients and servers in its own application code to
- perform that functionality. We call this <emphasis>embedding</emphasis> HornetQ.</para>
- <para>Examples of applications that might want to do this include any application that needs
- very high performance, transactional, persistent messaging but doesn't want the hassle of
- writing it all from scratch.</para>
- <para>Embedding HornetQ can be done in very few easy steps. Instantiate the configuration
- object, instantiate the server, start it, and you have a HornetQ running in your virtual
- machine. It's as simple and easy as that.</para>
+ <title>嵌入式HornetQ</title>
+ <para>HornetQ是由简单传统Java对象(POJO)实现,因此它可以在任何依赖注入的框架中运行,比如JBoss
+ Microcontainer,Sprint或Google Guice。另外如果你的应用程序内部需要消息功能,你可以在程序中
+ <emphasis>直接实例化</emphasis>HornetQ的客户端或服务器端。我们称之为<emphasis>嵌入式</emphasis>
+ HornetQ。</para>
+ <para>有些应用需要高性能、事务性及持久化的消息服务,但是又不希望自己去费时费力实现它。于是嵌入式HornetQ就
+ 成为了一个很适当的选择。</para>
+ <para>要使用嵌入式HornetQ只需要几个简单的步骤。首先初始化配置对象,再初始化服务器并启动它,在你的虚拟机
+ 中就运行越来了一个HornetQ服务器。就是这么简单。</para>
<section>
- <title>POJO instantiation</title>
- <para>You can follow this step-by-step guide:</para>
- <para>Create the configuration object - this contains configuration information for a
- HornetQ. If you want to configure it from a file on the classpath, use <literal
- >FileConfigurationImpl</literal></para>
+ <title>POJO的初始化</title>
+ <para>按照以下步骤去做:</para>
+ <para>创建配置对象--这个对象包装了HornetQ的配置信息。如果你想使用配置文件,则使用<literal
+ >FileConfigurationImpl</literal>。</para>
<programlisting>import org.hornetq.core.config.Configuration;
import org.hornetq.core.config.impl.FileConfiguration;
@@ -45,12 +40,10 @@
Configuration config = new FileConfiguration();
config.setConfigurationUrl(urlToYourconfigfile);
config.start();</programlisting>
- <para>If you don't need to support a configuration file, just use <literal
- >ConfigurationImpl</literal> and change the config parameters accordingly, such as
- adding acceptors. </para>
- <para>The acceptors are configured through <literal>ConfigurationImpl</literal>. Just add
- the <literal>NettyAcceptorFactory</literal> on the transports the same way you would
- through the main configuration file.</para>
+ <para>如果不需要配置文件,可以用<literal>ConfigurationImpl</literal>,只要将其中的各种配置参数设置好
+ 即可。如添加适当的接收器。</para>
+ <para><literal>ConfigurationImpl</literal>用来配置接收器。和主要配置文件相似,只需要添加
+ <literal>NettyAcceptorFactory</literal>即可。</para>
<programlisting>import org.hornetq.core.config.Configuration;
import org.hornetq.core.config.impl.ConfigurationImpl;
@@ -63,9 +56,8 @@
transports.add(new TransportConfiguration(InVMAcceptorFactory.class.getName()));
config.setAcceptorConfigurations(transports);</programlisting>
- <para>You need to instantiate and start HornetQ server. The class <literal
- >org.hornetq.api.core.server.HornetQ</literal> has a few static methods for creating
- servers with common configurations.</para>
+ <para>接着就需要初始化并启动HornetQ服务。<literal
+ >org.hornetq.api.core.server.HornetQ</literal>类有一些静态方法可用来创建HornetQ服务器。</para>
<programlisting>import org.hornetq.api.core.server.HornetQ;
import org.hornetq.core.server.HornetQServer;
@@ -74,25 +66,22 @@
HornetQServer server = HornetQ.newHornetQServer(config);
server.start();</programlisting>
- <para>You also have the option of instantiating <literal>HornetQServerImpl</literal>
- directly:</para>
+ <para>你还可以直接实例化<literal>HornetQServerImpl</literal>:</para>
<programlisting>HornetQServer server =
new HornetQServerImpl(config);
server.start();</programlisting>
</section>
<section>
- <title>Dependency Frameworks</title>
- <para>You may also choose to use a dependency injection framework such as <trademark>JBoss
- Micro Container</trademark> or <trademark>Spring Framework</trademark>.</para>
- <para>HornetQ standalone uses JBoss Micro Container as the injection framework. <literal
- >HornetQBootstrapServer</literal> and <literal>hornetq-beans.xml</literal> which are
- part of the HornetQ distribution provide a very complete implementation of what's needed
- to bootstrap the server using JBoss Micro Container. </para>
- <para>When using JBoss Micro Container, you need to provide an XML file declaring the
- <literal>HornetQServer</literal> and <literal>Configuration</literal> object, you
- can also inject a security manager and a MBean server if you want, but those are
- optional.</para>
- <para>A very basic XML Bean declaration for the JBoss Micro Container would be:</para>
+ <title>使用依赖注入框架</title>
+ <para>你还可以使用一个依赖注入框架来启动HornetQ,比如<trademark>JBoss
+ Microcontainer</trademark>或<trademark>Spring框架</trademark>。</para>
+ <para>HornetQ独立服务器使用的是JBoss Microcontainer作为其框架。在HornetQ的发布中包括的<literal
+ >HornetQBootstrapServer</literal>和<literal>hornetq-beans.xml</literal>文件共同实现了
+ 在JBoss Microcontainer中对HornetQ服务器的引导。</para>
+ <para>要使用JBoss Microcontainer,需要在xml文件中声明<literal>HornetQServer</literal>
+ 和<literal>Configuration</literal>对象。另外还可以注入一个安全管理器和一个MBean服务器。但是这些
+ 注入是可选的。</para>
+ <para>下面是一个基本的JBoss Microcontainer的XML Bean的声明:</para>
<programlisting><?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="urn:jboss:bean-deployer:2.0">
@@ -112,19 +101,17 @@
</constructor>
</bean>
</deployment></programlisting>
- <para><literal>HornetQBootstrapServer</literal> provides an easy encapsulation of JBoss
- Micro Container.</para>
+ <para><literal>HornetQBootstrapServer</literal>实现了JBoss Microcontainer的简单封装。</para>
<programlisting>HornetQBootstrapServer bootStrap =
new HornetQBootstrapServer(new String[] {"hornetq-beans.xml"});
bootStrap.run();</programlisting>
</section>
<section>
- <title>Connecting to the Embedded HornetQ</title>
- <para>To connect clients to HornetQ you just create the factories as normal:</para>
+ <title>连接嵌入式HornetQ</title>
+ <para>嵌入式HornetQ的连接和普通的连接一样要创建连接工厂:</para>
<section>
- <title>Core API</title>
- <para>If using the core API, just create the <literal>ClientSessionFactory</literal> and
- use the regular core API.</para>
+ <title>核心接口</title>
+ <para>使用核心接口,需要创建一个<literal>ClientSessionFactory</literal>然后正常建立连接。</para>
<programlisting>ClientSessionFactory nettyFactory = HornetQClient.createClientSessionFactory(
new TransportConfiguration(
InVMConnectorFactory.class.getName()));
@@ -152,10 +139,9 @@
session.close();</programlisting>
</section>
<section>
- <title>JMS API</title>
- <para>Connection on an Embedded HornetQ through JMS is also simple. Just instantiate
- <literal>ConnectionFactory</literal> directly. The following example
- illustrates that.</para>
+ <title>JMS接口</title>
+ <para>使用JMS接口连接嵌入HornetQ同样简单。只需要直接实例化
+ <literal>ConnectionFactory</literal>即可。如下面例子所示:</para>
<programlisting>ConnectionFactory cf =
HornetQJMSClient.createConnectionFactory(
new TransportConfiguration(InVMConnectorFactory.class.getName()));
@@ -186,8 +172,7 @@
</section>
</section>
<section>
- <title>JMS Embedding Example</title>
- <para>Please see <xref linkend="examples.embedded"/> for an example which shows how to setup
- and run HornetQ embedded with JMS.</para>
+ <title>JMS嵌入式HornetQ的例子</title>
+ <para>有关如何设置与运行JMS嵌入式HornetQ的例子请参见<xref linkend="examples.embedded"/>。</para>
</section>
</chapter>
14 years, 10 months
JBoss hornetq SVN: r9200 - branches/HnetQ_323_cn/docs/user-manual/zh.
by do-not-reply@jboss.org
Author: gaohoward
Date: 2010-05-05 04:24:45 -0400 (Wed, 05 May 2010)
New Revision: 9200
Modified:
branches/HnetQ_323_cn/docs/user-manual/zh/logging.xml
Log:
done
Modified: branches/HnetQ_323_cn/docs/user-manual/zh/logging.xml
===================================================================
--- branches/HnetQ_323_cn/docs/user-manual/zh/logging.xml 2010-05-05 08:00:38 UTC (rev 9199)
+++ branches/HnetQ_323_cn/docs/user-manual/zh/logging.xml 2010-05-05 08:24:45 UTC (rev 9200)
@@ -17,39 +17,30 @@
<!-- permitted by applicable law. -->
<!-- ============================================================================= -->
<chapter id="logging">
- <title>Logging</title>
- <para>HornetQ has its own logging delegate that has no dependencies on any particular logging
- framework. The default delegate delegates all its logs to the standard <ulink
- url="http://java.sun.com/j2se/1.4.2/docs/guide/util/logging/">JDK logging</ulink>,
- (a.k.a Java-Util-Logging: JUL). By default the server picks up its JUL configuration from a
- <literal>logging.properties</literal> file found in the config directories. This is
- configured to use our own HornetQ logging formatter and will log to the console as well as a
- log file. For more information on configuring JUL visit Suns website.</para>
- <para>You can configure a different Logging Delegate programatically or via a System
- Property.</para>
- <para>To do this programatically simply do the
- following<programlisting>org.hornetq.core.logging.Logger.setDelegateFactory(new Log4jLogDelegateFactory())</programlisting></para>
- <para>Where <literal>Log4jLogDelegateFactory</literal> is the implementation of <literal
- >org.hornetq.spi.core.logging.LogDelegateFactory </literal>that you would like to
- use.</para>
- <para>To do this via a System Property simply set the property <literal
- >org.hornetq.logger-delegate-factory-class-name</literal> to the delegate factory being
- used,
- i.e.<programlisting>-Dorg.hornetq.logger-delegate-factory-class-name=org.hornetq.integration.logging.Log4jLogDelegateFactory</programlisting></para>
- <para>As you can see in the above example HornetQ provides some Delegate Factories for your
- convenience. these are<orderedlist
- ><listitem><para>org.hornetq.core.logging.impl.JULLogDelegateFactory - the
- default that uses
- JUL.</para></listitem><listitem><para>org.hornetq.integration.logging.Log4jLogDelegateFactory
- - which uses Log4J</para></listitem></orderedlist></para>
- <para>If you configure your client's logging to use the JUL delegate, make sure you provide a
- <literal>logging.properties</literal> file and set the <literal
- >java.util.logging.config.file</literal> property on client startup</para>
+ <title>日志(Logging)</title>
+ <para>HornetQ有自己的独立的日志系统,不依赖于任何其它的日志框架。在默认情况下所有HornetQ的日志将输入到
+ 标准的<ulink
+ url="http://java.sun.com/j2se/1.4.2/docs/guide/util/logging/">JDK日志系统</ulink>,
+ (即JUL-Java Util Logging)。服务器在默认条件下读取config目录下的
+ <literal>logging.properties</literal>文件做为JUL的配置文件。它配置了使用HornetQ自己的格式化
+ 方法,将日志输出到屏幕终端(Console)及文件中。请访问Sun公司的相关网址来进一步了解如何配置使用JUL。</para>
+ <para>你可以通过编程或定义系统变量的方法来配置不同的日志代理(Logging Delegate)。</para>
+ <para>采用编程方法,只需要调用方法:
+ <programlisting>org.hornetq.core.logging.Logger.setDelegateFactory(new Log4jLogDelegateFactory())</programlisting></para>
+ <para>其中<literal>Log4jLogDelegateFactory</literal>实现了<literal
+ >org.hornetq.spi.core.logging.LogDelegateFactory </literal>接口。</para>
+ <para>如果要使用系统变量方法,则需要设置变量<literal
+ >org.hornetq.logger-delegate-factory-class-name</literal>为相应的代理工厂,即
+ <programlisting>-Dorg.hornetq.logger-delegate-factory-class-name=org.hornetq.integration.logging.Log4jLogDelegateFactory</programlisting></para>
+ <para>上面的例子可以看出HornetQ提供了一些代理工厂以方便用户使用,它们是:<orderedlist
+ ><listitem><para>org.hornetq.core.logging.impl.JULLogDelegateFactory - 默认的JUL日志代理工厂。</para>
+ </listitem><listitem><para>org.hornetq.integration.logging.Log4jLogDelegateFactory
+ - Log4J的日志代理工厂。</para></listitem></orderedlist></para>
+ <para>如果在客户端使用JUL代理,注意要提供<literal>logging.properties</literal>文件,并且在客户端启动之前设置<literal
+ >java.util.logging.config.file</literal>属性。</para>
<section>
- <title>Logging With The JBoss Application Server</title>
- <para>When HornetQ is deployed within the JBoss Application Server version 5.x or above then
- it will still use JUL however the logging is redirected to the default JBoss logger. For
- more information on this refer to the JBoss documentation. In versions before this you
- must specify what logger delegate you want to use.</para>
+ <title>与JBoss应用服务器日志的关系</title>
+ <para>当HornetQ部署到JBoss应用服务器版本5.x或以上时,虽然HornetQ仍然使用JUL,但是所有的日志输出被重定向到
+ JBoss logger。请参阅相关的JBoss文档来了解更多的信息。如果是以前版本的JBoss,则必需指定你所需要的日志代理。</para>
</section>
</chapter>
14 years, 10 months
JBoss hornetq SVN: r9199 - branches/HnetQ_323_cn/docs/user-manual/zh.
by do-not-reply@jboss.org
Author: gaohoward
Date: 2010-05-05 04:00:38 -0400 (Wed, 05 May 2010)
New Revision: 9199
Modified:
branches/HnetQ_323_cn/docs/user-manual/zh/thread-pooling.xml
Log:
done
Modified: branches/HnetQ_323_cn/docs/user-manual/zh/thread-pooling.xml
===================================================================
--- branches/HnetQ_323_cn/docs/user-manual/zh/thread-pooling.xml 2010-05-05 03:10:14 UTC (rev 9198)
+++ branches/HnetQ_323_cn/docs/user-manual/zh/thread-pooling.xml 2010-05-05 08:00:38 UTC (rev 9199)
@@ -17,98 +17,74 @@
<!-- permitted by applicable law. -->
<!-- ============================================================================= -->
<chapter id="thread-pooling">
- <title>Thread management</title>
- <para>This chapter describes how HornetQ uses and pools threads and how you can manage
- them.</para>
- <para>First we'll discuss how threads are managed and used on the server side, then we'll look
- at the client side.</para>
+ <title>线程管理</title>
+ <para>本章讲述HornetQ如何使用线程池以及如何管理线程。</para>
+ <para>首先我们讨论在服务器端线程是如何被管理的,然后我们再讨论客户端的情况。</para>
<section>
- <title>Server-Side Thread Management</title>
- <para>Each HornetQ Server maintains a single thread pool for general use, and a scheduled
- thread pool for scheduled use. A Java scheduled thread pool cannot be configured to use
- a standard thread pool, otherwise we could use a single thread pool for both scheduled
- and non scheduled activity.</para>
- <para>There are also a small number of other places where threads are used directly, we'll
- discuss each in turn.</para>
+ <title>服务器端线程的管理</title>
+ <para>每个HornetQ服务器都有一个线程池作为一般线程使用,另外还有一个可计划线程池。Java的可计划线程池不能作为
+ 标准的线程池使用,因此我们采用了两个单独的线程池。</para>
+ <para>另外在其它一些地方直接使用了线程,没有用线程池。我们将对这些线程作出解释。</para>
<section id="server.scheduled.thread.pool">
- <title>Server Scheduled Thread Pool</title>
- <para>The server scheduled thread pool is used for most activities on the server side
- that require running periodically or with delays. It maps internally to a <literal
- >java.util.concurrent.ScheduledThreadPoolExecutor</literal> instance.</para>
- <para>The maximum number of thread used by this pool is configure in <literal
- >hornetq-configuration.xml</literal> with the <literal
- >scheduled-thread-pool-max-size</literal> parameter. The default value is
- <literal>5</literal> threads. A small number of threads is usually sufficient
- for this pool.</para>
+ <title>服务器端可计划线程池</title>
+ <para>服务器可计划线程池可以定期地或延迟地执行所交给的任务,它用来完成HornetQ中绝大部分这样的任务。
+ 它内部使用的是一个 <literal
+ >java.util.concurrent.ScheduledThreadPoolExecutor</literal>实例。</para>
+ <para>最大线程数可以在<literal
+ >hornetq-configuration.xml</literal>文件中进行配置,参数名是<literal
+ >scheduled-thread-pool-max-size</literal>。默认值是<literal>5</literal>。
+ 通常这个线程池不需要很大数量的线程。</para>
</section>
<section>
- <title>General Purpose Server Thread Pool</title>
- <para>This general purpose thread pool is used for most asynchronous actions on the
- server side. It maps internally to a <literal
- >java.util.concurrent.ThreadPoolExecutor</literal> instance.</para>
- <para>The maximum number of thread used by this pool is configure in <literal
- >hornetq-configuration.xml</literal> with the <literal
- >thread-pool-max-size</literal> parameter.</para>
- <para>If a value of <literal>-1</literal> is used this signifies that the thread pool
- has no upper bound and new threads will be created on demand if there are enough
- threads available to satisfy a request. If activity later subsides then threads are
- timed-out and closed.</para>
- <para>If a value of <literal>n</literal> where <literal>n</literal>is a positive integer
- greater than zero is used this signifies that the thread pool is bounded. If more
- requests come in and there are no free threads in the pool and the pool is full then
- requests will block until a thread becomes available. It is recommended that a
- bounded thread pool is used with caution since it can lead to dead-lock situations
- if the upper bound is chosen to be too low.</para>
- <para>The default value for <literal>thread-pool-max-size</literal> is <literal
- >-1</literal>, i.e. the thread pool is unbounded.</para>
- <para>See the <ulink
+ <title>服务器通用线程池</title>
+ <para>服务器端绝大部分的异步操作都是由这个线程池来完成的。在它的内部使用了一个<literal
+ >java.util.concurrent.ThreadPoolExecutor</literal>的实例。</para>
+ <para>这个线程池的最大线程数在<literal>hornetq-configuration.xml</literal>文件中配置,相应的参数名为<literal
+ >thread-pool-max-size</literal>。</para>
+ <para>如果将参数设为<literal>-1</literal>则表示该线程池没有线程限制。也就是说当线程不够用时,线程池就
+ 会创建新的线程。当任务不多时,空闲的线程将会超时并被关闭。</para>
+ <para>如果这个参数的值是一个大于零的整数<literal>n</literal>,则该线程池的线程数是有限的。当所有线程都
+ 处于忙的状态并且线程数已经达到n时,任何新的请求都将被阻塞直到有线程空闲为止。在设置线程上限时,我们建议
+ 要非常谨慎。因为如何线程数量过低会造成死锁情况的发生。</para>
+ <para><literal>thread-pool-max-size</literal>的默认值是<literal
+ >-1</literal>,即线程池没有上限。</para>
+ <para>参见<ulink
url="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadPoolEx..."
- >J2SE javadoc</ulink> for more information on unbounded (cached), and bounded
- (fixed) thread pools.</para>
+ >J2SE javadoc</ulink>有关无边界(缓存)和有边界(固定)线程池的解释。</para>
</section>
<section>
- <title>Expiry Reaper Thread</title>
- <para>A single thread is also used on the server side to scan for expired messages in
- queues. We cannot use either of the thread pools for this since this thread needs to
- run at its own configurable priority.</para>
- <para>For more information on configuring the reaper, please see <xref
- linkend="message-expiry"/>.</para>
+ <title>过期回收线程</title>
+ <para>HornetQ使用一个单独的线程来扫描队列中过期的消息。由于这个线程需要自己的优先级配置,所以不能使用上述的
+ 任何一个线程池。</para>
+ <para>关于回收线程的配置请参阅<xref linkend="message-expiry"/>。</para>
</section>
<section>
- <title>Asynchronous IO</title>
- <para>Asynchronous IO has a thread pool for receiving and dispatching events out of the
- native layer. You will find it on a thread dump with the prefix
- HornetQ-AIO-poller-pool. HornetQ uses one thread per opened file on the journal
- (there is usually one).</para>
- <para>There is also a single thread used to invoke writes on libaio. We do that to avoid
- context switching on libaio what would cause performance issues. You will find this
- thread on a thread dump with the prefix HornetQ-AIO-writer-pool.</para>
+ <title>异步IO</title>
+ <para>HornetQ使用一个线程池来进行异步IO的操作,包括事件的接收和发送。这些线程的名字都是以
+ HornetQ-AIO-poller-pool为开头。每个打开的日志文件都对应有一个线程为其服务(通常只有
+ 一个)。</para>
+ <para>还有一个单独的线程用于向libaio发送写请求。这样做是为了避免上下文转换带来的性能下降。该
+ 线程的名字以HornetQ-AIO-writer-pool开头。</para>
</section>
</section>
<section id="thread-pooling.client.side">
- <title>Client-Side Thread Management</title>
- <para>On the client side, HornetQ maintains a single static scheduled thread pool and a
- single static general thread pool for use by all clients using the same classloader in
- that JVM instance.</para>
- <para>The static scheduled thread pool has a maximum size of <literal>5</literal> threads,
- and the general purpose thread pool has an unbounded maximum size.</para>
- <para>If required HornetQ can also be configured so that each <literal
- >ClientSessionFactory</literal> instance does not use these static pools but instead
- maintains its own scheduled and general purpose pool. Any sessions created from that
- <literal>ClientSessionFactory</literal> will use those pools instead.</para>
- <para>To configure a <literal>ClientSessionFactory</literal> instance to use its own pools,
- simply use the appropriate setter methods immediately after creation, for
- example:</para>
+ <title>客户端线程管理</title>
+ <para>在客户端HornetQ有一个静态的可计划线程池和一个静态的通用线程池,它们在一个JVM中由同一个classloader装载的所有客户端
+ 共同使用。</para>
+ <para>静态的可计划的线程池的最大线程数为 <literal>5</literal>,通用线程池则没有线程数限制。</para>
+ <para>如果需要还可以配置一个<literal
+ >ClientSessionFactory</literal>实例以使它拥有自己的可计划与通用线程池。通过这个工厂创建的会话都
+ 将使用这些线程池。</para>
+ <para>要想配置<literal>ClientSessionFactory</literal>使用自己的线程池,只要调用它相应的方法取出可,如:</para>
<programlisting>ClientSessionFactory myFactory = HornetQClient.createClientSessionFactory(...);
myFactory.setUseGlobalPools(false);
myFactory.setScheduledThreadPoolMaxSize(10);
myFactory.setThreadPoolMaxSize(-1); </programlisting>
- <para>If you're using the JMS API, you can set the same parameters on the ClientSessionFactory and use it to create the <literal
- >ConnectionFactory</literal> instance, for example:</para>
+ <para>如果使用JMS,你可以先用同样的参数设置ClientSessionFactory,然后再用这样工厂创建<literal
+ >ConnectionFactory</literal>的实例。如:</para>
<programlisting>ConnectionFactory myConnectionFactory = HornetQJMSClient.createConnectionFactory(myFactory); </programlisting>
- <para>If you're using JNDI to instantiate <literal>HornetQConnectionFactory</literal>
- instances, you can also set these parameters in the <literal>hornetq-jms.xml</literal>
- file where you describe your connection factory, for example:</para>
+ <para>如果你使用JNDI来创建<literal>HornetQConnectionFactory</literal>
+ 实例,你还可以在<literal>hornetq-jms.xml</literal>文件中进行配置。如:</para>
<programlisting><connection-factory name="ConnectionFactory">
<connectors>
<connector-ref connector-name="netty"/>
14 years, 10 months
JBoss hornetq SVN: r9198 - branches/HnetQ_323_cn/docs/user-manual/zh.
by do-not-reply@jboss.org
Author: gaohoward
Date: 2010-05-04 23:10:14 -0400 (Tue, 04 May 2010)
New Revision: 9198
Modified:
branches/HnetQ_323_cn/docs/user-manual/zh/libaio.xml
Log:
done.
Modified: branches/HnetQ_323_cn/docs/user-manual/zh/libaio.xml
===================================================================
--- branches/HnetQ_323_cn/docs/user-manual/zh/libaio.xml 2010-05-04 15:23:51 UTC (rev 9197)
+++ branches/HnetQ_323_cn/docs/user-manual/zh/libaio.xml 2010-05-05 03:10:14 UTC (rev 9198)
@@ -17,87 +17,77 @@
<!-- permitted by applicable law. -->
<!-- ============================================================================= -->
<chapter id="libaio">
- <title>Libaio Native Libraries</title>
- <para>HornetQ distributes a native library, used as a bridge between HornetQ and linux
- libaio.</para>
- <para><literal>libaio</literal> is a library, developed as part of the linux kernel project.
- With <literal>libaio</literal> we submit writes to the operating system where they are
- processed asynchronously. Some time later the OS will call our code back when they have been
- processed.</para>
- <para>We use this in our high performance journal if configured to do so, please see <xref
- linkend="persistence"/>.</para>
- <para>These are the native libraries distributed by HornetQ:</para>
+ <title>Libaio平台专有库</title>
+ <para>HornetQ发布包中包括一个平台专有的库,它可以使HornetQ使用Linux操作系统的libaio。</para>
+ <para><literal>libaio</literal>是Linux项目的一个库。它将用户提交的写操作用异步的方式执行。通过
+ 回调用户的代码来通知写操作的完成。</para>
+ <para>通过配置,HornetQ可以使用这个库来访问高性能的日志,具体请参见 <xref
+ linkend="persistence"/>。</para>
+ <para>下面列出了HornetQ所带的平台专有库文件:</para>
<itemizedlist>
<listitem>
- <para>libHornetQAIO32.so - x86 32 bits</para>
+ <para>libHornetQAIO32.so - x86 32 位平台</para>
</listitem>
<listitem>
- <para>libHornetQAIO64.so - x86 64 bits</para>
+ <para>libHornetQAIO64.so - x86 64 位平台</para>
</listitem>
</itemizedlist>
- <para>When using libaio, HornetQ will always try loading these files as long as they are on the
- <link linkend="using-server.library.path">library path</link>.</para>
+ <para>当使用libaio时,HornetQ会在<link linkend="using-server.library.path">库路径</link>中寻找并装
+ 载这些文件。</para>
<section>
- <title>Compiling the native libraries</title>
- <para>In the case that you are using Linux on a platform other than x86_32 or x86_64
- (for example Itanium 64 bits or IBM Power) you may need to compile the native library, since we
- do not distribute binaries for those platforms with the release.</para>
+ <title>库文件的编译</title>
+ <para>如果你的Linux平台不是x86_32或x86_64(比如Itanium 64或IBM Power),你需要自己编译相应的库文件,
+ 因为HornetQ不提供这些平台的库文件。</para>
<section>
- <title>Install requirements</title>
+ <title>安装要求</title>
<note>
- <para>At the moment the native layer is only available on Linux. If you are in a
- platform other than Linux the native compilation will not work</para>
+ <para>目前libaio只在Linux上有。所以它不可能在其它操作系统上编译。</para>
</note>
- <para>The native library uses <ulink url="http://en.wikipedia.org/wiki/Autoconf"
- >autoconf</ulink> what makes the compilation process easy, however you need to
- install extra packages as a requirement for compilation:</para>
+ <para>编译需要<ulink url="http://en.wikipedia.org/wiki/Autoconf"
+ >autoconf</ulink>工具,它用来简化编译过程。除此之外还需要一些安装包:</para>
<itemizedlist>
<listitem>
- <para>gcc - C Compiler</para>
+ <para>gcc - C 编译器</para>
</listitem>
<listitem>
- <para>gcc-c++ or g++ - Extension to gcc with support for C++</para>
+ <para>gcc-c++ or g++ - gcc的c++编译工具扩展</para>
</listitem>
<listitem>
- <para>autoconf - Tool for automating native build process</para>
+ <para>autoconf - 自动编译工具</para>
</listitem>
<listitem>
- <para>make - Plain old make</para>
+ <para>make - make 工具</para>
</listitem>
<listitem>
- <para>automake - Tool for automating make generation</para>
+ <para>automake - make文件自动生成工具</para>
</listitem>
<listitem>
- <para>libtool - Tool for link editing native libraries</para>
+ <para>libtool - 库连接工具</para>
</listitem>
<listitem>
- <para>libaio - library to disk asynchronous IO kernel functions</para>
+ <para>libaio - 磁盘异步IO库</para>
</listitem>
<listitem>
- <para>libaio-dev - Compilation support for libaio</para>
+ <para>libaio-dev - libaio的编译支持</para>
</listitem>
<listitem>
- <para>A full JDK installed with the environment variable JAVA_HOME set to its
- location</para>
+ <para>完整的JDK,JAVA_HOME要指向正确的位置</para>
</listitem>
</itemizedlist>
- <para>To perform this installation on RHEL or Fedora, you can simply type this at a
- command line:</para>
+ <para>如果在RHEL或Fedora上进行安装,输入以下命令:</para>
<programlisting>sudo yum install automake libtool autoconf gcc-g++ gcc libaio libaio-dev make</programlisting>
- <para>Or on debian systems:</para>
+ <para>如果是 debian系统,则:</para>
<programlisting>sudo apt-get install automake libtool autoconf gcc-g++ gcc libaio libaio-dev make</programlisting>
<note>
- <para>You could find a slight variation of the package names depending on the
- version and linux distribution. (for example gcc-c++ on Fedora versus g++ on
- Debian systems)</para>
+ <para>在有些Linux的版本中上述的安装包名可能有一些差别。(例如Fedora中的gcc-c++在Debian系统中
+ 的名称为g++)</para>
</note>
</section>
<section>
- <title>Invoking the compilation</title>
- <para>In the distribution, in the <literal>native-src</literal> directory, execute the
- shell script <literal>bootstrap</literal>. This script will invoke <literal
- >automake</literal> and <literal>make</literal> what will create all the make
- files and the native library.</para>
+ <title>开始编译</title>
+ <para>在HornetQ发布包的<literal>native-src</literal>目录下,执行shell脚本
+ <literal>bootstrap</literal>。这个脚本会调用 <literal
+ >automake</literal>以及<literal>make</literal>来创建所有的make文件和专有库。</para>
<programlisting>someUser@someBox:/messaging-distribution/native-src$ ./bootstrap
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
@@ -114,12 +104,11 @@
config.status: executing libtool commands
...</programlisting>
- <para>The produced library will be at <literal
- >./native-src/src/.libs/libHornetQAIO.so</literal>. Simply move that file over
- <literal>bin</literal> on the distribution or the place you have chosen on the
- <link linkend="using-server.library.path">library path</link>.</para>
- <para>If you want to perform changes on the HornetQ libaio code, you could just call
- make directly at the <literal>native-src</literal> directory.</para>
+ <para>编译好的库文件在<literal
+ >./native-src/src/.libs/libHornetQAIO.so</literal>。将该文件移到发布包的
+ <literal>bin</literal>目录下,或者你的<link linkend="using-server.library.path">库目录</link>
+ 所指向的目录即可。</para>
+ <para>如果你修改了HornetQ的libaio代码,只需要在<literal>native-src</literal>目录下直挂运行make即可完成编译。</para>
</section>
</section>
</chapter>
14 years, 10 months
JBoss hornetq SVN: r9197 - branches/HnetQ_323_cn/docs/user-manual/zh.
by do-not-reply@jboss.org
Author: gaohoward
Date: 2010-05-04 11:23:51 -0400 (Tue, 04 May 2010)
New Revision: 9197
Modified:
branches/HnetQ_323_cn/docs/user-manual/zh/ha.xml
Log:
done
Modified: branches/HnetQ_323_cn/docs/user-manual/zh/ha.xml
===================================================================
--- branches/HnetQ_323_cn/docs/user-manual/zh/ha.xml 2010-05-04 11:27:41 UTC (rev 9196)
+++ branches/HnetQ_323_cn/docs/user-manual/zh/ha.xml 2010-05-04 15:23:51 UTC (rev 9197)
@@ -17,81 +17,56 @@
<!-- permitted by applicable law. -->
<!-- ============================================================================= -->
<chapter id="ha">
- <title>High Availability and Failover</title>
- <para>We define high availability as the <emphasis>ability for the system to continue
- functioning after failure of one or more of the servers</emphasis>.</para>
- <para>A part of high availability is <emphasis>failover</emphasis> which we define as the
- <emphasis>ability for client connections to migrate from one server to another in event
- of server failure so client applications can continue to operate</emphasis>.</para>
+ <title>高可获得性(High Availability)和失效备援(Failover)</title>
+ <para>高可获得性是指<emphasis>当系统中有一台甚至多台服务器发生故障时还能继续运转的能力</emphasis>。</para>
+ <para>作为高可获得性的一部分,<emphasis>失效备援</emphasis>的含意是
+ <emphasis>当客户端当前连接的服务器发故障时,客户端可以将连接转到另一台正常的服务器,从而能够继续工作</emphasis>。</para>
<section>
- <title>Live - Backup Pairs</title>
- <para>HornetQ allows pairs of servers to be linked together as <emphasis>live -
- backup</emphasis> pairs. In this release there is a single backup server for each
- live server. A backup server is owned by only one live server. Backup servers are not
- operational until failover occurs.</para>
- <para>Before failover, only the live server is serving the HornetQ clients while the backup
- server remains passive. When clients fail over to the backup server, the backup server
- becomes active and starts to service the HornetQ clients.</para>
+ <title>主要-备份对</title>
+ <para>HornetQ可以将两个服务器以<emphasis>主要-备份对</emphasis>的形式连接在一起。目前HornetQ允许一个
+ 主要服务器有一个备份服务器,一个备份服务器只有一个主要服务器。在正常情况下主要服务器工作,备份服务器只有当
+ 发生失效备援发生时工作。</para>
+ <para>没有发生失效备援时,主要服务器为客户端提供服务,备份服务器处于待机状态。当客户端在失效备援后连接到备份服务
+ 器时,备份服务器开始激活并开始工作。</para>
<section id="ha.mode">
- <title>HA modes</title>
- <para>HornetQ provides two different modes for high availability, either by
- <emphasis>replicating data</emphasis> from the live server journal to the backup
- server or using a <emphasis>shared store</emphasis> for both servers.</para>
+ <title>高可获得性(HA)的模式</title>
+ <para>HornetQ的高可获得性有两种模式:一种模式通过由主服务器日志向备份服务器日志
+ <emphasis>复制数据</emphasis>。另一种模式则是主服务器与备份服务器间<emphasis>存贮共享</emphasis>。</para>
<note>
- <para>Only persistent message data will survive failover. Any non persistent message
- data will not be available after failover.</para>
+ <para>只有持久消息才可以在失效备援时不丢失。所有非持久消息则会丢失。</para>
</note>
<section id="ha.mode.replicated">
- <title>Data Replication</title>
- <para>In this mode, data stored in the HornetQ journal are replicated from the live
- server's journal to the backup server's journal. Note that we do not replicate
- the entire server state, we only replicate the journal and other persistent
- operations.</para>
- <para>Replication is performed in an asynchronous fashion between live and backup
- server. Data is replicated one way in a stream, and responses that the data has
- reached the backup is returned in another stream. Pipelining replications and
- responses to replications in separate streams allows replication throughput to
- be much higher than if we synchronously replicated data and waited for a
- response serially in an RPC manner before replicating the next piece of
- data.</para>
- <para>When the user receives confirmation that a transaction has committed, prepared
- or rolled back or a durable message has been sent, we can guarantee it has
- reached the backup server and been persisted.</para>
- <para>Data replication introduces some inevitable performance overhead compared to
- non replicated operation, but has the advantage in that it requires no expensive
- shared file system (e.g. a SAN) for failover, in other words it is a <emphasis
- role="italic">shared-nothing</emphasis> approach to high
- availability.</para>
- <para>Failover with data replication is also faster than failover using shared
- storage, since the journal does not have to be reloaded on failover at the
- backup node.</para>
+ <title>数据复制</title>
+ <para>在这种模式下,保存在HornetQ主服务器中日志中的数据被复制到备份服务器日志中。注意我们并不复制
+ 服务器的全部状态,而是只复制日志和其它的持久性质的操作。</para>
+ <para>复制的操作是异步进行的。数据通过流的方式复制,复制的結果则通过另一个流来返回。通过这样的异步方式
+ 我们可以获得比同步方式更大的呑吐量。</para>
+ <para>当用户得到确认信息如一个事务已经提交、准备或加滚,或者是一个持久消息被发送时,HornetQ确保这些状态
+ 已经复制到备份服务器上并被持久化。</para>
+ <para>数据复制这种方式不可避免地影响性能,但是另一方面它不依赖于昂贵的文件共享设备(如SAN)。它实际上是
+ 一种<emphasis role="italic">无共享</emphasis>的HA方式。</para>
+ <para>采用数据复制的失效备援比采用共享存储的失效备援要快,这是因为备份服务器在失效备援时不用重新装载日志。</para>
<graphic fileref="images/ha-replicated-store.png" align="center"/>
<section id="configuring.live.backup">
- <title>Configuration</title>
- <para>First, on the live server, in <literal
- >hornetq-configuration.xml</literal>, configure the live server with
- knowledge of its backup server. This is done by specifying a <literal
- >backup-connector-ref</literal> element. This element references a
- connector, also specified on the live server which specifies how to connect
- to the backup server.</para>
- <para>Here's a snippet from live server's <literal
- >hornetq-configuration.xml</literal> configured to connect to its backup
- server:</para>
+ <title>配置</title>
+ <para>首先在主服务器的 <literal>hornetq-configuration.xml</literal>文件中配置备份服务器。
+ 配置的参数是<literal>backup-connector-ref</literal>。这个参数指向一个连接器。这个连接器
+ 也在主服务器上配置。它定义了如何与备份服务器建立连接。</para>
+ <para>下面就是一个在<literal>hornetq-configuration.xml</literal>文件中的例子:</para>
<programlisting>
<backup-connector-ref connector-name="backup-connector"/>
<connectors>
- <!-- This connector specifies how to connect to the backup server -->
- <!-- backup server is located on host "192.168.0.11" and port "5445" -->
+ <!-- 这个连接器用于连接备份服务喝咖啡 -->
+ <!-- 备份服务器在主机"192.168.0.11"上,端口"5445" -->
<connector name="backup-connector">
<factory-class>org.hornetq.integration.transports.netty.NettyConnectorFactory</factory-class>
<param key="host" value="192.168.0.11"/>
<param key="port" value="5445"/>
</connector>
</connectors></programlisting>
- <para>Secondly, on the backup server, we flag the server as a backup and make
- sure it has an acceptor that the live server can connect to. We also make
- sure the shared-store paramater is set to false:</para>
+ <para>其次在备份服务器上,我们设置了备份服务器的标志,并且配置了相应的接受器以便主服务器能够建立
+ 连接。同时我们将shared-store参数设为false。</para>
<programlisting>
<backup>true</backup>
@@ -105,280 +80,191 @@
</acceptor>
</acceptors>
</programlisting>
- <para>For a backup server to function correctly it's also important that it has
- the same set of bridges, predefined queues, cluster connections, broadcast
- groups and discovery groups as defined on the live node. The easiest way to
- ensure this is to copy the entire server side configuration from live to
- backup and just make the changes as specified above. </para>
+ <para>为了使备份服务器正常工作,一定要保证它与主服务器有着同样的桥、预定义的队列、集群连接、
+ 广播组和发现组。最简单的作法是拷贝主服务器的全部配置然后再进行上述的修改。 </para>
</section>
<section>
- <title>Synchronizing a Backup Node to a Live Node</title>
- <para>In order for live - backup pairs to operate properly, they must be
- identical replicas. This means you cannot just use any backup server that's
- previously been used for other purposes as a backup server, since it will
- have different data in its persistent storage. If you try to do so, you will
- receive an exception in the logs and the server will fail to start.</para>
- <para>To create a backup server for a live server that's already been used for
- other purposes, it's necessary to copy the <literal>data</literal> directory
- from the live server to the backup server. This means the backup server will
- have an identical persistent store to the backup server.</para>
- <para>One a live server has failed over onto a backup server, the old live
- server becomes invalid and cannot just be restarted. To resynchonize the
- pair as a working live backup pair again, both servers need to be stopped,
- the data copied from the live node to the backup node and restarted
- again.</para>
- <para>The next release of HornetQ will provide functionality for automatically
- synchronizing a new backup node to a live node without having to temporarily
- bring down the live node.</para>
+ <title>备份服务器与主服务器间的同步</title>
+ <para>为了能正常工作,备份服务器与主服务器必须同步。这意谓着备份服务器不能是当前任意一个备份服
+ 务器。如果你这样做,主服务器将不能成功启动,在日志中会出现异常。</para>
+ <para>要想将一个现有的服务器配置成一个备份服务器,你需要将主服务器的<literal>data</literal>
+ 文件夹拷贝到并覆盖这个备份
+ 服务器的相同文件夹,这样做保证了备份服务器与主服务器的持久化数据完全一致。</para>
+ <para>当失效备援发生后,备份服务器代替主服务器工作,原来的主服务器失效。这时简单的重启主服务
+ 器是不行的。要想将主服务器与备份重新进行同步,就必须先将主服务器和备份服务器同时停止,再将
+ 主服务器的数据拷贝到备份服务器,然后再启动。</para>
+ <para>HornetQ以后将支持备份与主服务器间的自动同步,无需停止主服务器。</para>
</section>
</section>
<section id="ha.mode.shared">
- <title>Shared Store</title>
- <para>When using a shared store, both live and backup servers share the
- <emphasis>same</emphasis> journal using a shared file system. </para>
- <para>When failover occurs and the backup server takes over, it will load the
- persistent storage from the shared file system and clients can connect to
- it.</para>
- <para>This style of high availability differs from data replication in that it
- requires a shared file system which is accessible by both the live and backup
- nodes. Typically this will be some kind of high performance Storage Area Network
- (SAN). We do not recommend you use Network Attached Storage (NAS), e.g. NFS
- mounts to store any shared journal (NFS is slow).</para>
- <para>The advantage of shared-store high availability is that no replication occurs
- between the live and backup nodes, this means it does not suffer any performance
- penalties due to the overhead of replication during normal operation.</para>
- <para>The disadvantage of shared store replication is that it requires a shared file
- system, and when the backup server activates it needs to load the journal from
- the shared store which can take some time depending on the amount of data in the
- store.</para>
- <para>If you require the highest performance during normal operation, have access to
- a fast SAN, and can live with a slightly slower failover (depending on amount of
- data), we recommend shared store high availability</para>
+ <title>存贮共享</title>
+ <para>使用存贮共享,主服务器与备份服务器共用<emphasis>相同</emphasis>的日志,通常是一个共享的
+ 文件系统。</para>
+ <para>当发生失效备援时,工作由备份服务器接管。它首先从共享的文件系统中读取主服务器的持久数据,然后
+ 才能接受客户端的连接请求。</para>
+ <para>与数据复制方式不同的是这种方式需要一个共享的文件系统,主服务器与备份服务器都可以访问。典型的
+ 高性能的共享系统是存贮区域网络(SAN)系统。我们不建议使用网络附加存贮(NAS),如NFS,来存贮共享
+ 日志(主要的原因是它们比较慢)。</para>
+ <para>共享存贮的优点是不需要在主服务器与备份服务器之间进行数据复制,因此对性能不会造成影响。</para>
+ <para>共享存贮的缺点是它需要一个共享文件系统。同时,当备份服务器激活时它需要首先从共享日志中读取相应
+ 的信息,从而占用一定的时间。</para>
+ <para>如果你需要在一般工作情况下保持高性能,并且拥有一个快速的SAN系统,同时能够容忍较慢的失效备援
+ 过程(取决于数据量在多少),我们建议你采用存贮共享方式的高可获得性。</para>
<graphic fileref="images/ha-shared-store.png" align="center"/>
<section id="ha/mode.shared.configuration">
- <title>Configuration</title>
- <para>To configure the live and backup server to share their store, configure
- both <literal>hornetq-configuration.xml</literal>:</para>
+ <title>配置</title>
+ <para>要使用存贮共享模式,在两个服务器的配置文件<literal>hornetq-configuration.xml</literal>
+ 中将作如下设置:</para>
<programlisting>
<shared-store>true<shared-store>
</programlisting>
- <para>In order for live - backup pairs to operate properly with a shared store,
- both servers must have configured the location of journal directory to point
- to the <emphasis>same shared location</emphasis> (as explained in <xref
- linkend="configuring.message.journal"/>)</para>
- <para>If clients will use automatic failover with JMS, the live server will need
- to configure a connector to the backup server and reference it from its
- <literal>hornetq-jms.xml</literal> configuration as explained in <xref
- linkend="ha.automatic.failover"/>.</para>
+ <para>另外,需要将主服务器和备份服务器的日志文件位置指向<emphasis>同一个共享位置</emphasis>。
+ (参见<xref linkend="configuring.message.journal"/>)</para>
+ <para>如果客户端使用JMS自动失效备援,主服务器除了要配置一个连接器以连接到备份服务器外,还要在
+ 配置文件<literal>hornetq-jms.xml</literal>中指向这个连接器,如
+ <xref linkend="ha.automatic.failover"/>中所解释的那样。</para>
</section>
<section>
- <title>Synchronizing a Backup Node to a Live Node</title>
- <para>As both live and backup servers share the same journal, they do not need
- to be synchronized. However until, both live and backup servers are up and
- running, high-availability can not be provided with a single server. After
- failover, at first opportunity, stop the backup server (which is active) and
- restart the live and backup servers.</para>
- <para>In the next release of HornetQ we will provide functionality to
- automatically synchronize a new backup server with a running live server
- without having to temporarily bring the live server down.</para>
+ <title>备份服务器与主服务器间的同步。</title>
+ <para>由于主备服务器之间共享存贮,所以它们不需要进行同步。但是它需要主备服务器同时工作以提供
+ 高可获得性。如果一量发生失效备援后,就需要在尽可能早的时间内将备份服务器(处于工作状态)停下来,
+ 然后再启动主服务器和备份服务器。</para>
+ <para>HornetQ以后将支持自动同步功能,不需要先停止服务器。</para>
</section>
</section>
</section>
</section>
<section id="failover">
- <title>Failover Modes</title>
- <para>HornetQ defines two types of client failover:</para>
+ <title>失效备援的模式</title>
+ <para>HornetQ定义了两种客户端的失效备援:</para>
<itemizedlist>
<listitem>
- <para>Automatic client failover</para>
+ <para>自动客户端失效备援</para>
</listitem>
<listitem>
- <para>Application-level client failover</para>
+ <para>应用层的客户端失效备援</para>
</listitem>
</itemizedlist>
- <para>HornetQ also provides 100% transparent automatic reattachment of connections to the
- same server (e.g. in case of transient network problems). This is similar to failover,
- except it's reconnecting to the same server and is discussed in <xref
- linkend="client-reconnection"/></para>
- <para>During failover, if the client has consumers on any non persistent or temporary
- queues, those queues will be automatically recreated during failover on the backup node,
- since the backup node will not have any knowledge of non persistent queues.</para>
+ <para>HornetQ还支持100%透明的同一个服务器的自动连接恢复(适用于网络的临时性故障)。这与失效备援很相似,
+ 只不过连接的是同一个服务器,参见<xref linkend="client-reconnection"/>。</para>
+ <para>在发生失效备援时,如果客户端有非持久或临时队列的接收者时,这些队列会自动在备份服务器上重新创建。对于
+ 非持久性的队列,备份服务器事先是没有它们的信息的。</para>
<section id="ha.automatic.failover">
- <title>Automatic Client Failover</title>
- <para>HornetQ clients can be configured with knowledge of live and backup servers, so
- that in event of connection failure at the client - live server connection, the
- client will detect this and reconnect to the backup server. The backup server will
- then automatically recreate any sessions and consumers that existed on each
- connection before failover, thus saving the user from having to hand-code manual
- reconnection logic.</para>
- <para>HornetQ clients detect connection failure when it has not received packets from
- the server within the time given by <literal>client-failure-check-period</literal>
- as explained in section <xref linkend="connection-ttl"/>. If the client does not
- receive data in good time, it will assume the connection has failed and attempt
- failover.</para>
- <para>HornetQ clients can be configured with the list of live-backup server pairs in a
- number of different ways. They can be configured explicitly or probably the most
- common way of doing this is to use <emphasis>server discovery</emphasis> for the
- client to automatically discover the list. For full details on how to configure
- server discovery, please see <xref linkend="clusters.server-discovery"/>.
- Alternatively, the clients can explicitly specifies pairs of live-backup server as
- explained in <xref linkend="clusters.static.servers"/>.</para>
- <para>To enable automatic client failover, the client must be configured to allow
- non-zero reconnection attempts (as explained in <xref linkend="client-reconnection"
- />).</para>
- <para>Sometimes you want a client to failover onto a backup server even if the live
- server is just cleanly shutdown rather than having crashed or the connection failed.
- To configure this you can set the property <literal
- >FailoverOnServerShutdown</literal> to true either on the <literal
- >HornetQConnectionFactory</literal> if you're using JMS or in the <literal
- >hornetq-jms.xml</literal> file when you define the connection factory, or if
- using core by setting the property directly on the <literal
- >ClientSessionFactoryImpl</literal> instance after creation. The default value
- for this property is <literal>false</literal>, this means that by default
- <emphasis>HornetQ clients will not failover to a backup server if the live
- server is simply shutdown cleanly.</emphasis></para>
+ <title>自动客户端失效备援</title>
+ <para>HornetQ的客户端可以配置主/备份服务器的信息,当客户端与主服务器的连接发生故障时,可以自动检测到故障并
+ 进行失效备援处理,让客户端连接到备份服务器上。备份服务器可以自动重新创建所有在失效备援之前存在的会话与接收
+ 者。客户端不需要进行人工的连接恢复工作,从而节省了客户端的开发工作。</para>
+ <para>HornetQ的客户端在参数<literal>client-failure-check-period</literal>(在
+ <xref linkend="connection-ttl"/>中进行了解释)规定的时间内如果没有收到数据包,则认为连接发生故障。
+ 当客户端认为连接故障时,它就会尝试进行失效备援。</para>
+ <para>HornetQ有几种方法来为客户端配置主/备服务器对的列表。可以采用显式指定的方法,或者采用更为常用的
+ <emphasis>服务器发现</emphasis>的方法。有关如何配置服务器发现的详细信息,请参见
+ <xref linkend="clusters.server-discovery"/>。
+ 关于如何显式指定主/备服务器对的方法,请参见<xref linkend="clusters.static.servers"/>中的解释。</para>
+ <para>要使客户端具备自动失效备援,在客户端的配置中必须要指定重试的次数要大于零(参见
+ <xref linkend="client-reconnection"/>中的解释)。</para>
+ <para>有时你需要在主服务器正常关机的情况下仍然进行失效备援。如果使用JMS,你需要将<literal
+ >HornetQConnectionFactory</literal>的<literal
+ >FailoverOnServerShutdown</literal>属性设为true,或者是在<literal
+ >hornetq-jms.xml</literal>文件中进行相应的配置。如果使用的是核心接口,可以在创建
+ <literal>ClientSessionFactoryImpl</literal>实例时将上述同名属性设置为true。
+ 这个属性的默认值是false。这表示如果主服务器是正常关机,<emphasis>客户端将不会进行失效备援</emphasis>。</para>
<para>
<note>
- <para>By default, cleanly shutting down the server <emphasis role="bold">will
- not</emphasis> trigger failover on the client.</para>
- <para>Using CTRL-C on a HornetQ server or JBoss AS instance causes the server to
- <emphasis role="bold">cleanly shut down</emphasis>, so will not trigger
- failover on the client. </para>
- <para>If you want the client to failover when its server is cleanly shutdown
- then you must set the property <literal>FailoverOnServerShutdown</literal>
- to true</para>
+ <para>默认正常关机<emphasis role="bold">不会</emphasis>不会导致失效备援。</para>
+ <para>使用CTRL-C来关闭HornetQ服务器或JBoss应用服务器属于正常关机,所以不会触发客户端的失效
+ 备援。</para>
+ <para>要想在这种情况下进行失效备援必须将属性<literal>FailoverOnServerShutdown</literal>
+ 设为true。</para>
</note>
</para>
- <para>For examples of automatic failover with transacted and non-transacted JMS
- sessions, please see <xref linkend="examples.transaction-failover"/> and <xref
- linkend="examples.non-transaction-failover"/>.</para>
+ <para>有关事务性及非事务性JMS会话的自动失效备援的例子,请参见
+ <xref linkend="examples.transaction-failover"/>及<xref
+ linkend="examples.non-transaction-failover"/>。</para>
<section id="ha.automatic.failover.noteonreplication">
- <title>A Note on Server Replication</title>
- <para>HornetQ does not replicate full server state betwen live and backup servers.
- When the new session is automatically recreated on the backup it won't have any
- knowledge of messages already sent or acknowledged in that session. Any
- in-flight sends or acknowledgements at the time of failover might also be
- lost.</para>
- <para>By replicating full server state, theoretically we could provide a 100%
- transparent seamless failover, which would avoid any lost messages or
- acknowledgements, however this comes at a great cost: replicating the full
- server state (including the queues, session, etc.). This would require
- replication of the entire server state machine; every operation on the live
- server would have to replicated on the replica server(s) in the exact same
- global order to ensure a consistent replica state. This is extremely hard to do
- in a performant and scalable way, especially when one considers that multiple
- threads are changing the live server state concurrently.</para>
- <para>It is possible to provide full state machine replication using
- techniques such as <emphasis role="italic">virtual synchrony</emphasis>, but
- this does not scale well and effectively serializes all operations to a single
- thread, dramatically reducing concurrency.</para>
- <para>Other techniques for multi-threaded active replication exist such as
- replicating lock states or replicating thread scheduling but this is very hard
- to achieve at a Java level.</para>
- <para>Consequently it xas decided it was not worth massively reducing performance
- and concurrency for the sake of 100% transparent failover. Even without 100%
- transparent failover, it is simple to guarantee <emphasis role="italic">once and
- only once</emphasis> delivery, even in the case of failure, by using a
- combination of duplicate detection and retrying of transactions. However this is
- not 100% transparent to the client code.</para>
+ <title>关于服务器的复制</title>
+ <para>HornetQ在主服务器向备份服务器复制时,并不复制服务器的全部状态。所以当一个会话在备份服务器
+ 中重新创建后,它并不知道发送过的消息或通知过的消息。在失效备援的过程中发生的消息发送或通知也可
+ 能丢失。</para>
+ <para>理论上如果进行全部状态的复制,我们可以提供100%的透明的失效备援,不会失去任何的消息或通知。
+ 但是这样做要付出很大的代价:即所有信息都要进行复制(包括队列,会话等等)。也就是要求复制服务
+ 器的每个状态信息,主服务器的每一步操作都将向其备份进行复制,并且要在全局内保持顺序的一致。这样
+ 做就极难保证高性能和可扩展性,特别是考虑到多线程同时改变主服务器的状态的情况,要进行全状态复制
+ 就更加困难。</para>
+ <para>一些技术可以用来实现全状态复制,如<emphasis role="italic">虚拟同步技术
+ (virtual synchrony)</emphasis>。但是这些技术往往没有很好的可扩展性,并且将所有操作都
+ 进行序列化,由单一线程进行处理,这样明显地将底了并行处理能力。</para>
+ <para>另外还有其它一些多线程主动复制技术,比如复制锁状态或复制线程调度等。这些技术使用Java语言非常
+ 难于实现。</para>
+ <para>因此得出结论,采用大量牺牲性能来换取100%透明的失效备援是得不偿失的。没有100%透明的失效
+ 备援我们仍然可以轻易地保证一次且只有一次的传递。这是通过在发生故障时采用重复检测结合事务重试
+ 来实现的。</para>
</section>
<section id="ha.automatic.failover.blockingcalls">
- <title>Handling Blocking Calls During Failover</title>
- <para>If the client code is in a blocking call to the server, waiting for a response
- to continue its execution, when failover occurs, the new session will not have
- any knowledge of the call that was in progress. This call might otherwise hang
- for ever, waiting for a response that will never come.</para>
- <para>To prevent this, HornetQ will unblock any blocking calls that were in progress
- at the time of failover by making them throw a <literal
- >javax.jms.JMSException</literal> (if using JMS), or a <literal
- >HornetQException</literal> with error code <literal
- >HornetQException.UNBLOCKED</literal>. It is up to the client code to catch
- this exception and retry any operations if desired.</para>
- <para>If the method being unblocked is a call to commit(), or prepare(), then the
- transaction will be automatically rolled back and HornetQ will throw a <literal
- >javax.jms.TransactionRolledBackException</literal> (if using JMS), or a
- <literal>HornetQException</literal> with error code <literal
- >HornetQException.TRANSACTION_ROLLED_BACK</literal> if using the core
- API.</para>
+ <title>失效备援时阻塞调用的处理</title>
+ <para>如果当发生失效备援时客户端正面进行一个阻塞调用并等待服务器的返回,新创建的会话不会知道这个调用,
+ 因此客户端可能永远也不会得到响应,也就可能一直阻塞在那里。</para>
+ <para>为了防止这种情况的发生,HornetQ在失效备援时会解除所有的阻塞调用,同时抛出一个
+ <literal>javax.jms.JMSException</literal>异常(如果是JMS)或<literal
+ >HornetQException</literal>异常。异常的错误代码是<literal
+ >HornetQException.UNBLOCKED</literal>。客户端需要自行处理这个异常,并且进行
+ 必要的操作重试。</para>
+ <para>如果被解除阻塞的调用是commit()或者prepare(),那么这个事务会被自动地回滚,并且HornetQ
+ 会抛出一个<literal>javax.jms.TransactionRolledBackException</literal>(如果是JMS)
+ 或都是一个<literal>HornetQException</literal>,错误代码为 <literal
+ >HornetQException.TRANSACTION_ROLLED_BACK</literal>(如果是核心接口)。</para>
</section>
<section id="ha.automatic.failover.transactions">
- <title>Handling Failover With Transactions</title>
- <para>If the session is transactional and messages have already been sent or
- acknowledged in the current transaction, then the server cannot be sure that
- messages sent or acknowledgements have not been lost during the failover.</para>
- <para>Consequently the transaction will be marked as rollback-only, and any
- subsequent attempt to commit it will throw a <literal
- >javax.jms.TransactionRolledBackException</literal> (if using JMS), or a
- <literal>HornetQException</literal> with error code <literal
- >HornetQException.TRANSACTION_ROLLED_BACK</literal> if using the core
- API.</para>
- <para>It is up to the user to catch the exception, and perform any client side local
- rollback code as necessary. The user can then just retry the transactional
- operations again on the same session.</para>
- <para>HornetQ ships with a fully functioning example demonstrating how to do this,
- please see <xref linkend="examples.transaction-failover"/></para>
- <para>If failover occurs when a commit call is being executed, the server, as
- previously described, will unblock the call to prevent a hang, since no response
- will come back. In this case it is not easy for the client to determine whether
- the transaction commit was actually processed on the live server before failure
- occurred.</para>
- <para>To remedy this, the client can simply enable duplicate detection (<xref
- linkend="duplicate-detection"/>) in the transaction, and retry the
- transaction operations again after the call is unblocked. If the transaction had
- indeed been committed on the live server successfully before failover, then when
- the transaction is retried, duplicate detection will ensure that any durable
- messages resent in the transaction will be ignored on the server to prevent them
- getting sent more than once.</para>
+ <title>事务的失效备援处理</title>
+ <para>如果在一个事务性会话中,在当前事务中消息已经发出或通知,则服务器在这时如果发生失效备援,它不
+ 能保证发出的消息或通知没有丢失。</para>
+ <para>因此这个事务就会被标记为只回滚,任何尝试提交的操作都会抛出一个<literal
+ >javax.jms.TransactionRolledBackException</literal>异常(如果是JMS),或者是一
+ 个<literal>HornetQException</literal>的异常,错误代码为<literal
+ >HornetQException.TRANSACTION_ROLLED_BACK</literal>(如果是核心接口)。</para>
+ <para>客户端需要自行处理这些异常,进行必要的回滚处理。用户可以通过同一个会话重试该事务操作。</para>
+ <para>HornetQ发布包中包括了一个完整的例子来展示如何处理这种情况。参见
+ <xref linkend="examples.transaction-failover"/></para>
+ <para>如果是在提交过程中发生了失效备援,服务器将这个阻塞调用解除。这种情况下客户端很难确定在事故发生
+ 之前事务是否在主服务器中得到了处理。</para>
+ <para>为了解决这个问题,客户端可以在事务中使用重复检测(<xref linkend="duplicate-detection"/>)
+ ,并且在提交的调用被解除后重新尝试事务操作。如果在失效备援前事务确实在主服务器上已经完成提交,那么
+ 当事务进行重试时,重复检测功能可以保证重复发送的消息被丢弃,这样避免了消息的重复。</para>
<note>
- <para>By catching the rollback exceptions and retrying, catching unblocked calls
- and enabling duplicate detection, once and only once delivery guarantees for
- messages can be provided in the case of failure, guaranteeing 100% no loss
- or duplication of messages.</para>
+ <para>通过处理异常和重试,适当处理被解除的阻塞调用并配合重复检测功能,HornetQ可以在故障条件下保证
+ 一次并且只有一次的消息传递,没有消息丢失和消息重复。</para>
</note>
</section>
<section id="ha.automatic.failover.nontransactional">
- <title>Handling Failover With Non Transactional Sessions</title>
- <para>If the session is non transactional, messages or acknowledgements can be lost
- in the event of failover.</para>
- <para>If you wish to provide <emphasis role="italic">once and only once</emphasis>
- delivery guarantees for non transacted sessions too, enabled duplicate
- detection, and catch unblock exceptions as described in <xref
- linkend="ha.automatic.failover.blockingcalls"/></para>
+ <title>非事务会话的失效备援处理</title>
+ <para>如果会话是非事务性的,那么通过它的消息或通知在故障时可能会丢失。</para>
+ <para>如果你在非事务会话中要保证<emphasis role="italic">一次并且只有一次</emphasis>
+ 的消息传递,你需要使用重复检测功能,并适当处理被解除的阻塞调用。参见 <xref
+ linkend="ha.automatic.failover.blockingcalls"/>。</para>
</section>
</section>
<section>
- <title>Getting Notified of Connection Failure</title>
- <para>JMS provides a standard mechanism for getting notified asynchronously of
- connection failure: <literal>java.jms.ExceptionListener</literal>. Please consult
- the JMS javadoc or any good JMS tutorial for more information on how to use
- this.</para>
- <para>The HornetQ core API also provides a similar feature in the form of the class
- <literal>org.hornet.core.client.SessionFailureListener</literal></para>
- <para>Any ExceptionListener or SessionFailureListener instance will always be called by
- HornetQ on event of connection failure, <emphasis role="bold"
- >irrespective</emphasis> of whether the connection was successfully failed over,
- reconnected or reattached.</para>
+ <title>连接故障的通知</title>
+ <para>JMS提供了标准的异步接收连接故障通知的机制:<literal>java.jms.ExceptionListener</literal>。
+ 请参考JMS的javadoc或者其它JMS教程来进一步了解怎样使用这个接口。</para>
+ <para>HornetQ的核心接口也提供了一个相似的接口
+ <literal>org.hornet.core.client.SessionFailureListener</literal>。</para>
+ <para>任何ExceptionListener或SessionFailureListener的实例,在发生连接故障时,都会被HornetQ
+ 调用,<emphasis role="bold">不管</emphasis>该连接是否得到了失效备援、重新连接还是得到了恢复。</para>
</section>
<section>
- <title>Application-Level Failover</title>
- <para>In some cases you may not want automatic client failover, and prefer to handle any
- connection failure yourself, and code your own manually reconnection logic in your
- own failure handler. We define this as <emphasis>application-level</emphasis>
- failover, since the failover is handled at the user application level.</para>
- <para>To implement application-level failover, if you're using JMS then you need to set
- an <literal>ExceptionListener</literal> class on the JMS connection. The <literal
- >ExceptionListener</literal> will be called by HornetQ in the event that
- connection failure is detected. In your <literal>ExceptionListener</literal>, you
- would close your old JMS connections, potentially look up new connection factory
- instances from JNDI and creating new connections. In this case you may well be using
- <ulink url="http://www.jboss.org/community/wiki/JBossHAJNDIImpl">HA-JNDI</ulink>
- to ensure that the new connection factory is looked up from a different
- server.</para>
- <para>For a working example of application-level failover, please see <xref
- linkend="application-level-failover"/>.</para>
- <para>If you are using the core API, then the procedure is very similar: you would set a
- <literal>FailureListener</literal> on the core <literal>ClientSession</literal>
- instances.</para>
+ <title>应用层的失效备援</title>
+ <para>在某些情况下你可能不需要自动的客户端失效备援,希望自己来处理连接故障,使用自己的重新连接方案等。
+ 我们把它称之为<emphasis>应用层</emphasis>失效备援,因为它是发生在应用层的程序中。</para>
+ <para>为了实现应用层的失效备援,你可以使用监听器(listener)的方式。如果使用的是JMS,你需要在JMS连接上
+ 设置一个<literal>ExceptionListener</literal>类。这个类在连接发生故障时由HornetQ调用。在这个类
+ 中你可以将旧的连接关闭,使用JNDI查找新的连接工厂并创建新的连接。这里你可以使用
+ <ulink url="http://www.jboss.org/community/wiki/JBossHAJNDIImpl">HA-JNDI</ulink>
+ 来保证新的连接工厂来自于另一个服务器。</para>
+ <para>请参见<xref
+ linkend="application-level-failover"/>。这是一个完整的应用层失效备援的例子。</para>
+ <para>如果你使用核心接口,则过程也是很相似的:你在核心的<literal>ClientSession</literal>实例上设置一个
+ <literal>FailureListener</literal>,然后在这个类中进行相应的处理即可。</para>
</section>
</section>
</chapter>
14 years, 10 months
JBoss hornetq SVN: r9196 - trunk/src/main/org/hornetq/api/jms.
by do-not-reply@jboss.org
Author: timfox
Date: 2010-05-04 07:27:41 -0400 (Tue, 04 May 2010)
New Revision: 9196
Modified:
trunk/src/main/org/hornetq/api/jms/HornetQJMSClient.java
Log:
return type should be HornetQConnectionFactory
Modified: trunk/src/main/org/hornetq/api/jms/HornetQJMSClient.java
===================================================================
--- trunk/src/main/org/hornetq/api/jms/HornetQJMSClient.java 2010-05-04 11:22:51 UTC (rev 9195)
+++ trunk/src/main/org/hornetq/api/jms/HornetQJMSClient.java 2010-05-04 11:27:41 UTC (rev 9196)
@@ -14,7 +14,6 @@
import java.util.List;
-import javax.jms.ConnectionFactory;
import javax.jms.Queue;
import javax.jms.Topic;
@@ -35,69 +34,69 @@
private static final Logger log = Logger.getLogger(HornetQJMSClient.class);
/**
- * Creates a ConnectionFactory using all the defaults.
+ * Creates a HornetQConnectionFactory using all the defaults.
*
- * @return The ConnectionFactory.
+ * @return The HornetQConnectionFactory.
*/
- public static ConnectionFactory createConnectionFactory()
+ public static HornetQConnectionFactory createConnectionFactory()
{
return new HornetQConnectionFactory();
}
/**
- * Creates a ConnectionFactory using the ClientSessionFactory for its underlying connection.
+ * Creates a HornetQConnectionFactory using the ClientSessionFactory for its underlying connection.
*
* @param sessionFactory The underlying ClientSessionFactory to use.
- * @return The ConnectionFactory.
+ * @return The HornetQConnectionFactory.
*/
- public static ConnectionFactory createConnectionFactory(final ClientSessionFactory sessionFactory)
+ public static HornetQConnectionFactory createConnectionFactory(final ClientSessionFactory sessionFactory)
{
return new HornetQConnectionFactory(sessionFactory);
}
/**
- * Creates a ConnectionFactory that will use discovery to connect to the server.
+ * Creates a HornetQConnectionFactory that will use discovery to connect to the server.
*
* @param discoveryAddress The address to use for discovery.
* @param discoveryPort The port to use for discovery.
- * @return The ConnectionFactory.
+ * @return The HornetQConnectionFactory.
*/
- public static ConnectionFactory createConnectionFactory(final String discoveryAddress, final int discoveryPort)
+ public static HornetQConnectionFactory createConnectionFactory(final String discoveryAddress, final int discoveryPort)
{
return new HornetQConnectionFactory(discoveryAddress, discoveryPort);
}
/**
- * Creates a ClientSessionFactory using a List of TransportConfigurations and backups.
+ * Creates a HornetQConnectionFactory using a List of TransportConfigurations and backups.
*
* @param staticConnectors The list of TransportConfiguration to use.
- * @return The ConnectionFactory.
+ * @return The HornetQConnectionFactory.
*/
- public static ConnectionFactory createConnectionFactory(final List<Pair<TransportConfiguration, TransportConfiguration>> staticConnectors)
+ public static HornetQConnectionFactory createConnectionFactory(final List<Pair<TransportConfiguration, TransportConfiguration>> staticConnectors)
{
return new HornetQConnectionFactory(staticConnectors);
}
/**
- * Creates a ConnectionFactory using a single pair of live-backup TransportConfiguration.
+ * Creates a HornetQConnectionFactory using a single pair of live-backup TransportConfiguration.
*
* @param connectorConfig The TransportConfiguration of the server to connect to.
* @param backupConnectorConfig The TransportConfiguration of the backup server to connect to. can be null.
- * @return The ConnectionFactory.
+ * @return The HornetQConnectionFactory.
*/
- public static ConnectionFactory createConnectionFactory(final TransportConfiguration connectorConfig,
+ public static HornetQConnectionFactory createConnectionFactory(final TransportConfiguration connectorConfig,
final TransportConfiguration backupConnectorConfig)
{
return new HornetQConnectionFactory(connectorConfig, backupConnectorConfig);
}
/**
- * Creates a ConnectionFactory to connect to a single live server.
+ * Creates a HornetQConnectionFactory to connect to a single live server.
*
* @param connectorConfig The TransportConfiguration of the server.
- * @return The ConnectionFactory.
+ * @return The HornetQConnectionFactory.
*/
- public static ConnectionFactory createConnectionFactory(final TransportConfiguration connectorConfig)
+ public static HornetQConnectionFactory createConnectionFactory(final TransportConfiguration connectorConfig)
{
return new HornetQConnectionFactory(connectorConfig);
}
14 years, 10 months
JBoss hornetq SVN: r9195 - in trunk: src/config/common/schema and 8 other directories.
by do-not-reply@jboss.org
Author: timfox
Date: 2010-05-04 07:22:51 -0400 (Tue, 04 May 2010)
New Revision: 9195
Modified:
trunk/docs/user-manual/en/clusters.xml
trunk/docs/user-manual/en/configuration-index.xml
trunk/src/config/common/schema/hornetq-jms.xsd
trunk/src/main/org/hornetq/api/core/client/HornetQClient.java
trunk/src/main/org/hornetq/core/config/impl/ConfigurationImpl.java
trunk/src/main/org/hornetq/jms/server/JMSServerManager.java
trunk/src/main/org/hornetq/jms/server/impl/JMSServerConfigParserImpl.java
trunk/src/main/org/hornetq/jms/server/impl/JMSServerDeployer.java
trunk/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java
trunk/tests/config/hornetq-jms-for-JMSServerDeployerTest2.xml
trunk/tests/src/org/hornetq/tests/integration/client/ProducerFlowControlTest.java
trunk/tests/src/org/hornetq/tests/integration/jms/server/JMSServerDeployerTest.java
trunk/tests/src/org/hornetq/tests/integration/jms/server/config/JMSServerConfigParserTest.java
Log:
changed defaults for discovery timeouts etc
Modified: trunk/docs/user-manual/en/clusters.xml
===================================================================
--- trunk/docs/user-manual/en/clusters.xml 2010-05-03 13:10:21 UTC (rev 9194)
+++ trunk/docs/user-manual/en/clusters.xml 2010-05-04 11:22:51 UTC (rev 9195)
@@ -87,7 +87,7 @@
<local-bind-port>5432</local-bind-port>
<group-address>231.7.7.7</group-address>
<group-port>9876</group-port>
- <broadcast-period>1000</broadcast-period>
+ <broadcast-period>2000</broadcast-period>
<connector-ref connector-name="netty-connector"
backup-connector-name="backup-connector"/>
</broadcast-group>
@@ -129,7 +129,7 @@
<listitem>
<para><literal>broadcast-period</literal>. This is the period in milliseconds
between consecutive broadcasts. This parameter is optional, the default
- value is <literal>1000</literal> milliseconds.</para>
+ value is <literal>2000</literal> milliseconds.</para>
</listitem>
<listitem>
<para><literal>connector-ref</literal>. This specifies the connector and
@@ -257,12 +257,12 @@
factory by using the setter method <literal>setDiscoveryRefreshTimeout() if you
want to change the default value.</literal></para>
<para>There is also a further parameter settable on the connection factory using the
- setter method <literal>setInitialWaitTimeout()</literal>. If the connection
+ setter method <literal>setDiscoveryInitialWaitTimeout()</literal>. If the connection
factory is used immediately after creation then it may not have had enough time
to received broadcasts from all the nodes in the cluster. On first usage, the
connection factory will make sure it waits this long since creation before
creating the first connection. The default value for this parameter is <literal
- >2000</literal> milliseconds.</para>
+ >10000</literal> milliseconds.</para>
</section>
<section>
<title>Configuring client discovery using Core</title>
@@ -282,12 +282,12 @@
factory by using the setter method <literal>setDiscoveryRefreshTimeout() if you
want to change the default value.</literal></para>
<para>There is also a further parameter settable on the session factory using the
- setter method <literal>setInitialWaitTimeout()</literal>. If the session factory
+ setter method <literal>setDiscoveryInitialWaitTimeout()</literal>. If the session factory
is used immediately after creation then it may not have had enough time to
received broadcasts from all the nodes in the cluster. On first usage, the
session factory will make sure it waits this long since creation before creating
the first session. The default value for this parameter is <literal
- >2000</literal> milliseconds.</para>
+ >10000</literal> milliseconds.</para>
</section>
</section>
</section>
Modified: trunk/docs/user-manual/en/configuration-index.xml
===================================================================
--- trunk/docs/user-manual/en/configuration-index.xml 2010-05-03 13:10:21 UTC (rev 9194)
+++ trunk/docs/user-manual/en/configuration-index.xml 2010-05-04 11:22:51 UTC (rev 9195)
@@ -527,7 +527,7 @@
</entry>
<entry>Long</entry>
<entry>period in milliseconds between consecutive broadcasts</entry>
- <entry>1000 (in milliseconds)</entry>
+ <entry>2000 (in milliseconds)</entry>
</row>
<row>
<entry>
@@ -600,7 +600,7 @@
<entry>Period the discovery group
waits after receiving the last broadcast from a particular server before
removing that servers connector pair entry from its list.</entry>
- <entry>10000 (in milliseconds)</entry>
+ <entry>5000 (in milliseconds)</entry>
</row>
<row>
<entry><link linkend="diverts">diverts</link></entry>
@@ -1038,8 +1038,8 @@
<entry>Long</entry>
<entry>the initial time to wait (in ms) for discovery groups to wait for
broadcasts</entry>
- <entry>2000</entry>
- </row>
+ <entry>10000</entry>
+ </row>
<row>
<entry id="configuration.connection-factory.block-on-acknowledge">
<link linkend="send-guarantees.nontrans.acks">connection-factory.block-on-acknowledge</link>
Modified: trunk/src/config/common/schema/hornetq-jms.xsd
===================================================================
--- trunk/src/config/common/schema/hornetq-jms.xsd 2010-05-03 13:10:21 UTC (rev 9194)
+++ trunk/src/config/common/schema/hornetq-jms.xsd 2010-05-04 11:22:51 UTC (rev 9195)
@@ -28,7 +28,7 @@
<xsd:all>
<xsd:element name="discovery-group-ref" type="discovery-group-refType" maxOccurs="1" minOccurs="0"></xsd:element>
<xsd:element name="discovery-initial-wait-timeout" type="xsd:long" maxOccurs="1" minOccurs="0"></xsd:element>
-
+
<xsd:element name="connectors" maxOccurs="1" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
Modified: trunk/src/main/org/hornetq/api/core/client/HornetQClient.java
===================================================================
--- trunk/src/main/org/hornetq/api/core/client/HornetQClient.java 2010-05-03 13:10:21 UTC (rev 9194)
+++ trunk/src/main/org/hornetq/api/core/client/HornetQClient.java 2010-05-04 11:22:51 UTC (rev 9195)
@@ -66,7 +66,7 @@
public static final boolean DEFAULT_PRE_ACKNOWLEDGE = false;
- public static final long DEFAULT_DISCOVERY_INITIAL_WAIT_TIMEOUT = 2000;
+ public static final long DEFAULT_DISCOVERY_INITIAL_WAIT_TIMEOUT = 10000;
public static final long DEFAULT_DISCOVERY_REFRESH_TIMEOUT = 10000;
Modified: trunk/src/main/org/hornetq/core/config/impl/ConfigurationImpl.java
===================================================================
--- trunk/src/main/org/hornetq/core/config/impl/ConfigurationImpl.java 2010-05-03 13:10:21 UTC (rev 9194)
+++ trunk/src/main/org/hornetq/core/config/impl/ConfigurationImpl.java 2010-05-04 11:22:51 UTC (rev 9195)
@@ -143,7 +143,7 @@
public static final String DEFAULT_CLUSTER_PASSWORD = "CHANGE ME!!";
- public static final long DEFAULT_BROADCAST_PERIOD = 1000;
+ public static final long DEFAULT_BROADCAST_PERIOD = 2000;
public static final long DEFAULT_BROADCAST_REFRESH_TIMEOUT = 10000;
Modified: trunk/src/main/org/hornetq/jms/server/JMSServerManager.java
===================================================================
--- trunk/src/main/org/hornetq/jms/server/JMSServerManager.java 2010-05-03 13:10:21 UTC (rev 9194)
+++ trunk/src/main/org/hornetq/jms/server/JMSServerManager.java 2010-05-04 11:22:51 UTC (rev 9195)
@@ -229,6 +229,7 @@
int discoveryPort,
String clientID,
long discoveryRefreshTimeout,
+ long discoveryInitialWaitTimeout,
long clientFailureCheckPeriod,
long connectionTTL,
long callTimeout,
@@ -246,8 +247,7 @@
boolean preAcknowledge,
String loadBalancingPolicyClassName,
int transactionBatchSize,
- int dupsOKBatchSize,
- long initialWaitTimeout,
+ int dupsOKBatchSize,
boolean useGlobalPools,
int scheduledThreadPoolMaxSize,
int threadPoolMaxSize,
Modified: trunk/src/main/org/hornetq/jms/server/impl/JMSServerConfigParserImpl.java
===================================================================
--- trunk/src/main/org/hornetq/jms/server/impl/JMSServerConfigParserImpl.java 2010-05-03 13:10:21 UTC (rev 9194)
+++ trunk/src/main/org/hornetq/jms/server/impl/JMSServerConfigParserImpl.java 2010-05-04 11:22:51 UTC (rev 9195)
@@ -284,9 +284,9 @@
HornetQClient.DEFAULT_RECONNECT_ATTEMPTS,
Validators.MINUS_ONE_OR_GE_ZERO);
boolean failoverOnInitialConnection = XMLConfigurationUtil.getBoolean(e,
- "failover-on-initial-connection",
- HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION);
-
+ "failover-on-initial-connection",
+ HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION);
+
boolean failoverOnServerShutdown = XMLConfigurationUtil.getBoolean(e,
"failover-on-server-shutdown",
HornetQClient.DEFAULT_FAILOVER_ON_SERVER_SHUTDOWN);
@@ -309,6 +309,7 @@
"discovery-initial-wait-timeout",
HornetQClient.DEFAULT_DISCOVERY_INITIAL_WAIT_TIMEOUT,
Validators.GT_ZERO);
+
String groupid = XMLConfigurationUtil.getString(e, "group-id", null, Validators.NO_CHECK);
List<String> jndiBindings = new ArrayList<String>();
List<Pair<String, String>> connectorNames = new ArrayList<Pair<String, String>>();
@@ -380,7 +381,6 @@
cfConfig.setConnectorNames(connectorNames);
}
- cfConfig.setInitialWaitTimeout(discoveryInitialWaitTimeout);
cfConfig.setClientID(clientID);
cfConfig.setClientFailureCheckPeriod(clientFailureCheckPeriod);
cfConfig.setConnectionTTL(connectionTTL);
Modified: trunk/src/main/org/hornetq/jms/server/impl/JMSServerDeployer.java
===================================================================
--- trunk/src/main/org/hornetq/jms/server/impl/JMSServerDeployer.java 2010-05-03 13:10:21 UTC (rev 9194)
+++ trunk/src/main/org/hornetq/jms/server/impl/JMSServerDeployer.java 2010-05-04 11:22:51 UTC (rev 9195)
@@ -13,7 +13,6 @@
package org.hornetq.jms.server.impl;
-import org.hornetq.core.config.Configuration;
import org.hornetq.core.deployers.DeploymentManager;
import org.hornetq.core.deployers.impl.XmlDeployer;
import org.hornetq.core.logging.Logger;
@@ -33,8 +32,6 @@
{
private static final Logger log = Logger.getLogger(JMSServerDeployer.class);
- private final Configuration configuration;
-
private final JMSServerConfigParser parser;
private final JMSServerManager jmsServerManager;
@@ -60,15 +57,12 @@
protected static final boolean DEFAULT_QUEUE_DURABILITY = true;
public JMSServerDeployer(final JMSServerManager jmsServerManager,
- final DeploymentManager deploymentManager,
- final Configuration config)
+ final DeploymentManager deploymentManager)
{
super(deploymentManager);
this.jmsServerManager = jmsServerManager;
- configuration = config;
-
parser = new JMSServerConfigParserImpl();
}
@@ -186,7 +180,7 @@
*/
private void deployConnectionFactory(final Node node) throws Exception
{
- ConnectionFactoryConfiguration cfConfig = parser.parseConnectionFactoryConfiguration(node);
+ ConnectionFactoryConfiguration cfConfig = parser.parseConnectionFactoryConfiguration(node);
jmsServerManager.createConnectionFactory(false, cfConfig, cfConfig.getBindings());
}
Modified: trunk/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java
===================================================================
--- trunk/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java 2010-05-03 13:10:21 UTC (rev 9194)
+++ trunk/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java 2010-05-04 11:22:51 UTC (rev 9195)
@@ -188,7 +188,7 @@
{
if (server.getConfiguration().isFileDeploymentEnabled())
{
- jmsDeployer = new JMSServerDeployer(this, deploymentManager, server.getConfiguration());
+ jmsDeployer = new JMSServerDeployer(this, deploymentManager);
if (configFileName != null)
{
@@ -778,6 +778,7 @@
final int discoveryPort,
final String clientID,
final long discoveryRefreshTimeout,
+ final long discoveryInitialWaitTimeout,
final long clientFailureCheckPeriod,
final long connectionTTL,
final long callTimeout,
@@ -795,8 +796,7 @@
final boolean preAcknowledge,
final String loadBalancingPolicyClassName,
final int transactionBatchSize,
- final int dupsOKBatchSize,
- final long initialWaitTimeout,
+ final int dupsOKBatchSize,
final boolean useGlobalPools,
final int scheduledThreadPoolMaxSize,
final int threadPoolMaxSize,
@@ -808,7 +808,7 @@
final boolean failoverOnServerShutdown,
final String groupId,
final String... jndiBindings) throws Exception
- {
+ {
checkInitialised();
HornetQConnectionFactory cf = connectionFactories.get(name);
if (cf == null)
@@ -819,6 +819,7 @@
discoveryPort);
configuration.setClientID(clientID);
configuration.setDiscoveryRefreshTimeout(discoveryRefreshTimeout);
+ configuration.setInitialWaitTimeout(discoveryInitialWaitTimeout);
configuration.setClientFailureCheckPeriod(clientFailureCheckPeriod);
configuration.setConnectionTTL(connectionTTL);
configuration.setCallTimeout(callTimeout);
@@ -837,7 +838,6 @@
configuration.setLoadBalancingPolicyClassName(loadBalancingPolicyClassName);
configuration.setTransactionBatchSize(transactionBatchSize);
configuration.setDupsOKBatchSize(dupsOKBatchSize);
- configuration.setDiscoveryRefreshTimeout(initialWaitTimeout);
configuration.setUseGlobalPools(useGlobalPools);
configuration.setScheduledThreadPoolMaxSize(scheduledThreadPoolMaxSize);
configuration.setThreadPoolMaxSize(threadPoolMaxSize);
@@ -918,6 +918,7 @@
final int discoveryPort,
final String clientID,
final long discoveryRefreshTimeout,
+ final long discoveryInitialWaitTimeout,
final long clientFailureCheckPeriod,
final long connectionTTL,
final long callTimeout,
@@ -935,8 +936,7 @@
final boolean preAcknowledge,
final String loadBalancingPolicyClassName,
final int transactionBatchSize,
- final int dupsOKBatchSize,
- final long initialWaitTimeout,
+ final int dupsOKBatchSize,
final boolean useGlobalPools,
final int scheduledThreadPoolMaxSize,
final int threadPoolMaxSize,
@@ -956,6 +956,7 @@
cf.setClientID(clientID);
cf.setLocalBindAddress(localBindAddress);
cf.setDiscoveryRefreshTimeout(discoveryRefreshTimeout);
+ cf.setDiscoveryInitialWaitTimeout(discoveryInitialWaitTimeout);
cf.setClientFailureCheckPeriod(clientFailureCheckPeriod);
cf.setConnectionTTL(connectionTTL);
cf.setCallTimeout(callTimeout);
@@ -974,7 +975,6 @@
cf.setConnectionLoadBalancingPolicyClassName(loadBalancingPolicyClassName);
cf.setTransactionBatchSize(transactionBatchSize);
cf.setDupsOKBatchSize(dupsOKBatchSize);
- cf.setDiscoveryInitialWaitTimeout(initialWaitTimeout);
cf.setUseGlobalPools(useGlobalPools);
cf.setScheduledThreadPoolMaxSize(scheduledThreadPoolMaxSize);
cf.setThreadPoolMaxSize(threadPoolMaxSize);
@@ -1149,19 +1149,19 @@
private HornetQConnectionFactory internalCreateCF(final ConnectionFactoryConfiguration cfConfig) throws HornetQException,
Exception
{
-
List<Pair<TransportConfiguration, TransportConfiguration>> connectorConfigs = lookupConnectors(cfConfig);
lookupDiscovery(cfConfig);
HornetQConnectionFactory cf;
if (cfConfig.getDiscoveryAddress() != null)
- {
+ {
cf = internalCreateConnectionFactory(cfConfig.getName(),
cfConfig.getLocalBindAddress(),
cfConfig.getDiscoveryAddress(),
cfConfig.getDiscoveryPort(),
cfConfig.getClientID(),
cfConfig.getDiscoveryRefreshTimeout(),
+ cfConfig.getInitialWaitTimeout(),
cfConfig.getClientFailureCheckPeriod(),
cfConfig.getConnectionTTL(),
cfConfig.getCallTimeout(),
@@ -1179,8 +1179,7 @@
cfConfig.isPreAcknowledge(),
cfConfig.getLoadBalancingPolicyClassName(),
cfConfig.getTransactionBatchSize(),
- cfConfig.getDupsOKBatchSize(),
- cfConfig.getInitialWaitTimeout(),
+ cfConfig.getDupsOKBatchSize(),
cfConfig.isUseGlobalPools(),
cfConfig.getScheduledThreadPoolMaxSize(),
cfConfig.getThreadPoolMaxSize(),
@@ -1439,7 +1438,7 @@
cfConfig.setDiscoveryAddress(discoveryGroupConfiguration.getGroupAddress());
cfConfig.setDiscoveryPort(discoveryGroupConfiguration.getGroupPort());
cfConfig.setDiscoveryRefreshTimeout(discoveryGroupConfiguration.getRefreshTimeout());
-
+
}
}
Modified: trunk/tests/config/hornetq-jms-for-JMSServerDeployerTest2.xml
===================================================================
--- trunk/tests/config/hornetq-jms-for-JMSServerDeployerTest2.xml 2010-05-03 13:10:21 UTC (rev 9194)
+++ trunk/tests/config/hornetq-jms-for-JMSServerDeployerTest2.xml 2010-05-04 11:22:51 UTC (rev 9195)
@@ -30,7 +30,7 @@
<auto-group-id>false</auto-group-id>
<pre-acknowledge>true</pre-acknowledge>
<connection-ttl>2345</connection-ttl>
- <discovery-initial-wait-timeout>678</discovery-initial-wait-timeout>
+ <discovery-initial-wait-timeout>5464</discovery-initial-wait-timeout>
<failover-on-initial-connection>true</failover-on-initial-connection>
<failover-on-server-shutdown>false</failover-on-server-shutdown>
<connection-load-balancing-policy-class-name>FooClass</connection-load-balancing-policy-class-name>
Modified: trunk/tests/src/org/hornetq/tests/integration/client/ProducerFlowControlTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/client/ProducerFlowControlTest.java 2010-05-03 13:10:21 UTC (rev 9194)
+++ trunk/tests/src/org/hornetq/tests/integration/client/ProducerFlowControlTest.java 2010-05-04 11:22:51 UTC (rev 9195)
@@ -21,20 +21,17 @@
import junit.framework.Assert;
import org.hornetq.api.core.SimpleString;
-import org.hornetq.api.core.TransportConfiguration;
import org.hornetq.api.core.client.ClientConsumer;
import org.hornetq.api.core.client.ClientMessage;
import org.hornetq.api.core.client.ClientProducer;
import org.hornetq.api.core.client.ClientSession;
import org.hornetq.api.core.client.ClientSessionFactory;
-import org.hornetq.api.core.client.HornetQClient;
import org.hornetq.api.core.client.MessageHandler;
import org.hornetq.core.client.impl.ClientProducerCreditManagerImpl;
import org.hornetq.core.client.impl.ClientProducerCredits;
import org.hornetq.core.client.impl.ClientProducerInternal;
import org.hornetq.core.client.impl.ClientSessionInternal;
import org.hornetq.core.logging.Logger;
-import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
import org.hornetq.core.server.HornetQServer;
import org.hornetq.core.settings.HierarchicalRepository;
import org.hornetq.core.settings.impl.AddressFullMessagePolicy;
@@ -176,8 +173,6 @@
false);
}
- // (1000, 10 * 1024, 10 * 1024, 1024, 1024, 1024, 1, 1, 0, false);
-
private void testFlowControl(final int numMessages,
final int messageSize,
final int maxSize,
Modified: trunk/tests/src/org/hornetq/tests/integration/jms/server/JMSServerDeployerTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/jms/server/JMSServerDeployerTest.java 2010-05-03 13:10:21 UTC (rev 9194)
+++ trunk/tests/src/org/hornetq/tests/integration/jms/server/JMSServerDeployerTest.java 2010-05-04 11:22:51 UTC (rev 9195)
@@ -70,7 +70,7 @@
public void testValidateEmptyConfiguration() throws Exception
{
- JMSServerDeployer deployer = new JMSServerDeployer(jmsServer, deploymentManager, config);
+ JMSServerDeployer deployer = new JMSServerDeployer(jmsServer, deploymentManager);
String xml = "<configuration xmlns='urn:hornetq'> " + "</configuration>";
@@ -112,7 +112,7 @@
final String htmlEncodedName,
final String jndiName) throws Exception
{
- JMSServerDeployer deployer = new JMSServerDeployer(jmsServer, deploymentManager, config);
+ JMSServerDeployer deployer = new JMSServerDeployer(jmsServer, deploymentManager);
String xml =
@@ -131,7 +131,7 @@
final String htmlEncodedName,
final String jndiName) throws Exception
{
- JMSServerDeployer deployer = new JMSServerDeployer(jmsServer, deploymentManager, config);
+ JMSServerDeployer deployer = new JMSServerDeployer(jmsServer, deploymentManager);
String xml =
@@ -158,7 +158,7 @@
public void testDeployFullConfiguration() throws Exception
{
- JMSServerDeployer deployer = new JMSServerDeployer(jmsServer, deploymentManager, config);
+ JMSServerDeployer deployer = new JMSServerDeployer(jmsServer, deploymentManager);
String conf = "hornetq-jms-for-JMSServerDeployerTest.xml";
URL confURL = Thread.currentThread().getContextClassLoader().getResource(conf);
@@ -244,7 +244,7 @@
public void testDeployFullConfiguration2() throws Exception
{
- JMSServerDeployer deployer = new JMSServerDeployer(jmsServer, deploymentManager, config);
+ JMSServerDeployer deployer = new JMSServerDeployer(jmsServer, deploymentManager);
String conf = "hornetq-jms-for-JMSServerDeployerTest2.xml";
URL confURL = Thread.currentThread().getContextClassLoader().getResource(conf);
@@ -315,7 +315,8 @@
assertEquals("243.7.7.7", cf.getDiscoveryAddress());
assertEquals("172.16.8.10", cf.getLocalBindAddress());
assertEquals(12345, cf.getDiscoveryPort());
- assertEquals(5000, cf.getDiscoveryRefreshTimeout());
+ assertEquals(5432, cf.getDiscoveryRefreshTimeout());
+ assertEquals(5464, cf.getDiscoveryInitialWaitTimeout());
}
for (String binding : queueBindings)
@@ -348,7 +349,7 @@
DiscoveryGroupConfiguration dcg = new DiscoveryGroupConfiguration("mygroup", "172.16.8.10",
"243.7.7.7", 12345,
- 5000);
+ 5432);
config.getDiscoveryGroupConfigurations().put("mygroup", dcg);
HornetQServer server = createServer(false, config);
Modified: trunk/tests/src/org/hornetq/tests/integration/jms/server/config/JMSServerConfigParserTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/jms/server/config/JMSServerConfigParserTest.java 2010-05-03 13:10:21 UTC (rev 9194)
+++ trunk/tests/src/org/hornetq/tests/integration/jms/server/config/JMSServerConfigParserTest.java 2010-05-04 11:22:51 UTC (rev 9195)
@@ -83,7 +83,6 @@
assertEquals(false, cfConfig.isAutoGroup());
assertEquals(true, cfConfig.isPreAcknowledge());
assertEquals(2345, cfConfig.getConnectionTTL());
- assertEquals(678, cfConfig.getInitialWaitTimeout());
assertEquals(false, cfConfig.isFailoverOnServerShutdown());
assertEquals("FooClass", cfConfig.getLoadBalancingPolicyClassName());
assertEquals(34, cfConfig.getReconnectAttempts());
14 years, 10 months