Java 如何确定是否存在 JMS 连接?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3187943/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to find out if JMS Connection is there?
提问by Mauli
In JMS it is easy to find out if a connection is lost, a exception happens. But how do I find out if the connection is there again?
在 JMS 中,很容易发现连接是否丢失,是否发生异常。但是我如何确定连接是否再次存在?
Scenario: I use JMS to communicate with my server. Now my connection breaks (server is down), which results in a exception. So far so good. If the server is up again and the connection is reestablished, how do I know that?
场景:我使用 JMS 与我的服务器进行通信。现在我的连接中断(服务器关闭),导致异常。到现在为止还挺好。如果服务器再次启动并重新建立连接,我怎么知道?
I don't see any Listeners which would facilitate such information.
我没有看到任何可以提供此类信息的监听器。
采纳答案by T.Rob
Ahhh...the old exception handling/reconnection conundrum.
啊……旧的异常处理/重新连接难题。
There are some transport providers that will automatically reconnect your application for you and some who make the app drive reconnection. In general the reconnections hide the exception from the application. The down side is that you don't want the app to hang forever if allthe remote messaging nodes are down so ultimately, you mustinclude some reconnection logic.
有一些传输提供商会自动为您重新连接您的应用程序,还有一些使应用程序驱动器重新连接。通常,重新连接会隐藏应用程序中的异常。不利的一面是,如果所有远程消息传递节点都关闭,您不希望应用程序永远挂起,因此最终,您必须包含一些重新连接逻辑。
Now here's the interesting part - how do you handle the exceptions in a provider neutral way? The JMS exception is practically worthless. For example, a "security exception" can be that the Java security policies are too restrictive, that the file system permissions are too restrictive, that the LDAP credentials failed, that the connection to the transport failed, that the open of the queue or topic failed or any of dozens of other security-related problems. It's the linked exception that has the details from the transport provider that really help debug the problem. My clients have generally taken one of three different approaches here...
现在是有趣的部分 - 您如何以提供者中立的方式处理异常?JMS 异常实际上毫无价值。例如,“安全异常”可能是 Java 安全策略过于严格、文件系统权限过于严格、LDAP 凭据失败、与传输的连接失败、队列或主题的打开失败或许多其他与安全相关的问题中的任何一个。链接异常包含来自传输提供程序的详细信息,真正有助于调试问题。我的客户通常在这里采取三种不同方法中的一种......
- Treat all errors the same. Close all objects and reinitialize them. this is JMS portable.
- Allow the app to inspect the linked exceptions to distinguish between fatal and transient errors (i.e. auth error vs. queue full). Not provider portable.
- Provider-specific error-handling classes. A hybrid of the other two.
- 对所有错误一视同仁。关闭所有对象并重新初始化它们。这是 JMS 可移植的。
- 允许应用检查链接的异常以区分致命错误和暂时性错误(即身份验证错误与队列已满)。不是提供者可移植的。
- 特定于提供程序的错误处理类。其他两者的混合体。
In your case, the queue and topic objects are probably only valid in the context of the original connection. Assuming a provider who reconnects automatically the fact that you got an exception means reconnect failed and the context for queue and topic objects could not be restored. Close all objects and reconnect.
在您的情况下,队列和主题对象可能仅在原始连接的上下文中有效。假设自动重新连接的提供者您遇到异常的事实意味着重新连接失败并且队列和主题对象的上下文无法恢复。关闭所有对象并重新连接。
Whether you want to do something more provider-specific such as distinguish between transient and permanent errors is one of those "it depends" things and you'll have to figure that out on a case-by-case basis.
您是否想要做一些特定于提供者的事情,例如区分暂时性错误和永久性错误是那些“视情况而定”的事情之一,您必须逐案解决。
回答by Georgy Bolyuba
JMS spec does not describe any transport protocol, it does not say anything about connections (i.e. should broker keep them alive or establish a new connection for every session). So, I think what you mean by
JMS 规范没有描述任何传输协议,它没有说明任何关于连接的内容(即代理应该让它们保持活动状态还是为每个会话建立一个新连接)。所以,我想你的意思
Now my connection breaks (server is down), which results in a exception.
现在我的连接中断(服务器关闭),导致异常。
is that you are trying to send a message and you are getting a JmsException.
是您尝试发送消息并且收到 JmsException。
I think, the only way to see if broker is up is to try to send a message.
我认为,查看代理是否已启动的唯一方法是尝试发送消息。
回答by Chris K
Your only option in the case of a Connection based JMSException is to attempt to reestablish the connection in your exception handler, and retry the operation.
在基于连接的 JMSException 的情况下,您唯一的选择是尝试在您的异常处理程序中重新建立连接,然后重试该操作。
回答by shimatai
The best way to monitor for connection exception is setting an exception listener, for example:
监视连接异常的最佳方法是设置异常侦听器,例如:
ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup("jmsContextName");
connection = connectionFactory.createConnection();
connection.setExceptionListener(new ExceptionListener() {
@Override
public void onException(JMSException exception) {
logger.error("ExceptionListener triggered: " + exception.getMessage(), exception);
try {
Thread.sleep(5000); // Wait 5 seconds (JMS server restarted?)
restartJSMConnection();
} catch (InterruptedException e) {
logger.error("Error pausing thread" + e.getMessage());
}
}
});
connection.start();