2016-09-21 5 views
1

Мой вопроса очень похож на этот: Why is there a delay in Spring AMQP Message dispatching from a filled Queue?Spring AMQP Сообщение Задержка

Я могу видеть задержку между двумя вызовами моего сообщением слушателя, даже если очередь заполнена сообщениями. Я поместил сообщение в журнале с указанием времени в самом начале метода, время в конце, и время, принявшего метод (в миллисекундах):

Start - End - время
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 мс (в среднем), но я могу видеть задержки больше tan 50 мс (иногда больше tan 100 мс).

Если изменить параметр PrefetchCount в SimpleMessageListenerContainer (например, 200), то прирост производительности considerabily, и теперь я могу видеть в журналах, что задержка имеет desapear:

Start - End - время
2016-09-21T10: 26: 27.336; - 2016-09-21T10: 26: 27,366; - 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, что означает, что брокер разрешает только одно неактивное сообщение у потребителя. Только когда это сообщение является ack'd, следующий отправляется.

Увеличение количества предварительной выборки резко увеличивает производительность, но может привести к нарушению порядка доставки.

Что это значит?

Рассмотрите количество предварительной выборки 10. Вы обрабатываете 5 сообщений, а затем получаете сбой (# 6), и сообщение отклоняется и запрашивается (если такая настройка).

Сообщение # 6 будет отправлено повторно, если вы воспользовались всеми запрограммированными сообщениями - следовательно, это будет не по порядку.

Если вы никогда не запрашиваете сообщения, тогда нет проблем с доставкой сообщений.

+0

Спасибо, Гэри. А как насчет AcknowledgeMode.NONE? Должна быть лучше, чем иметь действительно большой ** prefetchCount **? – jandres

+0

Я не знаю, что вы подразумеваете под «действительно большим», но, да, оно должно быть достаточно большим. Мы не устанавливаем 'basicQos' при использовании' NONE', поэтому брокер будет отправлять сообщения как можно быстрее. С версиями до 1.3.0 это может привести к ситуации нехватки памяти, если слушатель не может идти в ногу. С 1.3.0 и более поздними версиями мы используем 'prefetchCount', чтобы поддерживать это количество сообщений и блокировать доставку, если слушатель не может идти в ногу. –

+0

Поймите, что вы потеряете любые предварительно запрограммированные сообщения с этим режимом, если сервер опустится. Вы можете использовать ackmode AUTO с 'txSize = 100', чтобы отправлять только каждые 100 сообщений. Однако вы можете получить дубликаты в этом случае. –

 Смежные вопросы

  • Нет связанных вопросов^_^