2016-09-21 128 views
1

我的问题是非常相似,这一个:Why is there a delay in Spring AMQP Message dispatching from a filled Queue?春AMQP的消息延迟

我可以看到即使在队列中充满了我的邮件消息监听器的两个调用之间的延迟。 - 完 - 时间
2016-09-

开始:我已在法的十分开始时,在结束的时间,而把该方法的时间(毫秒)放一个记录信息与时间21T10:08:55.263; - 2016-09-21T10:08:55.278; - 15;
2016-09-21T10:08:55.356; - 2016-09-21T10:08:55.356; - 0;
2016-09-21T10:08:55.388; - 2016-09-21T10:08:55.388; - 0;
2016-09-21T10:08:55.466; - 2016-09-21T10:08:55.466; - 0;

处理消息的时间大约是10毫秒(平均),但我可以看到延迟大于50毫秒(有时更大的tan 100毫秒)。

如果我改变SimpleMessageListenerContainer一样的参数PrefetchCount(例如200),则业绩增长considerabily,现在我可以在所述延迟具有desapear的日志中看到: - 完 -

开始时间
2016-09-21T10:26:27.336; - 2016-09-21T10:26:27.336; - 0;
2016-09-21T10:26:27.336; - 2016-09-21T10:26:27.351; - 15;
2016-09-21T10:26:27.351; - 2016-09-21T10:26:27.351; - 0;
2016-09-21T10:26:27.351; - 2016-09-21T10:26:27.351; - 0;

我的问题是:

  • 什么casues这种延迟?真的网络延迟?我怎样才能证明这一点?
  • 我在有关“prefetchCount”的文档中看到:“这个越高,消息传递的速度就越快,但是非顺序处理的风险就越高。”那真的意味着什么?如果我需要按顺序处理消息,我可以将“prefetchCount”的值设置为tan 1吗?

我的配置是这样的:

@Bean 
    public MessageListenerAdapter broadcastMessageListenerAdapter() { 
     return new MessageListenerAdapter(myHandlerBroadcast(), "onMessage"); 
    } 

@Bean(name="myBroadcastMessageListenerContainer") 
public SimpleMessageListenerContainer myBroadcastMessageListenerContainer() 
{ 
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(myConnectionFactory()); 
    container.setQueueNames(PX_BROADCAST_QUEUE + environment.getProperty("my.user")); 
    container.setMessageListener(broadcastMessageListenerAdapter()); 
    container.setAcknowledgeMode(AcknowledgeMode.AUTO); 
    container.setMessageConverter(myMessageConverter()); 
    container.setConcurrentConsumers(1); 
    container.setAutoStartup(false); 
    container.setPrefetchCount(500);  // ¿1? 
    return container; 
} 

@Bean(name="myHandlerBroadcast") 
public MyHandlerBroadcast myHandlerBroadcast(){ 
    return new MyHandlerBroadcast(); 
} 

回答

2

是;它是网络。您可以使用网络监视器“证明”它。默认prefetchCount是1,这意味着经纪人只允许在消费者处发送一封未经确认的消息。只有当该消息被删除时,才会发送下一个消息。

增加预取计数会显着提高性能,但会导致乱序传递。

这是什么意思?

考虑预取计数为10.处理5条消息,然后发生故障(#6),并且消息被拒绝并重新排序(如果已这样配置)。

消息#6将在消耗完所有预取消息后重新发送 - 因此它将失灵。

如果您从不要求消息,那么消息传递顺序没有问题。

+0

谢谢你加里。那么AcknowledgeMode.NONE呢?应该比拥有非常大的** prefetchCount **更好? – jandres

+0

我不知道你的意思是“真的很大”,但是,是的,它应该是相当大的。我们在使用'NONE'时不设置'basicQos',因此代理将尽可能快地发送消息。使用1.3.0之前的版本,如果听者无法跟上,这可能会导致内存不足。在1.3.0及更高版本中,我们使用'prefetchCount'来保持这些消息的准备就绪,并在侦听器无法跟上时阻止传送。 –

+0

了解,尽管如果服务器出现故障,您将失去使用该模式的任何预取消息。你可以使用'txSize = 100'的ackmode AUTO模式来每发送100条消息就发送一个确认消息。不过,你可以在这种情况下获得重复。 –