Пассажир использует больше соединений PostgreSQL, чем ожидалось

Серьезная проблема, возникающая в продакшене в течение долгого времени, мы понятия не имеем, откуда она взялась. Иногда может воспроизводить его на локальном хосте, служба поддержки Heroku Enterprise ничего не знает об этом.

В нашей производственной базе данных в настоящее время есть следующие настройки:

  • Пассажирский автономный, потоки отключены, максимум 25 процессов. Нет минимальной настройки.
  • 3 веб-дино

SELECT * FROM pg_stat_activity GROUP BY client_addr и подсчет количества подключений на каждый экземпляр показывает, что в наши пиковые дни открыто более 1 PSQL-подключения для одного пассажирского процесса.

Предположения:

  • Единый адрес - это один динамометрический стенд (Подтверждено сотрудниками Heroku)
  • Пассажир не запускает более 25 процессов одновременно (подтверждено с помощью passenger-status во время этих пиков)

Вот скриншот того, как выглядит SELECT * FROM pg_stat_activity;:

Пассажир использует больше соединений PostgreSQL, чем ожидалось На скриншоте мы видим, что 45 подключений psql исходит от того же динамометрического стенда, на котором работает пассажир. Если мы следовали нашей предыдущей логике, у него не должно быть более одного соединения на процесс Пассажира, поэтому 25.

Журналы не выглядят необычно, ничего не упоминается ни о сбое динамометрического стенда, ни о сбое процесса.

Вот скриншот нашего статуса пассажира для одного и того же динамометрического стенда (в разное время, просто чтобы доказать, что для одного динамометрического стенда создано не более 25 процессов): Пассажир использует больше соединений PostgreSQL, чем ожидалось

И, наконец, один из ответов, которые мы получили от службы поддержки Heroku (Замечательная поддержка, кстати)

I have also seen previous reports of Passenger utilising more connections than expected, but most were closed due to difficulty reproducing, unfortunately.

В документации Passenger поясняется, что Passenger самостоятельно обрабатывает соединения ActiveRecord.

Любые лиды приветствуются. Спасибо!

Различная информация:

  • Версия Ruby: 2.4.x
  • Версия Rails: 5.1.x
  • Пассажирская версия: 5.3.x
  • Версия PG: 10.x
  • Версия ActiveRecord: 5.1.x

Если вам нужна дополнительная информация, просто дайте мне знать в комментариях, я с радостью обновлю этот пост.

Последняя вещь: Мы используем ActionCable. Я где-то читал, что пассажир странно обрабатывает соединения сокетов (открывает несколько скрытый процесс, чтобы поддерживать соединение). Это один из наших зацепок, но пока не удалось воспроизвести его на localhost. Если кто-нибудь может подтвердить, как Passenger обрабатывает соединения ActionCable, мы будем очень признательны.

Обновление 1 (10.01.2018):

Опробовал:

  • Отключите функцию NewRelic Auto-Explain, как описано здесь: https://devcenter.heroku.com/articles/forked-pg-connections#disables-new-relic-explain
  • Запустите локально пассажирский сервер с минимальным и максимальным размером пула, установленным на 3 (больше заставляет мой компьютер гореть), затем завершите процесс с помощью различных сигналов (SIGKILL, SIGTERM), чтобы попытаться увидеть, закрыты ли соединения должным образом. Они есть.
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
403
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Наконец-то нам удалось решить проблему с Passenger. На самом деле, у нас была эта проблема очень давно.

Исправление

Если вы используете ActionCable и ваш маршрут кабеля по умолчанию - /cable, измените Procfile с:

web: bundle exec passenger start -p $PORT --max-pool-size $PASSENGER_MAX_POOL_SIZE

к

web: bundle exec passenger start -p $PORT --max-pool-size $PASSENGER_MAX_POOL_SIZE --unlimited-concurrency-path /cable

Объяснение

До изменения каждое соединение сокета (ActionCable) выполняло один единственный процесс в Passenger. Но на самом деле сокет - это то, что не должно занимать целый процесс. Процесс может обрабатывать множество открытых сокетов. (Многие - это более 10 тысяч одновременно для некоторых громких имен). К счастью, у нас гораздо меньше сокетов, но все же.

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

Документация

Некоторые показатели после 3 недель исправления

  • Количество разветвленных процессов на Passenger резко уменьшилось (с 75 процессов до ~ 15 процессов)
  • Использование глобальной памяти в веб-динамиках резко уменьшилось (связано с предыдущим пунктом о разветвленных процессах Passenger)
  • Глобальное количество подключений PSQL резко снизился и оставался стабильным в течение двух дней (даже после развертывания). (от 150 до ~ 30 подключений)
  • Количество соединений PSQL на дино резко уменьшилось (с ~ 50 на дино до менее 10 на дино)
  • Количество подключений Redis уменьшился и оставался стабильным в течение двух дней (даже после развертывания)
  • Среднее использование памяти в PostgreSQL резко снизился и оставался стабильным в течение двух дней.
  • Общая пропускная способность немного выше, чем обычно (пропускная способность - это количество запросов, обрабатываемых в минуту).

Другие вопросы по теме