跳转到内容
本站为社区维护的非官方中文翻译,与 Cloudflare, Inc. 无关联。本站不提供账户登录,请勿在任何非官方站点输入您的 Cloudflare 账户信息。官方文档:developers.cloudflare.com

Durable Objects 代码更新

最后更新 查看 MarkdownAgent 设置

默认情况下,Durable Objects 会将代码更新最多延迟 300 秒(5 分钟),以便正在处理的请求有时间完成。活跃对象可以继续运行当前代码,直至进入休眠或达到此延迟上限。延迟更新只是尽力而为,并不保证所有操作都能完成。

使用 --durable-objects-code-update-mode immediate 部署 Worker,即可立即应用代码更新,而无需等待。有关对象何时进入休眠的信息,请参阅 Durable Object 的生命周期。

代码更新策略

模式 默认 max_delay 行为
deferred 300 秒(5 分钟) 活跃的 Durable Object 可以继续运行当前代码,直至进入休眠。如果达到 max_delay 时它仍处于活跃状态(最长为 86400 秒),对象就会重置并采用新代码。
immediate 不适用 活跃的 Durable Object 会立即重置并采用新代码,无需等待进入休眠。

默认代码更新策略为 deferred,max_delay 为 300 秒。使用此默认设置无需任何配置。

显式设置的 code_update_strategy(无论是在 Wrangler 配置中、作为 CLI 标志传入,还是通过 REST API 发送)始终会覆盖默认值。

工作原理

  1. 你将新版本部署到 100% 的流量。
  2. 客户端向一个当前未运行的 Durable Object 发出请求。这将使用代码的最新版本。
  3. 如果 Durable Object 在 deferred 代码更新策略下处于活跃状态,它可以继续运行现有版本并接受新请求,同时等待进入休眠。如果对象在达到 max_delay 前进入休眠,那么下一个请求会使其在新版本上启动。
  4. 如果达到 max_delay 时对象仍处于活跃状态,它就会重置并采用新代码。
flowchart TD
    A["You deploy a new version"] --> B{"Is the Durable Object<br/>currently running?"}
    B -->|Inactive| C["Starts on the new version<br/>on the next request"]
    B -->|Active| D{"code_update_strategy<br/>mode?"}
    D -->|immediate| E["The object resets and<br/>adopts the new code"]
    D -->|deferred| F["Starts a max_delay timer,<br/>keeps running its current version"]
    F --> G{"Hibernates before<br/>max_delay timer ends?"}
    G -->|Yes| H["Starts on new version<br/>on next request"]
    G -->|"No"| E

对于每个活跃的 Durable Object,连续部署 Worker 时会出现以下行为:

  • 每次部署都会为该对象启动单独的 max_delay 计时器。
  • 第一个计时器到期时,对象会重置并采用最新部署的版本,不一定是启动该计时器的那个版本。

例如,假设某个 Durable Object 处于活跃状态。你使用 max_delay: 30 部署版本 A,为该对象启动 30 秒计时器。十秒后,你使用 max_delay: 60 部署版本 B,为同一对象启动一个独立的 60 秒计时器。版本 A 的计时器会先到期,即第 30 秒时到期。计时器到期后,对象会重置并采用最新部署的版本 B。如果对象在任一计时器到期前进入休眠,则下一个请求会使其在最新部署的版本上启动。

flowchart LR
    A["Deploy version A<br/>max_delay: 30s"] --> B["Timer A:<br/>expires in 30s"]
    C["Deploy version B<br/>10s later<br/>max_delay: 60s"] --> D["Timer B:<br/>expires in 60s"]
    B --> E["Timer A expires first"]
    D -.->|"superseded, never expires"| E
    E --> F["The object resets and<br/>adopts version B,<br/>the latest deployed version"]

这意味着,即使先前 deferred 部署的计时器仍在运行,immediate 部署也始终会立即强制更新,并且可能跳过期间部署的版本。

配置代码更新策略

通过 Wrangler 配置、CLI 标志或 REST API 为部署设置 code_update_strategy。每次部署时,Wrangler 都会提供已配置的策略。该策略不会在不同部署之间沿用:后续部署若省略该设置,就会使用默认策略。

code_update_strategy 适用于此 Worker 导出的每个 Durable Object 类;同一 Worker 中的不同类无法配置不同策略。这也包括通过 ctx.exports 导出且没有显式 bindings 条目的类。

如果 Durable Objects 绑定使用 script_name 引用在另一个 Worker 中定义的类,则该类的代码更新由另一个 Worker 自身的 code_update_strategy 控制,而非包含该绑定的 Worker。

选项

