Spring AMQP中的SimpleMessageListenerContainer
和DirectMessageListenerContainer
有什么区别?我检查了他们的两个文档页面,SimpleMessageListenerContainer
几乎没有内部工作的解释,DirectMessageListenerContainer
则有以下解释:
SimpleMessageListenerContainer 并不是那么简单。对Rabbitmq Java客户端的最新更改促进了一个更简单的侦听器容器,该容器直接在Rabbit客户端使用者线程上调用侦听器。没有txSize属性-每个消息都被单独确认(或取消确认)。
我真的不明白这些是什么意思。它说listener container that invokes the listener directly on the rabbit client consumer thread
。如果是这样,那么SimpleMessageListenerContainer
如何进行调用?
我写了一个小应用程序,使用了DirectMessageListenerContainer
,只是为了看到区别,我切换到SimpleMessageListenerContainer
,但据我所知,RabbitMQ方面没有任何区别。从Java角度来看,区别在于方法(SimpleMessageListenerContainer
提供了更多)和日志(DirectMessageListenerContainer
记录了更多的东西)
我想知道使用其中每个场景的场景。
答案 0 :(得分:2)
SMLC对于每个使用者(并发)都有一个专用线程,该线程轮询内部队列。当新消息在客户端线程上到达消费者时,它将被放入内部队列中,然后消费者线程将其拾取并调用侦听器。早期版本的客户端需要提供多线程。对于较新的客户端,这不是问题,因此我们可以直接调用侦听器(因此命名)。
除了txSize
以外,还有一些其他区别。
答案 1 :(得分:1)
在DirectMessageListenerContainer中,某些逻辑被移到AMQP实现中,与SimpleConcepterContainer一样,与ListenerContainer相反
这就是SimpleMessageListenerContainer中的Javadocs对于setTxSize()的说法
/**
* Tells the container how many messages to process in a single transaction (if the channel is transactional). For
* best results it should be less than or equal to {@link #setPrefetchCount(int) the prefetch count}. Also affects
* how often acks are sent when using {@link AcknowledgeMode#AUTO} - one ack per txSize. Default is 1.
* @param txSize the transaction size
*/
每处理txSize个消息,客户端就会发送一个ack。在方法
中对此进行控制private boolean doReceiveAndExecute(BlockingQueueConsumer consumer) throws Throwable { //NOSONAR
Channel channel = consumer.getChannel();
for (int i = 0; i < this.txSize; i++) {
logger.trace("Waiting for message from consumer.");
Message message = consumer.nextMessage(this.receiveTimeout);
.
.
在较新的实现中,每条消息都直接在线程上进行确认,并根据消费者的事务处理模型(Single或publisher confirms)将确认发送给Rabbit MQ