Node.JS Высокое использование памяти WebSocket - PullRequest
1 голос
/ 20 мая 2019

В настоящее время у нас есть производственное приложение node.js, которое некоторое время не работает.Теперь приложение представляет собой платформу для проведения торгов в режиме реального времени, а также проводит аукционы по времениФактическая система, управляющая продажами в реальном времени, идеальна и работает как требуется.Мы заметили, что во время наших продаж по времени (когда у предметов в продаже есть таймеры, и они постепенно заканчиваются, и если кто-то делает ставки в течение последнего установленного времени, это будет увеличивать время на X секунд).

Теперь проблема, с которой я столкнулся, заключается в том, что в течение определенного времени окончания продаж (которое может продолжаться часами), если у предметов есть 60 секунд между каждым лотом и имеют расширения, если пользователи делали ставки в последние 10 секунд.Таким образом, мы смогли подключиться через devtools, и я сделал экспорт кучи памяти, чтобы увидеть, что происходит, но все, что я могу видеть, это то, что все индикаторы указывают на поток для записи и буферы.Так что мой вопрос в том, что я делаю не так.Ниже приведен снимок экрана экспорта динамической памяти:

heap-memory-snapshot

Как видно из вышесказанного, для этой цели используется много памяти.он использовал 1473 МБ физической памяти.Мы увидели этот рост очень быстро (в течение 30 минут), и каждый шаг, казалось, был больше, чем предыдущий.Поэтому, когда он достигал 3,5 ГБ, он увеличивался со скоростью около 120 МБ каждую секунду, а затем, когда он увеличивался примерно до 5 ГБ, он увеличивался со скоростью 500 МБ в секунду и достигал около 6 ГБ, а затем рабочий сбой (максимальный размер кучи 8 ГБ),и тогда мы были в процессе.

Итак, позвольте мне рассказать вам о платформе.Как я уже говорил ранее, это платформа для торгов, платформа использует Node (v11.3.0) и кластеризована с использованием встроенной кластерной библиотеки.Это порождает 4 рабочих, и имеет основной процесс (так 5 в целом).Система принимает заявки, проверяет другие заявки, вычисляет, кто выигрывает, и, по существу, отправляет обновления подключенным клиентам через Redis PUB / SUB, после чего транслируется этим рабочим, подключенным пользователям.

Все данные хранятся в Redis и MySQL.используется для обновления данных в redis, так как redis выполнил в 10 раз быстрее, чем мог mysql.

Теперь, когда это работает, для соединения создается небольшой сеанс для соединения, который затем используется для аутентификации пользователя.(которое является сообщением, отправленным клиентом), все события сообщения отправляются обработчику, который передает его правильной команде, после чего все эти команды устанавливаются как асинхронные функции и запускаются как асинхронные.

Теперь это не вызывает проблемнебольшой масштаб, но у нас было более 250 соединений, и мы наблюдали вышеупомянутое поведение и не уверены, где найти исправление.Мы заметили, что при открытии верхнего объекта он был подключен к buffer.js и stream_writable.js.Я также вижу, что все ссылки связаны с system / JSArrayBufferData, и все они ссылаются на них, существует множество объектов, и мы не можем решить эту проблему.

Мы считаем, что одно из следующего:

  1. Мы регистрируем в файл, используя режим добавления, который записывает много информации на консоль и в файл, используя fs.writeFile и режим добавления.Мы провели некоторое исследование и выяснили, что причиной такого поведения может быть запись в консоль.

  2. Это функция получения лотов, которая выводит все лоты для этой страницы (в настоящее время установлена ​​на50) каждый раз, когда элемент заканчивается, поэтому, если таймер заканчивается, он будет запрашивать полную загрузку страницы для всех элементов на этой странице, вместо добавления новых лотов.

  3. Естьчто-то еще происходит здесь, о чем мы не знаем, возможно, используемая нами внешняя библиотека может не удалять ссылку.

Я перечислил интересующие нас библиотеки, которые нам нужны:

  • "bluebird": "^ 3.5.1", (для обещания библиотеки redis)
  • "colors": "^ 1.2.5", (используется в каждом console.log(мы вызываем журналы для всего, что происходит, это может быть около 50 каждые несколько секунд.)
  • "nodejs-websocket": "^ 1.7.1", (Наша библиотека веб-сокетов)
  • "redis": "^ 2.8.0", (наш клиент redis)

В любом случае, если есть что-то кропотливое и очевидное, я бы хотел услышать, поскольку все, что я отслеживал в Интернете и другие вопросы о переполнении стека, недостаточно близко связано с проблемой, с которой мы сталкиваемся.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...