# client\_settings\_json 中缓存的数据库错误 30 分钟 - 网站加载失败

**URL:** <https://meta.discourse.org/t/database-errors-cached-for-30-minutes-in-client-settings-json-site-fails-to-load/387521>\
**Category:** Bug\
**Created:** [2025年十一月4日 01:22 UTC](https://meta.discourse.org/t/database-errors-cached-for-30-minutes-in-client-settings-json-site-fails-to-load/387521 "2025-11-04T01:22:49Z")\
**Posts on this page:** 1\
**Showing post:** 1

<div class="post-metadata">

**Author:** ![Mudit\_Maheshwari](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mudit_maheshwari/32/331278_2.png) [@Mudit\_Maheshwari](https://meta.discourse.org/u/Mudit_Maheshwari)\
**Post date:** [2025年十一月4日 01:22 UTC](https://meta.discourse.org/t/database-errors-cached-for-30-minutes-in-client-settings-json-site-fails-to-load/387521/1 "2025-11-04T01:22:49Z")

</div>

**优先级/严重性** : **罕见但关键**  
在短暂的数据库错误后，网站最多会变得无法使用 30 分钟。由于缺少导致 JavaScript 错误的客户端设置，页面无法正确加载。

**平台** :

- 影响: 所有 Discourse 安装
- 观察到: 经历短暂数据库连接问题的生产环境

## **描述**

**实际结果**  
当发生短暂数据库错误时（连接超时、连接池耗尽、网络故障），错误会被缓存 30 分钟。在此期间：

- **网站无法正确加载** - 页面显示损坏或无法正常工作
- 由于缺少/无效的设置，会发生客户端 JavaScript 错误
- 每次请求都会记录“缓存中缺少 ‘client\_settings\_json\[git\_version\]’ 的 Nil client\_settings\_json”
- 空的客户端设置会返回给浏览器
- **即使在数据库完全恢复后，这种情况仍然会持续**

**预期结果**  
当发生短暂数据库错误时，系统不应缓存该错误。数据库恢复后，下一个请求应成功获取并缓存客户端设置，并且网站应立即恢复正常运行。

## **可复现步骤**

1. 启动一个配置了客户端设置的 Discourse 实例
2. 模拟数据库连接问题（例如，耗尽连接池、引入网络延迟或暂时阻止端口 5432）
3. 发出一个触发 SiteSetting.client\_settings\_json 的请求（任何页面加载都会执行此操作）
4. 观察错误：“生成 client\_settings\_json\_uncached 时出错：[数据库错误]”
5. 页面无法正确渲染，JavaScript 控制台显示与缺少设置相关的错误
6. 恢复数据库连接
7. 在接下来的 30 分钟内发出其他请求。尽管数据库健康，但仍会看到“缓存中缺少 Nil client\_settings\_json”错误
8. 30 分钟后，缓存过期，网站最终恢复

## **用户影响**

在此期间，网站实际上是关闭的：

- 页面无法正确渲染
- JavaScript 应用程序由于缺少配置而无法初始化

这会将“ **1 秒的数据库小故障变成 30 分钟的停机时间** ”。

## **根本原因**

在 lib/site\_setting\_extension.rb 中，[client\_settings\_json\_uncached](https://github.com/discourse/discourse/blob/main/lib/site_setting_extension.rb#L245-L276) 方法会捕获异常并返回 [nil](https://github.com/discourse/discourse/blob/main/lib/site_setting_extension.rb#L275)。此 nil 会被缓存 30 分钟，导致网站中断。

## **建议修复**

已提交一个 [pull request](https://github.com/discourse/discourse/pull/35781) 来修复此问题。该修复需要一个简单的更改，即重新引发异常而不是返回 nil。

它为何有效：

1. 重新引发异常可防止 Discourse.cache.fetch 缓存错误
2. 外部 client\_settings\_json 方法已经具有正确的异常处理程序，该处理程序返回“”（空字符串）而不缓存它
3. 网站在数据库出现问题时仍可运行（尽管性能会下降）
4. 数据库健康后，网站会在下一个请求时自动恢复
5. 此修复可确保短暂的数据库错误不会导致 30 分钟的停机时间。

## **影响**

此错误会影响所有遇到短暂数据库问题的 Discourse 安装：

- 流量高峰期间的连接池耗尽
- 应用程序和数据库之间的网络故障
- 数据库故障转移场景（例如，主/副本切换）
- site\_settings 表上的锁争用
- 由于慢查询导致的查询超时

**严重性** : 上述任何常见、短暂的问题都会导致整个网站在 30 分钟内无法使用，即使根本问题在几秒钟内得到解决。

## **解决方法**

如果您现在遇到此问题，可以手动清除缓存以恢复服务：

在 Rails 控制台中

```plaintext
Discourse.cache.delete(SiteSettingExtension.client_settings_cache_key)

```

---

_[View the full topic](https://meta.discourse.org/t/database-errors-cached-for-30-minutes-in-client-settings-json-site-fails-to-load/387521)._
