简体中文
事后分析:用户登录时发生了意外的 500 错误
2024年7月18日身份验证服务返回意外500错误的事件报告。
概要
2024年7月18日,Logto Cloud 的身份验证服务发生了 500 内部服务器错误,导致服务中断。
- 受影响的用户:所有尝试进行身份验证的 Cloud 用户
- 受影响的地区:欧洲和美国
- 严重性:严重,扰乱了用户的登录体验
根本原因
在最近的 Cloud 部署期间,数据库架构中的一个重大更改导致登录体验 API 在预发布和生产环境之间的过渡过程中失败。
时间线
- 2024-07-18 08:57 (UTC): 对 Logto Cloud 进行了更新部署
- 2024-07-18 09:28 (UTC): 第一个用户报告了 500 错误
- 2024-07-18 09:31 (UTC): 开发团队确认了问题并开始调查
- 2024-07-18 09:32 (UTC): 问题自动解决
- 2024-07-18 09:40 (UTC): 找到根本原因
事件分析
什么是数据库重大更改,为什么会发生?
我们目前正在开发一个名为“自定义 UI” 的新功能,允许用户使用他们自己的网页来自定义 Logto 的登录体验。此功能需要在 sign-in-exp
表中添加新列以存储自定义 UI 配置。
由于开发过程中的需求变化,该功能的发布被推迟,但架构更改的第一部分已经在几周前部署到生产环境,尽管尚未投入使用。 数据库列的更新是在 此 PR 中引入的。
不幸的是,此更改不具有向后兼容性,导致旧代码的 API 请求在与新数据库通信时失败。
我们如何部署新的 Logto Cloud 版本?
部署新版本的 Logto Cloud 时,我们首先将其部署到预发布环境,然后交换预发布和生产环境。 过程如下:
- 运行数据库更改脚本并更新数据库。
- 将新源码部署到预发布服务器。
- 运行预发布服务器并进行测试。
- 交换预发布和生产服务器,使“预发布”成为“生产”,以便用户可以在没有停机的情况下访问新版本。
然而,两个环境共享同一个数据库,整个过程需要时间。所以在数据库更新和环境交换之间的时间窗口中,在线用户仍然处于生产环境的旧代码,但尝试与新数据库通信。
这是事件的根本原因,也是为什么问题在 35 分钟内自动解决的原因。
为什么在代码审核过程中没有解决这个问题?
我们确实有一个 CI 任务来检查数据库更改的向后兼容性。然而,以前合并 PR 之前不要求通过 CI 检查。这是因为大多数情况下开发阶段通常在几个冲刺内较短,而架构更改的第一和第二部分通常包含在同一发布阶段。 这次,功能发布被推迟,将架构更改分布在两次发布中。开发人员认为 CI 失败是预期的,并通知审核人员这不应阻止 PR 的合并。 确实存在沟通差距,最终 在未提供任何必要的向后兼容性支持的情况下合并了 PR。
经验教训
- 在对数据库架构进行重大更改时,我们应该始终考虑与旧版本源码的向后兼容性。
- 更改数据库列时,我们应该避免直接在架构中更改,而应该使用弃用和迁移方法。
- 开发人员应对发布过程和时间表有更多的意识。
纠正和预防措施
- ✅ 现在要求数据库向后兼容性 CI 检查通过后才能合并包含架构更改的 PR。
- ✅ 强调团队内部向后兼容性的重要性。