11

在我的 Web 应用程序中,当用户登录到应用程序时,他们的浏览器会向服务器打开一个 Websocket,以便可以将更新推送到浏览器。

它是在 Azure 应用服务中运行的 ASP.NET Core Web 应用(自托管)。我想使用 Azure 的部署槽交换功能将代码更新推送到生产环境,实现零停机部署。

在我所做的有限测试中,看起来在插槽交换之后,Websocket 连接对浏览器连接到的原始插槽保持打开状态。(因此,如果浏览器的 Websocket 连接到插槽 A,并且我们交换了插槽 A 和 B,以便新连接进入插槽 B,那么 Websocket 仍然对运行在插槽 A 上的应用程序开放。)

在某些时候,旧插槽将脱机,这将强制关闭任何打开的 Websocket。我希望在插槽交换后尽快将 Websocket 重新打开到新插槽,这样如果我更新与 Websocket 相关的代码,所有客户端都将尽快运行新代码。

这可能如何工作的草图:

  1. 插槽交换发生
  2. 向旧插槽上运行的代码发送通知
  3. 在旧插槽上运行的代码推送 Websocket 消息以重新连接
  4. 收到消息后,浏览器会打开一个新的 Websocket 连接(将转到新插槽)
  5. 连接成功后,浏览器关闭旧的 Websocket

有更好的方法吗?

在旧插槽上运行的代码如何知道它何时被交换?

优雅地处理这个甚至可能吗?或者总是会有一堆竞争条件?

4

1 回答 1

6

WebSocket 确实保持连接,因为 ARR 只能将新请求定向到“新”应用程序。例如,如果您在交换过程中下载一个大文件,您会看到相同的行为。

我处理这个问题的方法是让我的部署系统(Octopus)进行交换,然后向“旧”应用程序发出请求,通知所有连接的 WebSocket 客户端他们需要断开连接并重新连接。客户端将立即断开连接,选择一个随机延迟(以防止一次重新连接数千次),然后在该延迟后重新连接。

于 2018-03-21T19:25:43.957 回答