Spring-RabbitMQ - mit manueller Kanal-Bestätigung auf einen Dienst mit @RabbitListener Konfiguration
Wie zu erkennen die Nachrichten manuell, ohne die Verwendung der automatischen Anerkennung.
Gibt es eine Möglichkeit, verwenden Sie diese zusammen mit der @RabbitListener
und @EnableRabbit
- Stil der Konfiguration.
Der größte Teil der Dokumentation erzählt uns SimpleMessageListenerContainer
zusammen mit ChannelAwareMessageListener
.
Jedoch mit, dass wir verlieren die Flexibilität, die bereitgestellt wird mit den Anmerkungen.
Ich konfiguriert haben, meinen Dienst als unten :
@Service
public class EventReceiver {
@Autowired
private MessageSender messageSender;
@RabbitListener(queues = "${eventqueue}")
public void receiveMessage(Order order) throws Exception {
//code for processing order
}
Meine RabbitConfiguration ist als unten
@EnableRabbit
public class RabbitApplication implements RabbitListenerConfigurer {
public static void main(String[] args) {
SpringApplication.run(RabbitApplication.class, args);
}
@Bean
public MappingJackson2MessageConverter jackson2Converter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
return converter;
@Bean
public SimpleRabbitListenerContainerFactory myRabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(rabbitConnectionFactory());
factory.setMaxConcurrentConsumers(5);
factory.setMessageConverter((MessageConverter) jackson2Converter());
factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
return factory;
}
@Bean
public ConnectionFactory rabbitConnectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setHost("localhost");
return connectionFactory;
}
@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
registrar.setContainerFactory(myRabbitListenerContainerFactory());
}
@Autowired
private EventReceiver receiver;
}
}
Jede Hilfe wird sehr geschätzt, wie die Anpassung manuelle Kanal-Bestätigung zusammen mit den oben genannten Stil der Konfiguration.
Wenn wir implementieren die ChannelAwareMessageListener dann die onMessage-Signatur ändern.
Können wir implementieren ChannelAwareMessageListener auf einen Dienst ?
- Die Frage, warum Sie selbst dies tun müssen. Wenn Ihr code ist wie in der Antwort unten (lehne auf Fehler, ansonsten ack), der container wird automatisch für Sie mit AUTO-ack-Modus - wenn der Hörer löst eine exception aus, wird die Nachricht abgelehnt werden; andernfalls acked.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Fügen Sie die
Channel
zu den@RabbitListener
Methode...und verwenden Sie das tag in der
basicAck
,basicReject
.BEARBEITEN
Anwendung.Eigenschaften:
channel.basicAck('100001', false)
. Jetzt unabhängig davon, ob ich "true" oder "false" in der Zeile oben der code der listener und Warteschlange gehe in Endlosschleife. So können Sie mir helfen wie man das umgehen kann.spring.rabbitmq.listener.simple.acknowledge-mode
. Im Frühjahr Boot 2.0 kann es seinspring.rabbitmq.listener.simple.acknowledge-mode
oderspring.rabbitmq.listener.direct.acknowledge-mode
da Spring AMQP unterstützt jetzt 2 container-Typen. Siehe Dokumentation.Nur für den Fall, Sie brauchen, um zu verwenden #onMessage() von ChannelAwareMessageListener Klasse. Dann können Sie es auf diese Weise.
}
Und für die rabbitConfiguration
}
Dank für gary ' s helfen. Ich endlich das Problem gelöst. Ich dokumentierte dies zum Wohle der anderen.
Dies muss dokumentiert werden als Teil der standard-Dokumentation im Frühjahr AMQP Referenz-Dokumentation Seite.
Service Klasse ist, wie unten beschrieben.
die Konfiguration wurde auch geändert, wie unten
Hinweis: keine Notwendigkeit zu konfigurieren Rabbitconnectionfactory oder containerfactor etc, da die annotation implicity kümmern sich um alles.
basicConsume
oderbasicGet
gegen den Kanal -basicGet
Holen Sie eine weitere Nachricht. Die listener-container ist bereits das konsumieren von ihm und die Nachricht wird verwendet, um die Methode aufzurufen, hat eine andere Lieferung tag. Verwenden Sie stattdessen@Header(AmqpHeaders.DELIVERY_TAG) long tag
. Siehe meine Antwort (edit).getDefaultConsumer()
macht nichts in diesem Fall (zurücknull
) undbasicGet
holt die nächste Nachricht in der Warteschlange.basicAck
können Sie sehen, die un-acked Nachricht in das Kaninchen Admin UI; Schritt über, und die Meldung ist acked.