【问题标题】:Ideal way to set up a JMS connection so it auto reconnects设置 JMS 连接以使其自动重新连接的理想方式
【发布时间】:2012-07-20 16:53:41
【问题描述】:

我目前正在为持久订阅编写一个信使服务(它可能最终变得不持久,我们仍在讨论这个问题),我正在寻找一些关于如何处理我们的服务器因任何原因暂时停机的情况的建议我们需要自动重新订阅主题。以下是它如何连接的示例代码:

public void DurableChatter(String broker, String username, String password)
{
    javax.jms.MessageProducer publisher = null;
    javax.jms.MessageConsumer subscriber = null;
    javax.jms.Topic topic = null;

    //Create a connection:
    try{
        javax.jms.ConnectionFactory factory;
        factory = (new progress.message.jclient.ConnectionFactory (broker));
        connection = factory.createConnection (username, password);

        //Durable Subscriptions are indexed by username, clientID and subscription name
        //It is a good proactice to set the clientID:
        connection.setClientID(CLIENT_ID);
        pubSession = connection.createSession(false,javax.jms.Session.AUTO_ACKNOWLEDGE);
        subSession = connection.createSession(false,javax.jms.Session.AUTO_ACKNOWLEDGE);
    }
    catch (javax.jms.JMSException jmse){
        System.err.println ("Error: Cannot connect to Broker - " + broker);
        jmse.printStackTrace();
        System.exit(1);
    }

    //Create Publisher and Durable Subscriber:
    try{

        topic = pubSession.createTopic(APP_TOPIC);
        subscriber = subSession.createDurableSubscriber(topic, "SampleSubscription");
        subscriber.setMessageListener(this);
        publisher = pubSession.createProducer(topic);
        connection.start();
    }
    catch (javax.jms.JMSException jmse){
        System.out.println("Error: connection not started.");
        jmse.printStackTrace();
        System.exit(1);
    }

    //Wait for user input

    try
    {
        System.out.println("Enter text to send as message and press enter.");
        java.io.BufferedReader stdin =
            new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
        while (true)
        {
            String s = stdin.readLine();

            if(s == null){
                exit();
            }
            else if (s.length()>0)
            {
                try
                {
                    javax.jms.TextMessage msg = pubSession.createTextMessage();
                    msg.setText(username + ": " + s);
                    //Publish the message persistantly:
                    publisher.send(
                        msg,                               //message
                        javax.jms.DeliveryMode.PERSISTENT, //publish persistantly
                        javax.jms.Message.DEFAULT_PRIORITY,//priority
                        MESSAGE_LIFESPAN);                 //Time to Live
                }
                catch (javax.jms.JMSException jmse){
                    System.err.println("Error publishing message:" + jmse.getMessage());
                }
            }
        }
    }
    catch (java.io.IOException ioe)
    {
        ioe.printStackTrace();
    }
}

【问题讨论】:

    标签: java jms messenger


    【解决方案1】:

    你应该让你的客户implement javax.jmsExceptionListener

    这将允许您的客户端在连接丢失时立即接收来自 JMS API 的回调,即使您的应用程序目前没有发布任何内容。

    创建Connection,连接并启动它后,调用connection.setExceptionListener(myListener)。另请参阅Connection 的 Javadoc。

    【讨论】:

      【解决方案2】:

      您需要多快的故障检测速度? 设置您的协议,以确保每个客户端至少每分钟发送一次消息(您需要在通信协议中添加一些新的“绒毛”keepalive 消息) - 任何未收到 keepalive 消息的客户端都可以安全地假设服务器已关闭并开始重新连接。

      理想情况下,最好使用 UDP 广播而不是 JMS(用于开销)来完成这种事情,但我假设如果您有 UDP 广播作为选项,您将使用 jgroups 为您进行集群检测/故障转移/重新加入.

      【讨论】:

      • 如果这就是您所要求的,它不必是即时的。无论如何,这可以通过 try/catch 块来完成吗?
      • 仅当底层连接在断开时抛出某种异常。我不能不试就告诉你。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-30
      • 2010-12-06
      • 2015-11-24
      • 2014-12-03
      • 2011-02-02
      • 2015-03-12
      • 2017-02-15
      相关资源
      最近更新 更多