code_update_strategy 结果
(省略) 默认使用 deferred,max_delay 为 300 秒。
{ "mode": "deferred" } 使用默认 max_delay:300 秒(5 分钟)。
{ "mode": "deferred", "max_delay": 0 } 立即应用更新。
{ "mode": "deferred", "max_delay": 120 } 代码更新最多延迟 120 秒,以便对象有时间进入休眠。
{ "mode": "immediate" } 对象会立即采用新代码,无需等待进入休眠。
{ "mode": "immediate", "max_delay": 60 } REST API 会返回错误。Wrangler 会静默丢弃 max_delay;对象随即采用新代码。

Wrangler

在 Wrangler 配置文件的 durable_objects 对象中,与 bindings 并列添加 code_update_strategy:

{
	"durable_objects": {
		"bindings": [
			{
				"name": "CHAT_ROOM",
				"class_name": "ChatRoom",
			},
		],
		"code_update_strategy": {
			"mode": "deferred",
			"max_delay": 60,
		},
	},
}
[[durable_objects.bindings]]
name = "CHAT_ROOM"
class_name = "ChatRoom"

[durable_objects.code_update_strategy]
mode = "deferred"
max_delay = 60

max_delay 以秒为单位,仅在 mode 为 deferred 时适用。可接受的值范围为 0 到 86400(24 小时),精度为毫秒,例如 45.678。省略 max_delay 时,默认值为 300 秒(5 分钟)。

如果你使用 ctx.exports,且不需要显式的 bindings 条目,仍可单独设置 code_update_strategy:

{
	"durable_objects": {
		"code_update_strategy": {
			"mode": "deferred",
			"max_delay": 60,
		},
	},
}
[durable_objects.code_update_strategy]
mode = "deferred"
max_delay = 60

REST

将 code_update_strategy 添加到创建部署请求中。此字段属于部署,而非 Worker 版本:

curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/scripts/$SCRIPT_NAME/deployments" \
  --request POST \
  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "strategy": "percentage",
    "versions": [
      {
        "version_id": "f3b5b2d2-75d6-4c3f-ae3d-4df2f9cfeb7a",
        "percentage": 100
      }
    ],
    "code_update_strategy": {
      "mode": "deferred",
      "max_delay": 60
    }
  }'

code_update_strategy 为只写字段。创建、获取和列出部署时,响应中不会包含此字段。

为单次部署设置策略

向 wrangler deploy、wrangler versions deploy 或 wrangler rollback 传入 --durable-objects-code-update-mode,即可替换单次部署的整个已配置策略。该标志接受 immediate 或 deferred <duration>。使用 deferred 时必须指定时长:

npx wrangler versions deploy <VERSION_ID>@100% --durable-objects-code-update-mode immediate
npx wrangler versions deploy <VERSION_ID>@100% --durable-objects-code-update-mode deferred 30s

Wrangler 按照以下顺序选择完整的代码更新策略:

  1. --durable-objects-code-update-mode 标志,包括 deferred 时指定的时长。
  2. Wrangler 配置中的 durable_objects.code_update_strategy。
  3. 默认值:{ "mode": "deferred", "max_delay": 300 }。

对于 Wrangler 配置中的 deferred 策略,省略 max_delay 时会使用 300 秒。将 max_delay 设为 0 可立即应用更新。标志值不会从配置文件继承 max_delay。

如果等待的代价高于重置,单次部署覆盖就很有用。例如,在以下情况下,可将 code_update_strategy 设为 { "mode": "immediate" }(或传入 --durable-objects-code-update-mode immediate):

  • 你需要立即发布正确性或安全修复,即使这会中断活跃对象。
  • 某些对象很少进入休眠或从不休眠,而你需要强制其采用新代码,或降低其持续时间费用,不再等待。

渐进式部署

在渐进式部署期间,Cloudflare 会将每个 Durable Object 分配到部署中的某个版本。提高某个版本的流量百分比,会将更多对象分配给该版本。只有新分配的对象遵循上述工作原理中描述的机制。例如,将某版本的流量百分比从 20% 提高到 50%,只会让新分配给它的额外 30% 对象开始等待 max_delay。已经运行该版本的对象不会受到影响。

只要仍有任何版本可能在运行,就应确保 Worker 和 Durable Object 代码保持向前和向后兼容,而不仅是在部署期间兼容。请参阅代码更新。

限制

  • deferred 代码更新策略只是尽力而为。Cloudflare 不保证所有操作都会完成,也不保证对象在整个 max_delay 期间都继续运行当前代码。
  • 代码更新策略不会延迟与代码更新无关的重启,例如 Workers 运行时更新。

相关资源

这篇文档对您有帮助吗?