Durable Objects 的内存状态什么时候会丢?

DO 空闲大约 10 秒,满足条件的对象就可以被休眠;代码一部署,对象就会重启,构造函数重新执行,WebSocket 连接也被终止。

答案是:内存状态随时可能消失,所以任何丢了会心疼的东西都要写进存储,内存里只放可由存储重建的缓存。

具体什么时候会丢,官方文档给了一组大致的时间,下面逐条看。对象的整体模型见 Durable Objects 为什么能让一千个请求排队改同一份状态?。

对象什么时候会被休眠或移出内存?

官方文档给出的行为是:

  • 空闲约 10 秒后,满足条件的对象可以被休眠(hibernate)。
  • 没有休眠条件的空闲对象,大约 70 到 140 秒后被移出内存。
  • 挂起的 fetch()、RPC 调用等未完成操作,最多可使对象留在内存约 15 分钟。

官方同时注明,这些具体数值由运行时决定,可能变化,所以别把它们写进你的逻辑里。

什么情况会让对象重启?

代码部署、运行时更新、宿主迁移都会让对象重启,构造函数重新执行,WebSocket 连接被终止。文档没有提供关闭钩子,所以没有“退出前存一下”的机会,推荐增量写入存储。

内存里到底能放什么?

内存变量可以当缓存,但只是缓存:丢了必须能从存储重建。构造函数里的初始化放进 blockConcurrencyWhile,保证重启后先把状态从存储恢复好再处理请求,写法见主文章的最小例子。

还要注意,未捕获异常可能让对象处于未知状态,甚至被重置,关键路径要自己 try...catch。跨 await 的内存状态为什么也不可靠,见 Durable Objects 是单线程的,为什么还会丢更新?。

本文的休眠、移出内存、15 分钟和重启行为全部来自官方文档,我没有在本地或线上验证。官方注明具体数值由运行时决定,可能变化,以官方文档为准。