Spring Integration Rendezous通道确认速度慢

时间:2018-03-04 01:31:56

标签: spring-integration spring-amqp spring-dsl

我有一个与队列通道配合使用的dsl流程。但是,当我使用Rendezvous通道使其同步时,我获得最多30条消息/秒的确认率。我的处理程序只需350微秒即可完成整个过程,但确认率仍然很低。这大大地堆积了兔子队列。我甚至将并发消费者扩展到10并增加了预取,但这没有帮助。然后我添加了几个更多缩放的实例,但这有助于将ack率提高到45左右/秒。

如何更快地确认流量确认?我期待每秒超过500的速度。

Dsl Flow:

SimpleMessageListenerContainer simpleMessageListenerContainer = profileTagRabbitMLCConfig.transactedChannelSpanRabbitSMLC(queueName)

simpleMessageListenerContainer?.setConcurrentConsumers(concurrentConsumer)
            simpleMessageListenerContainer?.setPrefetchCount(prefetch)

            return IntegrationFlows.from(Amqp.inboundAdapter(simpleMessageListenerContainer))
                    .channel(rendezvousTransformerChannel1())
                    .transform(myTransformer, 'transform', { e -> e.advice(adviceWithRecoverer) })
                    .channel(rendezvousTransformerChannel2())
                    .handle(myHandler, 'save', { e -> e.advice(adviceWithRecoverer) })
                    .get()

同步频道:

@Bean
MessageChannel rendezvousTransformerChannel1() {
    return MessageChannels.rendezvous().get()
}

@Bean
MessageChannel rendezvousHandlerChannel() {
    return MessageChannels.rendezvous().get()
}

容器:

SimpleMessageListenerContainer 
transactedChannelSpanRabbitSMLC(CachingConnectionFactory rabbitConnectionFactory, String queueName){

    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer()
    container.setConnectionFactory(rabbitConnectionFactory)
    container.setQueueNames(queueName)
    container.setChannelTransacted(true)
    container
}

重试的恢复建议:

Advice getRetryAdviceWithRecovery() {
    RequestHandlerRetryAdvice advice = new RequestHandlerRetryAdvice()
    advice.setRetryTemplate(getRetryTemplate())
    advice.recoveryCallback = getRecoveryCallback() // sends message to rabbit exchange
    advice
}

轮询:

@Bean(name = PollerMetadata.DEFAULT_POLLER)
    public PollerMetadata poller() {
        return Pollers.fixedDelay(100).maxMessagesPerPoll(500L).get();
    }

1 个答案:

答案 0 :(得分:0)

您的使用案例是什么促使您使用RendezvousChannel

这种情况非常罕见,而且我不认为我曾经在同一个流程中见过2。

您必须拥有此频道类型的轮询;我没有看到它们,所以它暗示你有一个默认的轮询器bean。

您需要显示您的轮询器,但我怀疑它没有很好地调整。 RendezvousChannel send()阻止receive()

无论如何,如果在侦听器容器线程上使用任何类型的线程切换(QueueChannelRendezvousChannel),都会导致消息丢失。

您可能应该从您的流中移除那些将使用.channel()的{​​{1}}。

如果要进行并发,请在侦听器容器上使用DirectChannel属性。

  

concurrentConsumers

如果您要在container.setChannelTransacted(true)发布消息,交易也非常昂贵。