2012-07-20 25 views
5

Actualmente estoy programando un servicio de mensajería para suscripciones duraderas (podría terminar siendo no duradero, todavía estamos discutiendo eso) y estaba buscando algunas sugerencias sobre cómo manejamos un escenario donde nuestro servidor baja temporalmente por cualquier razón y necesitamos volver a suscribir el tema automáticamente. Aquí hay un código de ejemplo de cómo se conecta:Forma ideal de configurar una conexión JMS para que se vuelva a conectar automáticamente

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(); 
    } 
} 

Respuesta

0

¿Cuán rápido necesita ser la detección de fallas? configure su protocolo para que garantice que a cada cliente se le envíe un mensaje al menos una vez por minuto (tendrá que agregar un nuevo mensaje de "mantenimiento" al protocolo de comunicación) - cualquier cliente que no reciba un mensaje de keepalive puede asumir con seguridad el servidor está inactivo y comienza a reconectarse.

Idealmente, este tipo de cosas se realiza mejor con difusión UDP y no JMS (para la sobrecarga), pero supongo que si tiene difusión UDP como una opción, usted usaría jgroups para agrupar detecion/failover/reencontrar tú.

+0

No tiene que ser instantáneo si eso es lo que está preguntando. ¿Hay alguna forma de que esto se pueda hacer con un bloque try/catch? – Icebreaker

+0

solo si la conexión subyacente arroja algún tipo de excepción cuando se corta. No podría decírtelo sin intentarlo. – radai

3

Debe hacer que su cliente implement javax.jmsExceptionListener.

Esto permitirá que su cliente reciba instantáneamente una devolución de llamada de la API de JMS cuando se pierda la conexión, incluso si su aplicación no desea publicar nada en este momento.

Después de crear el Connection, conectándolo e iniciando, llame al connection.setExceptionListener(myListener). Ver también Javadoc para Connection.

Cuestiones relacionadas