我如何设计 API 使得代码更新不会造成中断?
How do I design an API such that code updates don't cause interruptions?
我计划将 API 作为 Web 服务提供。然而,当我更新我的 API 的(解释的)代码库时,我预计可能需要重新启动 API 服务,或者甚至只是有一段时间代码被覆盖。这引入了传入的 API 请求可能被丢弃的可能性,或者更糟糕的是,由 API 触发的进程可能会被中断。
python 的烧瓶库似乎提供了一些解决方案;通过启用调试模式,它将检查所有 python 文件上的修改标志,并且对于每个请求,它将重新加载任何已更改的模块。并不是性能损失让我放弃了这种方法 - 而是它看起来有点被抛弃的想法。
肯定有一个优雅的、高可用性的方法来解决什么一定是常见问题?
编辑:正如@piotrek 在下面回答的那样,"there is no silver bullet"。一条短暂可见的评论建议在更新后使用 DNS 切换到新的 API 服务器。
实际上没有灵丹妙药。你提到了两件不同的事情。一是可用性。这取决于您希望在 9,999... 可用性中有多少个 9。第二件事是 api 改变。所以:
可用性:
有些技术可以让你做热点changes/deloyments。这意味着挂起的请求走旧路径,新请求走新路径。如果您的技术不支持它,您可能出于其他原因无法使用它,还有其他选择
在小型 Intranet 应用程序中,您根本不关心。你停止了世界:停止应用程序,上传新版本并开始。在应用程序停止时,许多 Web 框架停止接受新连接并等待所有未决请求完成。如果您不支持它,您有 2 个选择:
- 忽略它(数据库将回滚当前事务,用户将得到错误)
- 自己实施(可能具有挑战性)。
并且您尽最大努力缩短不活动时间。
- 如果您无力阻止一切,那么您可以:
- 聚类。一项一项地重新启动服务。一直有一些服务器可用。这并不总是可能的,因为有时您必须更改数据库,但并不总是可以在工作系统上进行,或者在更新失败的情况下您不能丢失任何数据
- 微服务。如果您将应用程序拆分为许多与持久队列连接的独立组件,那么您只能关闭系统的某些部分(优雅降级)。例如,您可以禁用将更改写入数据库但仍允许读取的组件。如果您有基础设施可以快速完成更新,那么更新可能不会被注意到 - 请求将被放入队列并由新版本接收
api 变化:
您对 api 进行版本控制。每个请求都说明它需要哪个版本。
- 如果您控制所有客户/小规模/决定不支持旧版本:您不在乎。每个人都必须更新其客户端。
- 如果没有,那么微服务可能会有所帮助。您将 public api 与内部 api 分开。并保留所有 public api 服务 运行 并宣布其中一些已弃用。你监控他们的使用情况。当您确定某个版本的使用率足够低时,您会宣布生命周期结束,然后关闭特定版本
这是我目前最好的
我计划将 API 作为 Web 服务提供。然而,当我更新我的 API 的(解释的)代码库时,我预计可能需要重新启动 API 服务,或者甚至只是有一段时间代码被覆盖。这引入了传入的 API 请求可能被丢弃的可能性,或者更糟糕的是,由 API 触发的进程可能会被中断。
python 的烧瓶库似乎提供了一些解决方案;通过启用调试模式,它将检查所有 python 文件上的修改标志,并且对于每个请求,它将重新加载任何已更改的模块。并不是性能损失让我放弃了这种方法 - 而是它看起来有点被抛弃的想法。
肯定有一个优雅的、高可用性的方法来解决什么一定是常见问题?
编辑:正如@piotrek 在下面回答的那样,"there is no silver bullet"。一条短暂可见的评论建议在更新后使用 DNS 切换到新的 API 服务器。
实际上没有灵丹妙药。你提到了两件不同的事情。一是可用性。这取决于您希望在 9,999... 可用性中有多少个 9。第二件事是 api 改变。所以:
可用性:
有些技术可以让你做热点changes/deloyments。这意味着挂起的请求走旧路径,新请求走新路径。如果您的技术不支持它,您可能出于其他原因无法使用它,还有其他选择
在小型 Intranet 应用程序中,您根本不关心。你停止了世界:停止应用程序,上传新版本并开始。在应用程序停止时,许多 Web 框架停止接受新连接并等待所有未决请求完成。如果您不支持它,您有 2 个选择:
- 忽略它(数据库将回滚当前事务,用户将得到错误)
- 自己实施(可能具有挑战性)。
并且您尽最大努力缩短不活动时间。
- 如果您无力阻止一切,那么您可以:
- 聚类。一项一项地重新启动服务。一直有一些服务器可用。这并不总是可能的,因为有时您必须更改数据库,但并不总是可以在工作系统上进行,或者在更新失败的情况下您不能丢失任何数据
- 微服务。如果您将应用程序拆分为许多与持久队列连接的独立组件,那么您只能关闭系统的某些部分(优雅降级)。例如,您可以禁用将更改写入数据库但仍允许读取的组件。如果您有基础设施可以快速完成更新,那么更新可能不会被注意到 - 请求将被放入队列并由新版本接收
api 变化:
您对 api 进行版本控制。每个请求都说明它需要哪个版本。
- 如果您控制所有客户/小规模/决定不支持旧版本:您不在乎。每个人都必须更新其客户端。
- 如果没有,那么微服务可能会有所帮助。您将 public api 与内部 api 分开。并保留所有 public api 服务 运行 并宣布其中一些已弃用。你监控他们的使用情况。当您确定某个版本的使用率足够低时,您会宣布生命周期结束,然后关闭特定版本
这是我目前最好的