Приоритет/Серьезность
Редко, но критично: сайт становится неработоспособным до 30 минут после временных ошибок базы данных. Страницы не загружаются корректно из-за отсутствующих настроек клиента, что вызывает ошибки JavaScript.
Платформа
- Затрагивает: все установки Discourse
- Наблюдается в: производственных средах, испытывающих временные проблемы с подключением к базе данных
Описание
Фактический результат
При возникновении временной ошибки базы данных (тайм-аут подключения, исчерпание пула соединений, сетевой сбой) ошибка кэшируется на 30 минут. В это время:
- Сайт не загружается корректно — страницы выглядят сломанными или неработоспособными
- Возникают ошибки клиентского JavaScript из-за отсутствующих/некорректных настроек
- Каждый запрос логирует сообщение: «Nil client_settings_json from the cache for ‘client_settings_json_[git_version]’»
- Браузеру возвращаются пустые настройки клиента
- Это продолжается даже после полного восстановления базы данных
Ожидаемый результат
При возникновении временной ошибки базы данных система не должна кэшировать ошибку. После восстановления базы данных следующий запрос должен успешно получить и закэшировать настройки клиента, и сайт должен немедленно возобновить нормальную работу.
Шаги для воспроизведения
- Запустите экземпляр Discourse с настроенными настройками клиента.
- Симулируйте проблему с подключением к базе данных (например, исчерпайте пул соединений, добавьте задержку сети или временно заблокируйте порт 5432).
- Выполните запрос, вызывающий SiteSetting.client_settings_json (для этого подойдет загрузка любой страницы).
- Наблюдайте ошибку: «Error while generating client_settings_json_uncached: [database error]».
- Страницы не рендерятся корректно, консоль JavaScript показывает ошибки, связанные с отсутствующими настройками.
- Восстановите подключение к базе данных.
- Выполняйте дополнительные запросы в течение следующих 30 минут. Продолжайте видеть ошибки «Nil client_settings_json from the cache», несмотря на исправную базу данных.
- Через 30 минут кэш истекает, и сайт наконец восстанавливается.
Влияние на пользователя
В этот период сайт фактически неработоспособен:
- Страницы не рендерятся корректно
- JavaScript-приложения не инициализируются из-за отсутствия конфигурации
Это превращает 1-секундный сбой базы данных в 30-минутный простой.
Первопричина
В файле lib/site_setting_extension.rb метод client_settings_json_uncached перехватывает исключения и возвращает nil. Этот nil кэшируется на 30 минут, ломая сайт.
Предлагаемое исправление
Для решения этой проблемы был отправлен pull request. Исправление требует простого изменения: вместо возврата nil нужно снова выбрасывать исключение.
Почему это работает:
- Повторная выброска исключения предотвращает кэширование ошибки через Discourse.cache.fetch.
- Внешний метод client_settings_json уже имеет корректную обработку исключений, которая возвращает «» (пустую строку) без её кэширования.
- Сайт продолжает функционировать во время проблем с базой данных (хотя и с ухудшенной производительностью).
- Сайт автоматически восстанавливается при следующем запросе, как только база данных станет исправной.
- Исправление гарантирует, что временные ошибки базы данных не вызовут 30-минутные простои.
Влияние
Эта ошибка затрагивает все установки Discourse, испытывающие временные проблемы с базой данных:
- Исчерпание пула соединений во время пиков трафика
- Сетевые сбои между приложением и базой данных
- Сценарии переключения базы данных (например, переключение между главным и репликой)
- Конфликт блокировок в таблице site_settings
- Тайм-ауты запросов из-за медленных запросов
Серьезность: Любая из этих распространенных временных проблем приводит к тому, что весь сайт становится неработоспособным на 30 минут, даже если основная проблема разрешается за секунды.
Обходной путь
Если вы столкнулись с этой проблемой прямо сейчас, вы можете вручную очистить кэш для восстановления работы:
В консоли Rails
Discourse.cache.delete(SiteSettingExtension.client_settings_cache_key)