Мой вопроса очень похож на этот: 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();
}
Спасибо, Гэри. А как насчет AcknowledgeMode.NONE? Должна быть лучше, чем иметь действительно большой ** prefetchCount **? – jandres
Я не знаю, что вы подразумеваете под «действительно большим», но, да, оно должно быть достаточно большим. Мы не устанавливаем 'basicQos' при использовании' NONE', поэтому брокер будет отправлять сообщения как можно быстрее. С версиями до 1.3.0 это может привести к ситуации нехватки памяти, если слушатель не может идти в ногу. С 1.3.0 и более поздними версиями мы используем 'prefetchCount', чтобы поддерживать это количество сообщений и блокировать доставку, если слушатель не может идти в ногу. –
Поймите, что вы потеряете любые предварительно запрограммированные сообщения с этим режимом, если сервер опустится. Вы можете использовать ackmode AUTO с 'txSize = 100', чтобы отправлять только каждые 100 сообщений. Однако вы можете получить дубликаты в этом случае. –