Задержка вызова JmsTemplate при высоком уровне параллелизма

В настоящее время мы проводим нагрузочное тестирование с более чем 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, и нет никакой подсказки, где находится узкое место. Единственные подозрительные моменты:

  1. Вызов клиентского компонента MQ (компонент Spring), обертывающего JmsTemplate
  2. Вызов 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 пришлось долго ждать.


person Michael J    schedule 14.06.2019    source источник
comment
Мы подтвердили, что до вызова JmsTemplate это было быстро, и пул соединений долго ждал, чтобы создать новое соединение. Вероятно, конфигурация сервера и клиента IBM MQ не соответствует...   -  person Michael J    schedule 17.06.2019


Ответы (1)


Пул соединений MQ не работает должным образом

Ваше значение тайм-аута бездействия составляет 60 мс. По умолчанию 30000 мс (30 секунд). Это максимальное время в мс, в течение которого соединение может простаивать в пуле. Таким образом, с вашим свойством тайм-аута простоя соединения удаляются после 60 мс простоя и создаются при необходимости. И создание соединения занимает много времени.

Попробуй это:

ibm.mq.pool.idleTimeout=60000
person Devrim    schedule 19.03.2020