activemq-artemis/docs/user-manual/zh/connection-ttl.xml

140 lines
9.2 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

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

<?xml version="1.0" encoding="UTF-8"?>
<!-- ============================================================================= -->
<!-- Copyright © 2009 Red Hat, Inc. and others. -->
<!-- -->
<!-- The text of and illustrations in this document are licensed by Red Hat under -->
<!-- a Creative Commons AttributionShare Alike 3.0 Unported license ("CC-BY-SA"). -->
<!-- -->
<!-- An explanation of CC-BY-SA is available at -->
<!-- -->
<!-- http://creativecommons.org/licenses/by-sa/3.0/. -->
<!-- -->
<!-- In accordance with CC-BY-SA, if you distribute this document or an adaptation -->
<!-- of it, you must provide the URL for the original version. -->
<!-- -->
<!-- Red Hat, as the licensor of this document, waives the right to enforce, -->
<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent -->
<!-- permitted by applicable law. -->
<!-- ============================================================================= -->
<chapter id="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.&lt;init&gt;(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>