2017-07-26 2 views
1

Je publie des messages dans RabbitMQ et je voudrais suivre les erreurs lorsque RabbitMQ est en panne, pour cela j'ai ajouté un RetryTemplate avec le rappel de récupération, mais le rappel de récupération fournit seulement cette méthode getLastThrowable() et Je ne suis pas sûr de savoir comment fournir les détails des messages qui ont échoué lorsque RabbitMQ est en panne. (Selon la documentation « Le RecoveryCallback est quelque peu limitée en ce que le contexte de nouvelle tentative ne contient que le champ lastThrowable. Pour les cas d'utilisation plus sophistiqués, vous devez utiliser un RetryTemplate externe afin que vous puissiez transmettre des informations supplémentaires au RecoveryCallback via les attributs du contexte ") mais je ne sais pas comment le faire, si quelqu'un pouvait m'aider avec un exemple qui serait génial.Récupérer les détails du message dans Spring RecoveryCallback

Lapin Modèle

public RabbitTemplate rabbitMqTemplate(RecoveryCallback publisherRecoveryCallback) { 
    RabbitTemplate r = new RabbitTemplate(rabbitConnectionFactory); 
    r.setExchange(exchangeName); 
    r.setRoutingKey(routingKey); 
    r.setConnectionFactory(rabbitConnectionFactory); 
    r.setMessageConverter(jsonMessageConverter()); 

    RetryTemplate retryTemplate = new RetryTemplate(); 
    ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy(); 
    backOffPolicy.setInitialInterval(500); 
    backOffPolicy.setMultiplier(10.0); 
    backOffPolicy.setMaxInterval(10000); 
    retryTemplate.setBackOffPolicy(backOffPolicy); 
    r.setRetryTemplate(retryTemplate); 
    r.setRecoveryCallback(publisherRecoveryCallback); 
    return r; 
    } 

Récupération Callback

@Component 
public class PublisherRecoveryCallback implements RecoveryCallback<AssortmentEvent> { 
    @Override 
    public AssortmentEvent recover(RetryContext context) throws Exception { 
     log.error("Error publising event",context.getLastThrowable()); 
     //how to get message details here?? 
     return null; 
    } 
} 

AMQP Adaptateur Outbound

return IntegrationFlows.from("eventsChannel") .split() .handle(Amqp.outboundAdapter(rabbitMqTemplate) .exchangeName(exchangeName) .confirmCorrelationExpression("payload") .confirmAckChannel(ackChannel) .confirmNackChannel(nackChannel) ) .get();

Répondre

0

Le n'est pas possible parce que la fonction RabbitTemplate.execute() est pas déjà au courant de message envoyer, car il peut b e effectuée à partir de toute autre méthode, où nous ne pourrions pas avoir des messages à traiter:

return this.retryTemplate.execute(
        (RetryCallback<T, Exception>) context -> RabbitTemplate.this.doExecute(action, connectionFactory), 
        (RecoveryCallback<T>) this.recoveryCallback); 

Ce que je vous suggère de le faire est comme le stockage message au ThreadLocal avant l'envoi et l'obtenir à partir de là de votre commande RecoveryCallback.

+0

Le problème est que j'utilise le DSL d'intégration de ressort et je n'ai pas le contrôle du rabbitTemplate. –

+1

Donc, vous pouvez utiliser '.handle()' pour stocker de la valeur dans le 'ThreadLocal' et le retourner pour le prochain' .handle (Amqp.outboundChannelAdapter()) ' –

+1

parfait, je vais essayer de stocker le message (thread local) dans le premier handle() et ensuite passer cette valeur à l'adatper sortant, puis supprimer ce message du thread local une fois que j'ai reçu l'ack, merci Artem !!!!!!! –