2015-10-17 18 views
6

Ho la seguente applicazione PHP. Che pubblica un utente registrati a una coda di messaggi. L'applicazione Java legge da quella coda e la importa. Speriamo che lo schema qui sotto lo descriva. Sto solo lavorando con il lato Java delle cose. I messaggi JSON esistono già sulla coda.RabbitMQ - Apache Camel Reading Messaggi cosa fare con i messaggi non riusciti

enter image description here

percorso (Java Il consumo di lato).

@Component 
public class SignUpRouting { 

    errorHandler(deadLetterChannel("rabbitmq://signUpDeadLetter.exchange?username=etc..").useOriginalMessage()); 

    from("rabbitmq://phpSignUp.exchange?username=etc....") 
      .routeId("signUpRoute") 
      .processRef("signUpProcessor") 
      .end(); 
    //.... 

Il processore ..

@Component 
public class SignupProcessor implements Processor { 

    private ObjectMapper mapper = new ObjectMapper(); 

    @Override 
    public void process(Exchange exchange) throws Exception { 

     String json = exchange.getIn().getBody(String.class); 
     SignUpDto dto = mapper.readValue(json, SignUpDto.class); 

     SignUp signUp = new SignUp(); 
     signUp.setWhatever(dto.getWhatever()); 
     //etc.... 

     // save record 
     signUpDao.save(signUp); 
    } 
} 

mia domanda è questa .. Cosa devo fare devo fare quando il trasformatore non importare il messaggio.

Diciamo per esempio che c'era un'eccezione DAO. Un campo dati potrebbe essere stato toolong o l'importazione era nel formato errato. Non voglio perdere il messaggio. Mi piacerebbe vedere l'errore e riprovare l'importazione. Ma non vorrei continuare a ritentare il messaggio ogni 30 secondi.

Sto pensando che avrei bisogno di creare un'altra coda .. Una coda di messaggi non funzionanti e riproverò indefinitamente il messaggio ogni 6 ore? .. Vorrei quindi visualizzare i registri vedere l'errore e caricare una correzione e il messaggio sarebbe rielaborato?

Come implementarlo? O sono sulla strada sbagliata?

EDIT ho provato a regolare deadLetterExchange per vedere se sarebbe ottenere le cose nella giusta direzione ... comunque errori e dice coda non può essere non nullo

rabbitmq://phpSignUp.exchange?username=etc...&deadLetterExchange=signUpDeadLetter.exchange 
+0

se si utilizza un'altra coda perché non si memorizza il messaggio esatto non riuscito insieme alla traccia dello stack dell'eccezione e quindi si elaborano i dati da quella coda –

+0

non sono sicuro di averlo compreso. potresti fornire un esempio? –

+0

Se si ha il lusso di un team di supporto, invierei il messaggio a un'altra coda o scrivere su una tabella di database e quindi inviare una e-mail per avvisare il personale di supporto. Crea un'altra interfaccia che permetta al personale di supporto di modificare il testo del messaggio e reinserirlo nel processore di registrazione.Qualunque cosa tu faccia richiederà un intervento manuale. Progettare di conseguenza. Ci dovrebbe essere una buona validazione sull'app PHP in modo tale che il suo sia un evento raro. – Sammy

risposta

2

Ecco un esempio di utilizzare Dead Letter intestazioni:

 <from uri="rabbitmq://localhost/youexchange?queue=yourq1&amp; 
      exchangeType=topic&amp; 
      routingKey=user.reg.*&amp; 
      deadLetterExchange=dead.msgs&amp; 
      deadLetterExchangeType=topic&amp; 
      deadLetterRoutingKey=dead.letters&amp; 
      deadLetterQueue=dead.letters&amp; 
      autoAck=false&amp; 
      autoDelete=false"/> 

      <!--We can use onException to make camel to retry, and after that, dead letter queue are the fallback--> 
     <onException useOriginalMessage="true"> 
      <exception>java.lang.Exception</exception> 
      <redeliveryPolicy asyncDelayedRedelivery="true" maximumRedeliveries="3" redeliveryDelay="5000"/> 
     </onException> 

Abbiamo bisogno di spegnere AUTOACK e impostare DeadLetterQueue, poi se c'è un'eccezione gettata, il messaggio sarà in morti lettere in coda. Per utilizzare onException, possiamo controllare il nuovo tentativo prima che il dromedico lasci cadere il messaggio nella coda di messaggi non recapitati.

+0

Un paio di domande. Perché abbiamo bisogno di girare di AutoAck? e cos'è deadLetterExchangeType = topic? –

+0

Se autoAck è attivo, il cammello invierà basic.ack mentre ricevono i messaggi. Non sarà possibile per cammello inviare un basic.refuse o basic.nack su eccezioni, quindi gli attributi deadletter saranno inutili. – sanigo

+0

E gli attributi deadLetterExchangeXXX vengono utilizzati per instradare le lettere morte nello scambio e nella coda specificati. Nelle impostazioni demo, ho usato topic, ma puoi usare altri tipi di scambio. – sanigo

1

Si potrebbe utilizzare onException per rilevare eccezioni, se c'è un'eccezione, il messaggio sarà indirizzato allo scambio di lettere morte, ecco l'esempio in DSL di primavera:

<onException useOriginalMessage="true"> 
      <exception>java.sql.SQLException</exception> 
      <redeliveryPolicy asyncDelayedRedelivery="true" maximumRedeliveries="1" redeliveryDelay="1000"/> 

      <inOnly uri="rabbitmq://localhost/dead.msgs?exchangeType=fanout&amp; 
        autoDelete=false&amp; 
        bridgeEndpoint=true"/> 
</onException> 
+0

Questa è una buona risposta e una soluzione praticabile +1. Tuttavia, mi sembra che non utilizzi le intestazioni e la configurazione della lettera morta specifica di rabbitmq. Come visto http://camel.apache.org/rabbitmq.html –

+0

perché è necessario impostare bridgeEndpoint = true. a cosa serve? –

+0

Se non si aggiunge l'attributo, la coda di destinazione non riceverà alcun messaggio. – sanigo

Problemi correlati