Задержка вызова JmsTemplate в высоком параллелизме - PullRequest
1 голос
/ 14 июня 2019

В настоящее время мы выполняем нагрузочное тестирование с более чем 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

Проблема заключается в том, что перед отправкой сообщения в MQ существует длительное время ожидания (более 1 минуты), когда нагрузочный тест достиг 100TPS, и нет подсказки, где находится узкое место. Единственные подозрительные точки:

  1. Вызов обертки компонента клиента MQ (пружинный компонент) JmsTemplate
  2. Вызов JmsTemplate для отправки сообщения

Из нашей dynatrace не объясняется, какая из них была медленной; Однако фактическое время отправки было очень быстро. Итак, мы подозревали, что это может быть проблема с любым из следующих:

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.

...