Cliente Java RabbitMQ: ¿cómo manejar sensatamente las excepciones y los cierres?

Esto es lo que sé hasta ahora (corrígeme):

En el cliente Java RabbitMQ, las operaciones en un canal se lanzan IOExceptioncuando hay una falla general de la red (datos mal formados del agente, fallas de autenticación, latidos perdidos).

Las operaciones en un canal también pueden generar la ShutdownSignalExceptionexcepción no verificada, generalmente AlreadyClosedExceptioncuando tratamos de realizar una acción en el canal / conexión después de que se cerró.

El proceso de apagado ocurre en caso de "falla de la red, falla interna o apagado local explícito" (por ejemplo, a través de channel.close () o connection.close ()). El evento de apagado propaga la "topología", desde Conexión -> Canal -> Consumidor, y cuando se llama al canal al que llama, se llama al handleShutdown()método del Consumidor .

Un usuario también puede agregar un escucha de apagado que se llama después de que se completa el proceso de apagado.

Esto es lo que me falta:

  1. Dado que una IOException indica una falla en la red, ¿también inicia una solicitud de apagado?
  2. ¿Cómo afecta el uso del modo de recuperación automática a las solicitudes de apagado? ¿Hace que las operaciones del canal se bloqueen mientras intenta reconectarse con el canal, o se seguirá lanzando la excepción ShutdownSignalException?

Así es como estoy manejando las excepciones en este momento, ¿es este un enfoque sensato?

Mi configuración es que estoy sondeando un consumidor de colas y enviando tareas a un grupo de trabajadores. El cliente rabbitmq está encapsulado MyRabbitMQWrapperaquí. Cuando se produce una excepción al sondear la cola, apago todo y reinicio el cliente. Cuando ocurre una excepción en el trabajador, también lo registro y termino el trabajador.

Mi mayor preocupación (relacionada con la Pregunta 1): supongamos que se produce una IOException en el trabajador, luego la tarea no se ataca. Si no se produce el apagado, ahora tengo una tarea no confirmada que estará en el limbo para siempre.

Pseudocódigo:

class Main {
    public static void main(String[] args) {
        while(true) {
            run();
            //Easy way to restart the client, the connection has been
            //closed so RabbitMQ will re-queue any un-acked tasks.
            log.info("Shutdown occurred, restarting in 5 seconds");
            Thread.sleep(5000);
        }
    }

    public void run() {
      MyRabbitMQWrapper rw = new MyRabbitMQWrapper("localhost");

      try {
        rw.connect();

        while(!Thread.currentThread().isInterrupted()) {
           try {
               //Wait for a message on the QueueingConsumer
               MyMessage t = rw.getNextMessage();
               workerPool.submit(new MyTaskRunnable(rw, t));
           } catch (InterruptedException | IOException | ShutdownSignalException e) {
               //Handle all AMQP library exceptions by cleaning up and returning
               log.warn("Shutting down", e);
               workerPool.shutdown();
               break;
           }
        }
      } catch (IOException e) {
        log.error("Could not connect to broker", e);
      } finally {
        try { 
            rw.close(); 
        } catch(IOException e) { 
            log.info("Could not close connection");
        }
      }
    }
}

class MyTaskRunnable implements Runnable {
    ....

    public void run() {
        doStuff();
        try {
            rw.ack(...);
        } catch (IOException | ShutdownSignalException e) {
            log.warn("Could not ack task");
        }
    }
}
Respuesta 1

Después de actualizar a log4j2 versión 2.6, me enfrento a estas advertencias: 2016-06-06 16: 36: 14,920 localhost-startStop-1 WARN El Logger foo.bar se creó con el mensaje factory org.apache.logging.log4j.spi .. ..

Cuando construyo mi proyecto usando subprocesos, es decir, mvn -T 4 install -Dmaven.test.skip = true Me aparece como Tiempo total: 10: 17.623s (Reloj de pared) ¿Qué se entiende por reloj de pared aquí? Cuando construyo normalmente estoy ...

Me gustaría saber qué compiladores nativos de Java se pueden recomendar para compilar código Java en binarios de Windows y Mac OS X. Tal vez alguien sepa qué compiladores se han utilizado para crear el Eclipse ...

No puedo entender por qué en la última iteración 12 está reemplazando 14. Si las condiciones tienen una matriz de corriente máxima de órgano grande solo entonces sustituir por otro máximo sigue siendo el mismo. Posible explicación por favor? ...