WebSocket за nginx обрывается: таймаут или сбой приложения
Если WebSocket за nginx обрывается после простоя, сначала подтвердите, что соединение установилось, затем сопоставьте закрытие с последними данными от приложения. Документированный таймаут nginx по умолчанию — 60 секунд без данных от проксируемого сервера. Это возможная причина, а не диагноз любого обрыва примерно через минуту.
Сначала отделите неудачное открытие от обрыва
Пользователь видит один симптом: интерфейс перестал обновляться. Но соединение могло вообще не перейти в WebSocket, открыться и закрыться позже либо продолжать работать без нужной подписки. Эти ситуации требуют разных действий.
Для описанного nginx сценария HTTP Upgrade официальная документация связывает создание туннеля с запросом смены протокола и ответом 101 от upstream. Заголовки Upgrade и Connection требуют явной передачи. Проверяйте эффективную конфигурацию нужного маршрута, а не соседнего обычного API.
Если перехода не было, увеличение времени ожидания уже открытого канала не решает эту стадию. Сначала разберите ответ приложения, маршрут и разрешение подключения. Если канал открылся и передавал сообщения, сохраните момент начала этой отдельной стадии.
Лента времени вместо фразы «отваливается постоянно»
Предлагаемый журнал сеанса связывает один идентификатор соединения с наблюдениями браузера, прокси и приложения. Время в следующей таблице учебное, в секундах от начала сеанса. Предполагается, что других данных от приложения за указанный период не было.
| Момент | Браузер | Прокси | Приложение | Что можно проверить |
|---|---|---|---|---|
| 0 | Переход подтверждён | Создан канал | Принято соединение | Это уже установленный WebSocket |
| 20 | Получено событие | Прочитаны данные upstream | Отправлено событие | Последняя наблюдаемая серверная активность |
| 45 | Отправлено прикладное сообщение | Есть движение в другую сторону | Нового ответа по условию нет | Активность клиента не равна данным upstream |
| 80 | Наблюдается закрытие | Нужно проверить причину в журнале | Нужно проверить состояние процесса | 80 − 20 = 60 секунд; совпадение ещё не доказательство |
В этом примере канал существовал 80 секунд, а пауза после серверных данных составила 60. Диагностика только от момента открытия дала бы другой ответ. Реальный журнал должен показывать фактические чтения и события, а не воспроизводить эти условные числа.
Согласуйте часы или используйте понятную относительную шкалу. В распределённом приложении события с разных машин могут иметь разные источники времени. Не приписывайте порядок двум почти соседним отметкам, если точности измерения для такого вывода недостаточно.
Что означает proxy_read_timeout
В справке proxy_read_timeout срок относится к промежутку между последовательными операциями чтения ответа upstream. Это не предельная длительность всего ответа. Поэтому регулярно получаемые серверные данные и молчащий канал дают разные условия для проверки.
У соединения могут быть и другие участники: внешний балансировщик, ещё один прокси, приложение. Составьте фактическую цепочку и найдите, где произошло завершение. Таймер nginx не объясняет автоматически перезапуск процесса или решение другого узла прекратить сеанс.
Для поддержки сервера подготовьте одну воспроизводимую хронологию и конфигурацию соответствующего маршрута без секретов. Просьба «поставить максимальный таймаут везде» лишает диагностику проверяемой гипотезы и затрагивает посторонние запросы.
Heartbeat: проверьте назначение и отправителя
В RFC 6455 Ping и Pong — управляющие кадры. Ping может служить проверке отзывчивости другой стороны или поддержанию соединения. Текстовое сообщение с названием ping не становится таким кадром автоматически.
В nginx-документации периодические Ping от проксируемого сервера предложены как способ сбрасывать соответствующий таймаут и проверять соединение. Выбранная библиотека и обе стороны должны поддерживать нужный обмен. Согласуйте его с фактическим прикладным протоколом.
Интервал выбирают относительно подтверждённых ограничений всей цепочки и допустимой задержки обнаружения разрыва. Здесь нет универсального безопасного значения. Слишком частые проверки тоже создают работу: учтите количество одновременно открытых каналов и поведение при недоступном сервере.
Отдельно решите, что считается отсутствием ответа и кто закрывает неисправный сеанс. Постоянная отправка проверочных сообщений без оценки результата может сохранять видимость активности, не подтверждая работоспособность функции. Пользователю нужен статус доступности, соответствующий наблюдениям.
Повторное соединение и повторная операция — разные вещи
После открытия нового канала приложению может потребоваться восстановить подписки и получить текущее состояние. Сам факт соединения не возвращает автоматически пропущенные события. Определите, что сервер хранит и какой способ восстановления действительно поддерживает продукт.
Если пользователь отправлял значимую команду перед разрывом, отсутствие ответа не доказывает отсутствие действия. Мы советуем сначала проверить состояние операции, а не повторять её вслепую. Этот вопрос должен быть решён в договоре приложения независимо от времени ожидания прокси.
Предусмотрите задержки между повторными подключениями и пределы ненужной активности при массовом отказе. Не делайте вид, что клиент полностью восстановился, пока не подтверждены подписки и актуальные данные. Для оператора полезно различать восстановление канала и восстановление функции.
Проверка исправления на своём сеансе
- Подтвердите стадию: отказ открытия, закрытие канала или отсутствие нужных сообщений.
- Запишите последний обмен в обоих направлениях и фактическую причину закрытия, если она доступна.
- Сопоставьте паузу с настройками конкретного участника цепочки.
- Проверьте состояние приложения и события его перезапуска.
- Измените только подтверждённый параметр или согласованный heartbeat.
- В безопасной среде повторите активный и простаивающий сеанс.
- Отдельно проверьте восстановление подписок и неопределённую команду после разрыва.
Пример не требует длительного испытания рабочего сервера. Приёмку можно спланировать на ограниченном тестовом сеансе с вымышленными данными. Наблюдаемый результат должен включать и нормальную работу, и понятное поведение при намеренно завершённом тестовом соединении.
Если канал относится к веб-приложению, закрепите восстановление в его функциональных требованиях. Для доработки существующего интерфейса передайте список состояний и хронологию. Тогда изменение настройки можно оценить по конкретной причине и результату, а не по одному исчезнувшему сообщению.
Вопросы и ответы
Почему WebSocket через nginx закрывается через 60 секунд?
По документации nginx это таймаут по умолчанию без данных от проксируемого сервера. Подтвердите последнюю серверную активность и причину закрытия: такой срок не исключает другие источники обрыва.
Можно ли поддерживать соединение обычным сообщением ping?
Прикладное сообщение и управляющий кадр Ping — разные вещи. Используйте механизм, согласованный с библиотекой и протоколом, и проверяйте нужное направление обмена.
Что восстановить после повторного подключения WebSocket?
Кроме канала, могут потребоваться подписки и актуальное состояние. Значимые команды с неизвестным результатом сначала сверяйте с сервером, а не повторяйте автоматически.
Читайте также
Dovecot: письма удалены, а квота ящика не изменилась
ПоддержкаПосле смены DNS домен даёт SERVFAIL: проверить DNSSEC
ПоддержкаПеренос сайта на другой хостинг: порядок, цена и риски
ПоддержкаPostgreSQL: почему после добавления серверов заканчиваются соединения
КомментарииJava 27: что проверить владельцу серверного приложения
РазработкаПриложение Bubble на своём сервере: что придётся переделать