Я борюсь с проблемой производительности уже более двух месяцев и не могу ее решить.Поэтому я хотел бы спросить идеи, в чем может быть проблема.
Проблема
Мы разрабатываем приложение с Spring Websocket, где клиент подписывается на свою очередь пользователя (/user/exchange/amq.direct/update
) для полученияобновления на них.Я настраиваю тест JMeter, который подписывается на пользовательскую очередь и отправляет сообщение каждые 4 секунды в течение 12 минут сеанса.Когда работает около 300 потоков (что составляет около 4500 запросов / мин), время отклика сервера резко увеличивается до более чем 6 секунд (что я считаю таймаутом в моем тесте JMeter).
Тествыполняется на отдельной машине, а приложение запускается на машине Linux (Debian) без других запущенных приложений.
То, что я уже пробовал
- Обмен внешним брокером сообщений (rabbitMQ) свнутренний.Интересно, что с помощью внутреннего брокера я могу обрабатывать до 2000 потоков, но затем получаю тот же тайм-аут.
- Я удалил все бизнес-логики и отправил только простую строку в качестве сообщения STOMP
- Я пробовал разные конфигурации для
ClientInboundChannel
и ClientOutboundChannel
- Я пробовал разные
SendBufferSizeLimit
в WebSocketMessageBrokerConfigurer
- Чтобы убедиться, что у меня нет проблем с сетью, я измерялвремя входящего сообщения от
ClientInboundChannel
до его отправки в ClientOutboundChannel
путем реализации для них ChannelInterceptors
.Это подтвердило, что ответу на отправку действительно требуется более 6 секунд. - В то время, когда время отклика через websocket становится таким ужасным (что, кстати, уже влияет на вызов подключения STOMP для новых потоков), у меня естьнет проблем с традиционными http-запросами.
- Моя запись полета показывает, что с процессором проблем нет, и при пике, составляющем всего 40%, также ОЗУ намного ниже порогового значения около 1,5 ГБ.
- Кроме того, я не вижу никакого конфликта потоков или горячего метода.
- У меня не исчерпаны дескрипторы файлов.
- Сборка мусора не проблема.У меня было только 4 прогона в течение 7 минут, и время GC составляет около 200-300 мс
Поскольку я уже давно работаю над этой темой, я, вероятно, забыл много вещей, которые я тожепопробовал, поэтому, пожалуйста, не стесняйтесь, чтобы начать разговор.
Я надеюсь, вы можете дать мне больше вдохновения, где искать проблему.
Обновление:
Я понялчто я могу увеличить ограничение кеша DefaultSubscriptionRegistry
, которое используется SimpleMessageBroker
.Это привело к простой обработке тысяч пользователей с приложением.Похоже, это проблема RabbitMQ.Я протестировал наш RabbitMQ с помощью инструмента PerfTest , и с этим тестом у меня не возникло никаких проблем.Но и в тесте используется не плагин STOMP, а amqp.
Итак, есть ли подобное ограничение для внешнего брокера сообщений в Spring Websocket?
Обновление 2:
Мне удалось воспроизвести проблему с примером приложения, которое выможно найти на github: https://github.com/mld-ger/spring-websocket-performance-issue
Кроме того, поскольку я считаю, что это может быть ошибкой в Spring, я открыл тикет: https://jira.spring.io/browse/SPR-16950