30.8. 检测拒绝连接
本节讨论到实时连接时间(TTL),并解释 JBoss EAP 消息传递如何处理已退出但未完全关闭资源的崩溃客户端和客户端。
清理服务器上的拒绝连接资源
在 JBoss EAP 客户端应用退出之前,它应当使用 最终 块以受控的方式关闭其资源。
以下是在最终 块中正确关闭其会话和会话工厂的核心客户端的示例 :
ServerLocator locator = null;
ClientSessionFactory sf = null;
ClientSession session = null;
try {
locator = ActiveMQClient.createServerLocatorWithoutHA(..);
sf = locator.createClientSessionFactory();;
session = sf.createSession(...);
... do some stuff with the session...
}
finally {
if (session != null) {
session.close();
}
if (sf != null) {
sf.close();
}
if(locator != null) {
locator.close();
}
}
以下是行为良好的 JMS 客户端应用程序的示例:
Connection jmsConnection = null;
try {
ConnectionFactory jmsConnectionFactory = ActiveMQJMSClient.createConnectionFactoryWithoutHA(...);
jmsConnection = jmsConnectionFactory.createConnection();
... do some stuff with the connection...
}
finally {
if (connection != null) {
connection.close();
}
}
不幸的是,客户端有时崩溃,无法清理其资源。如果出现这种情况,它可以使服务器端资源挂起在服务器上。如果未移除这些资源,则会导致服务器上的资源泄漏,而且随着时间推移,可能会导致服务器内存或其他资源不足。
在查看清除死的客户端资源时,务必要清楚有时客户端和服务器之间的网络可能会出现故障,然后返回,允许客户端重新连接。由于 JBoss EAP 支持客户端重新连接,因此务必不要太快清理"dead"服务器端资源,否则将阻止任何客户端重新连接并恢复服务器上的旧会话。
JBoss EAP 使所有这些可配置。对于配置的每个 ClientSessionFactory ( Time-To-Live 或 TTL),可以使用 属性来设置服务器在没有客户端的任何数据时保持连接的时长(以毫秒为单位)。客户端将定期自动发送"ping"数据包,以防止服务器关闭其连接。如果服务器在 TTL 时间内没有接收任何数据包,它将自动关闭与该连接相关的服务器中的所有会话。
如果您使用 JMS,连接 TTL 由 ActiveMQConnectionFactory 实例上的 ConnectionTTL 属性定义,或者,如果您部署 JMS 连接工厂实例直接在服务器端的 JNDI 中,您可以使用 connectionTtl 参数在 xml 配置中指定它。
基于网络的连接(如 http-connector) 上的 ConnectionTTL 的默认值为 60000,即 1 分钟。内部连接上的连接 TTL 的默认值(如 in-vm 连接)为 -1。ConnectionTTL 的值为 -1 表示服务器端的连接永远不会超时。
如果您不希望客户端指定自己的连接 TTL,您可以在服务器端设置全局值。这可以通过在服务器配置中指定 connection-ttl-override 属性来完成。connection-ttl-override 的默认值为 -1,表示"不覆盖",即允许客户端使用自己的值。
关闭核心会话或 JMS 连接
使用完所有核心客户端会话和 JMS 连接时,务必始终在 最后一个块 中明确关闭它们。
如果您未能这样做,JBoss EAP 将在垃圾收集时检测到这一点。然后,它将关闭连接并记录类似如下的警告:
[Finalizer] 20:14:43,244 WARNING [org.apache.activemq.artemis.core.client.impl.DelegatingSession] I'm closing 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.apache.activemq.artemis.core.client.impl.DelegatingSession] The session you didn't close was created here:
java.lang.Exception
at org.apache.activemq.artemis.core.client.impl.DelegatingSession.<init>(DelegatingSession.java:83)
at org.acme.yourproject.YourClass (YourClass.java:666)
请注意,如果您使用 JMS,则警告将涉及 JMS 连接,而不是客户端会话。此外,日志将告知您实例化未关闭的 JMS 连接或核心客户端会话的确切代码行。这样,您可以找出代码中的错误并相应地进行更正。
从客户端幻灯片检测故障
只要客户端从服务器接收数据,它将认为连接处于活动状态。如果客户端没有接收任何 客户端-failure-period 毫秒的任何数据包,它将考虑连接失败,并将启动故障转移,或调用任何 FailureListener 实例,如果您使用 JMS,则发出 ExceptionListener 实例,具体取决于客户端的配置方式。
如果您使用 JMS,则行为由 ActiveMQConnectionFactory 实例上的 ClientFailureCheckPeriod 属性定义。
网络连接中的客户端失败检查周期(如 HTTP 连接)的默认值为 30000 或 30 秒。in-vm 连接中的客户端失败检查期间的默认值为 -1。值 -1 表示客户端端的连接永远不会失败(如果没有从服务器收到任何数据)。无论连接类型如何,检查周期通常都比服务器上连接 TTL 的值小得多,以便客户端能够在发生暂时故障时重新连接。
配置异步连接执行
服务器端收到的大多数数据包都在 远程线程 中执行。这些数据包代表短期运行的操作,出于性能的原因,始终在远程 线程 中执行。
但是,默认情况下,某些类型的数据包是使用来自线程池中的线程来执行的,以便远程 线程 不会太长时间关联。请注意,在另一个线程上异步处理操作会增加延迟。这些数据包是:
org.apache.activemq.artemis.core.protocol.core.impl.wireformat.RollbackMessage
org.apache.activemq.artemis.core.protocol.core.impl.wireformat.SessionCloseMessage
org.apache.activemq.artemis.core.protocol.core.impl.wireformat.SessionCommitMessage
org.apache.activemq.artemis.core.protocol.core.impl.wireformat.SessionXACommitMessage
org.apache.activemq.artemis.core.protocol.core.impl.wireformat.SessionXAPrepareMessage
org.apache.activemq.artemis.core.protocol.core.impl.wireformat.SessionXARollbackMessage
要禁用异步连接执行,请将 async-connection-execution-enabled 参数设置为 false。默认值为 true。