140 lines
9.2 KiB
XML
140 lines
9.2 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!-- ============================================================================= -->
|
||
<!-- Copyright © 2009 Red Hat, Inc. and others. -->
|
||
<!-- -->
|
||
<!-- The text of and illustrations in this document are licensed by Red Hat under -->
|
||
<!-- a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). -->
|
||
<!-- -->
|
||
<!-- An explanation of CC-BY-SA is available at -->
|
||
<!-- -->
|
||
<!-- http://creativecommons.org/licenses/by-sa/3.0/. -->
|
||
<!-- -->
|
||
<!-- In accordance with CC-BY-SA, if you distribute this document or an adaptation -->
|
||
<!-- of it, you must provide the URL for the original version. -->
|
||
<!-- -->
|
||
<!-- Red Hat, as the licensor of this document, waives the right to enforce, -->
|
||
<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent -->
|
||
<!-- permitted by applicable law. -->
|
||
<!-- ============================================================================= -->
|
||
<chapter id="connection-ttl">
|
||
<title>失效连接的检测</title>
|
||
<para>本章将讨论连接的生存时间(TTL)以及HornetQ如何处理出现故障的客户端或者异常退出的客户端(即客户端在
|
||
退出时没有合理的关闭相关资源)。</para>
|
||
<section id="dead.connections">
|
||
<title>服务器端对失效连接的清除</title>
|
||
<para>当客户端的应用程序退出时,应该关闭所使用的资源。在<literal>finally</literal>进行资源的关闭
|
||
是一个很好的方法。</para>
|
||
<para>下面的例子中,一个Hornet客户端在finally中关闭了它的会话(session)和会话工厂(session factory):</para>
|
||
<programlisting>
|
||
ClientSessionFactory sf = null;
|
||
ClientSession session = null;
|
||
|
||
try
|
||
{
|
||
sf = HornetQClient.createClientSessionFactory(...);
|
||
|
||
session = sf.createSession(...);
|
||
|
||
... do some stuff with the session...
|
||
}
|
||
finally
|
||
{
|
||
if (session != null)
|
||
{
|
||
session.close();
|
||
}
|
||
|
||
if (sf != null)
|
||
{
|
||
sf.close();
|
||
}
|
||
}
|
||
</programlisting>
|
||
<para>下面的例子给出了一个JMS客户端是如何适当关闭相关资源的:</para>
|
||
<programlisting>
|
||
Connection jmsConnection = null;
|
||
|
||
try
|
||
{
|
||
ConnectionFactory jmsConnectionFactory = HornetQJMSClient.createConnectionFactory(...);
|
||
|
||
jmsConnection = jmsConnectionFactory.createConnection();
|
||
|
||
... do some stuff with the connection...
|
||
}
|
||
finally
|
||
{
|
||
if (connection != null)
|
||
{
|
||
connection.close();
|
||
}
|
||
}
|
||
</programlisting>
|
||
<para>然而有时候资源在客户端得不到合理的关闭。有的客户端应用在结束时忘记了关闭资源,有的客户端有时发生故障导致
|
||
程序突然中断,相关资源也没有来得及关闭!</para>
|
||
<para>如果上述情况发生了,那么这些资源就会留在服务器端而不会被清理。这就会造成资源泄漏现象并最終导致服务器内存
|
||
溢出或其它资源的溢出错误。</para>
|
||
<para>因此在服务器端要有某种机制来避免资源的泄漏。也就是对无效资源进行回收。在判断什么是无效资源时,HornetQ
|
||
考虑到了客户端重新连接的情况。就是当一个连接由于网络临时中断后又恢复正常时,客户端有可能通过不断重试
|
||
成功地连接到服务器端。如果服务器端过早清除了相关的连接资源,则客户端就可能重试失败。</para>
|
||
<para>HornetQ的资源回收是完全可配置的。每个 <literal
|
||
>ClientSessionFactory</literal> 有一个<emphasis>连接 TTL</emphasis>的参数。
|
||
这个参数的意义是当客户端的一个连接没有任何数到达服务器时,服务器充许这个连接有效的最长时间。客户端通过定
|
||
时向服务器端发送“ping“数据包来维持连接的有效,以免被服务器关掉。如果服务器在TTL指定的时间内没有收到任何
|
||
数据包,则认为该连接无效,继而关闭与该连接相关的所有的会话(session)。</para>
|
||
<para>如果使用JMS,<literal>HornetQConnectionFactory</literal>的<literal>ConnectionTTL</literal>
|
||
属性是用来定义连接的存活时间的。如果你将JMS连接工厂部署到JNDI中,则应使用配置文件中的<literal
|
||
>connection-ttl</literal>参数来定义连接的TTL。</para>
|
||
<para>默认的连接TTL值是<literal>60000</literal>毫秒,即一分钟。 <literal>ConnectionTTL</literal>
|
||
设为<literal>-1</literal>表示服务器永远不检测超时的连接。</para>
|
||
<para>如果你不想让客户端来规定连接存活时间(TTL),你可以在服务器端的配置文件中定义
|
||
<literal>connection-ttl-override</literal>属性。它的默认值是<literal>-1</literal>,表示
|
||
服务器端该属性无效(即客户端可以定义自己的连接TTL)。</para>
|
||
<section>
|
||
<title>关闭没有被成功关闭的核心会话或JMS连接</title>
|
||
<para>如前所述,在使用完毕后在<literal>finally</literal>中将所有的核心会话或JMS连接关闭是十分重要的。</para>
|
||
<para>如果你没有这样做,HornetQ会在拉圾回收时进行检测并会在日志中打印类似以下的警告(如果是JMS则在警告中
|
||
是相应的JMS连接):</para>
|
||
<programlisting>
|
||
|
||
[Finalizer] 20:14:43,244 WARNING [org.hornetq.core.client.impl.DelegatingSession] I'm closin
|
||
g a ClientSession you left open. Please make sure you close all ClientSessions explicitly before let
|
||
ting them go out of scope!
|
||
[Finalizer] 20:14:43,244 WARNING [org.hornetq.core.client.impl.DelegatingSession] The sessi
|
||
on you didn't close was created here:
|
||
java.lang.Exception
|
||
at org.hornetq.core.client.impl.DelegatingSession.<init>(DelegatingSession.java:83)
|
||
at org.acme.yourproject.YourClass (YourClass.java:666)
|
||
|
||
</programlisting>
|
||
<para>HornetQ然后将未关闭的连接/会话关闭。</para>
|
||
<para>注意在日志的警告中还给出了创建JMS连接/客户端会话的具体行号,以便准确地确定出错的地方。</para>
|
||
</section>
|
||
</section>
|
||
<section>
|
||
<title>客户端的故障检测</title>
|
||
<para>前面讲述了客户端如何向服务器发送ping以及服务器端如何清理失效的连接。发送ping还有另外一个目的,就是能
|
||
让客户端检测网络或服务器是否出现故障。</para>
|
||
<para>从客户端的角度来看,只要客户端能从一个连接不断接收服务器的数据,那么这个连接就被认为是一个有效的连接。</para>
|
||
<para>如果在属性<literal>client-failure-check-period</literal>所定义的时间内(单位毫秒)客户端没有
|
||
收到任何数据,客户端就认为这们连接发生了故障。根据不同的配置,客户端在这种情况下要么进行failover,要么
|
||
调用<literal>FailureListener</literal>的接口(或者是JMS的<literal>ExceptionListener</literal>)。</para>
|
||
<para>如果使用JMS,这个参数是<literal>HornetQConnectionFactory</literal>的<literal>ClientFailureCheckPeriod</literal>。
|
||
如果你向JNDI部署JMS连接工厂,那么相应的参数在<literal>hornetq-jms.xml</literal>配置文件中,参数名
|
||
为<literal>client-failure-check-period</literal>。</para>
|
||
<para>这个参数的默认值是<literal>30000</literal>毫秒,即半分钟。<literal>-1</literal>表示客户端不检查
|
||
连接的有效性。即不论是否有数据来自服务器,连接都一直有效。这一参数通常要比服务器端的连接TTL小许多,以使
|
||
客户端在出现短暂连接故障的情况下可以与服务器成功地重新连接。</para>
|
||
</section>
|
||
<section id="connection-ttl.async-connection-execution">
|
||
<title>配置异步连接任务执行</title>
|
||
<para>默认情况下,服务器接收到的数据包被远程模块的线程处理。</para>
|
||
<para>为了避免远程模块的线程被长时间占用,数据包可以转给另外的一个线程池来处理。要注意这样做的增加了一些时间延迟。
|
||
因此如果数据包处理耗时很少,还是由远程模块线程来处理较好。
|
||
|
||
要配置这样的异步连接很行任务,将<literal>hornetq-configuration.xml</literal>文件中的
|
||
<literal>async-connection-execution-enabled</literal> 参数设为<literal>true</literal>
|
||
(默认值是 <literal>true</literal>)。</para>
|
||
</section>
|
||
</chapter>
|