查看源代码 部署
LiveView 的有状态模型引发了一个问题:部署新版本 LiveView 时需要考虑哪些因素?
首先,每当 LiveView 断开连接时,它会自动尝试使用指数退避机制重新连接到服务器。这意味着它会立即尝试,然后等待 2 秒再尝试,然后等待 5 秒再尝试,依此类推。如果正在进行部署,通常意味着下一次重新连接会立即成功,并且您的负载均衡器会自动将流量重定向到新的服务器。
但是,您的 LiveView 可能仍然具有在过渡过程中会丢失的状态。如何处理呢?好消息是,您可以遵循一系列实践,这些实践不仅有助于部署,而且还能改进您的应用程序。
在适当的情况下,将状态保留在查询参数中。例如,如果您的应用程序有选项卡,并且用户点击了一个选项卡,那么您应该使用
<.link patch={...}>
并将选项卡名称作为参数传递,而不是使用phx-click
和Phoenix.LiveView.handle_event/3
来管理它。然后,您将收到新的选项卡名称Phoenix.LiveView.handle_params/3
,它将设置相关的分配,以选择要显示的选项卡。您甚至可以在应用程序路由器中为每个选项卡定义特定的 URL。通过这样做,您可以减少服务器状态的数量,使选项卡导航可以通过链接共享,从而改善搜索引擎索引等等。考虑将其他相关状态存储在数据库中。例如,如果您正在构建一个聊天应用程序,并且您想要存储哪些消息已读,您可以在数据库中存储这些信息。页面加载后,您将检索最后一条已读消息的索引。这使应用程序更加健壮,允许数据在设备之间同步等等。
如果您的应用程序使用表单(这很可能是真的),请记住,Phoenix 会执行自动表单恢复:如果断开连接,Phoenix 会收集表单数据并在重新连接时重新提交。此机制对于大多数表单来说开箱即用,但您可能需要为最复杂的表单自定义或测试它。有关更多信息,请参阅 “表单绑定”文档中的相关部分。
其理念是:如果您遵循上述做法,您应用程序中的大多数状态都已在处理,因此部署不应该带来额外的顾虑。不仅如此,它还将为您的应用程序带来整体优势,例如索引、链接共享、设备共享等等。
如果您确实有无法立即处理的复杂状态,则可能需要采用特殊策略。这可能包括将“旧”状态持久化到 Redis/S3/数据库,并在新的连接上加载新状态。或者,您可能需要在迁移连接时格外小心(例如,如果您正在构建游戏,您可能希望在关闭旧服务器之前等待正在进行的会话完成,同时将新会话路由到新的服务器)。这种情况下将取决于您的需求(而且它们可能无论使用哪种应用程序堆栈都存在)。