В настоящее время мы проводим нагрузочное тестирование с более чем 200 TPS, чтобы имитировать высокий параллелизм с приложением, используя Spring Boot 2.1.1 и Spring JMS с IBM MQ Spring Boot Starter v2.1.1. Кроме того, мы настроили пул соединений MQ на максимальный размер соединения 500 с тайм-аутом простоя 60 секунд.
ibm.mq.pool.enabled=true
ibm.mq.pool.idleTimeout=60
ibm.mq.pool.maxConnections=500
Проблема в том, что существует длительное время ожидания (более 1 минуты) перед отправкой сообщения в MQ, когда нагрузочный тест достиг 100TPS, и нет никакой подсказки, где находится узкое место. Единственные подозрительные моменты:
- Вызов клиентского компонента MQ (компонент Spring), обертывающего JmsTemplate
- Вызов JmsTemplate для отправки сообщения
Из нашей динамической трассировки нельзя понять, какой из них был медленным; однако фактическое время отправки было очень быстрым. Итак, мы подозревали, что это может быть проблема с любым из следующего:
1) JmsTemplate является синглтоном и может быть узким местом 2) MQClient.class может быть бутылкой по той же причине, что и синглтон 3) Пул соединений MQ не работает должным образом
Мы пытались точно определить это многими способами, такими как ведение журнала и трассировка с помощью Dynatrace, во время теста производительности. Но мы пока не нашли первопричину, почему так долго не отправлялось сообщение в MQ
@Component
@AllArgsConstructor
@Slf4j
public class MQClient {
private final JmsTemplate jmsTemplate;
private final QueueResolver queueResolver;
public String requestSomething(
final String someId,
final String messageText) throws JMSException {
final AtomicReference<Message> message = new AtomicReference<Message>();
jmsTemplate.send(
queueResolver.getRequestQueueName(someId),
new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
final BytesMessage msg = session.createBytesMessage();
msg.writeBytes(messageText.getBytes(Charset.forName("UTF-8")));
msg.setJMSReplyTo(session.createQueue(
queueResolver.getReplyQueueName(someId)));
message.set(msg);
return message.get();
}
});
return message.get().getJMSMessageID();
}
}
Ошибки не было, так как перед отправкой сообщения MQ пришлось долго ждать.