2010-07-06 14 views
16

En JMS es fácil averiguar si se pierde una conexión, ocurre una excepción. ¿Pero cómo averiguo si la conexión está allí nuevamente?¿Cómo saber si la conexión JMS está allí?

Escenario: uso JMS para comunicarme con mi servidor. Ahora mi conexión se interrumpe (el servidor está inactivo), lo que da como resultado una excepción. Hasta aquí todo bien. Si el servidor vuelve a estar activo y la conexión se restablece, ¿cómo lo sé?

No veo ningún Oyente que facilite dicha información.

Respuesta

15

Ahhh ... el viejo acertijo de manejo/reconexión de excepciones.

Existen algunos proveedores de transporte que volverán a conectar automáticamente su aplicación y la que hará que la aplicación vuelva a conectarse. En general, las reconexiones ocultan la excepción de la aplicación. El inconveniente es que no desea que la aplicación se cuelgue para siempre si los nodos de mensajería remota están inactivos, por lo que en última instancia, debe incluir alguna lógica de reconexión.

Ahora esta es la parte interesante: ¿cómo manejas las excepciones de una manera neutral como proveedor? La excepción JMS es prácticamente inútil. Por ejemplo, una "excepción de seguridad" puede ser que las políticas de seguridad de Java son demasiado restrictivas, que los permisos del sistema de archivos son demasiado restrictivos, que las credenciales de LDAP fallaron, que la conexión al transporte falló, que la apertura de la cola o el tema fallado o cualquiera de docenas de otros problemas relacionados con la seguridad. Es la excepción vinculada que tiene los detalles del proveedor de transporte que realmente ayudan a solucionar el problema. Mis clientes generalmente han tomado uno de tres enfoques diferentes aquí ...

  1. Trate todos los errores de la misma manera. Cierra todos los objetos y reinicialízalos. esto es portátil JMS.
  2. Permita que la aplicación inspeccione las excepciones vinculadas para distinguir entre errores fatales y transitorios (es decir, error de autenticación frente a cola llena). No proveedor portátil.
  3. Clases de manejo de errores específicas del proveedor. Un híbrido de los otros dos.

En su caso, los objetos de cola y tema probablemente solo sean válidos en el contexto de la conexión original. Suponiendo que un proveedor que vuelve a conectar automáticamente el hecho de que recibió una excepción significa que la reconexión falló y el contexto para los objetos de cola y tema no se pudo restaurar. Cierra todos los objetos y reconecta.

Si desea hacer algo más específico para el proveedor, como distinguir entre errores transitorios y permanentes, es una de esas cosas "depende" y tendrá que averiguarlo caso por caso.

+0

La cuestión es que, si tengo, digamos, un cliente GUI que se comunica a través de JMS con un servidor, simplemente no tiene sentido inundar la cola con mensajes que no se pueden manejar de todos modos, porque el servidor está inactivo. Así que supongo que la única opción realista sería enviar un "ping" en intervalos (con un ttl bajo) para verificar si todavía es posible (o de nuevo) comunicarse con el servidor. ¿Es este un enfoque que recomendarías? – Mauli

+0

Ese es un enfoque común. Por ejemplo, WebSphere MQ Explorer actualizará su conexión al administrador de colas cada 15 segundos de forma predeterminada. Si falla la llamada API, la reconexión se impulsa en el cliente. Si eso funciona, la GUI solo tarda un segundo extra en responder. Si falla, la GUI obtiene la excepción y maneja su propia lógica de reconexión. En el caso de las aplicaciones, por lo general aconsejo a las personas que diseñen llamadas de instrumentación en su API, como por ejemplo un "ping" no transaccional. –

4

La especificación JMS no describe ningún protocolo de transporte, no dice nada sobre las conexiones (es decir, si el intermediario debe mantenerlas activas o establecer una nueva conexión para cada sesión). Entonces, creo que lo que quiere decir es

Ahora mi conexión se interrumpe (el servidor está inactivo), lo que da como resultado una excepción.

es que estás tratando de enviar un mensaje y estás obteniendo una JmsException.

Creo que la única manera de ver si el intermediario está activo es intentar enviar un mensaje.

+1

Exactamente - porque JMS es un protocolo asíncrono, la aplicación puede haber conexiones establecidas de forma transitoria - sólo porque una conexión tuvo éxito doesn no significa que la cola ahora está disponible. –

1

Su única opción en el caso de una Excepción de JMS basada en la conexión es intentar restablecer la conexión en su controlador de excepción y vuelva a intentar la operación.

5

La mejor manera de controlar a excepción de conexión es establecer una escucha de excepciones, por ejemplo:

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(); 
Cuestiones relacionadas