Spring AMQP 中的 SimpleMessageListenerContainer 和 DirectMessageListenerContainer 有什么区别?

What's the difference between SimpleMessageListenerContainer and DirectMessageListenerContainer in Spring AMQP?

Spring AMQP 中的 SimpleMessageListenerContainerDirectMessageListenerContainer 有什么区别?我检查了他们的两个文档页面,SimpleMessageListenerContainer 几乎没有对内部工作原理的解释,DirectMessageListenerContainer 有以下解释:

The SimpleMessageListenerContainer is not so simple. Recent changes to the rabbitmq java client has facilitated a much simpler listener container that invokes the listener directly on the rabbit client consumer thread. There is no txSize property - each message is acked (or nacked) individually.

我不太明白这些是什么意思。它说 listener container that invokes the listener directly on the rabbit client consumer thread。如果是这样,那么SimpleMessageListenerContainer如何调用?

我写了一个小应用程序并使用了 DirectMessageListenerContainer,只是为了看看区别,我切换到 SimpleMessageListenerContainer,但据我所知,RabbitMQ 方面没有区别。 Java 方面的区别在于方法(SimpleMessageListenerContainer 提供了更多)和日志(DirectMessageListenerContainer 记录了更多内容)

我想知道使用其中每一个的场景。

在 DirectMessageListenerContainer 中,一些逻辑被移动到 AMQP 实现中,而不是像 SimpleMessageListenerContainer 那样的 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);
        .
        .

在较新的实现中,每条消息都直接在线程上确认,并基于事务模型(单一或publisher confirms)消费者向 Rabbit MQ 发送确认

SMLC 为每个轮询内部队列的消费者(并发)提供了一个专用线程。当一条新消息到达客户端线程上的消费者时,它会被放入内部队列,消费者线程会拾取它并调用侦听器。这是客户端的早期版本所必需的,以提供 multi-threading。使用较新的客户端这不是问题,因此我们可以直接调用侦听器(因此得名)。

除了 txSize 之外还有其他一些差异。

参见Choosing a Container