为了账号安全,请及时绑定邮箱和手机立即绑定

更新 Go Web 应用程序的最佳实践

更新 Go Web 应用程序的最佳实践

Go
SMILET 2021-09-10 16:52:36
我想知道将更新部署到 (MVC) Go web 应用程序的最佳实践是什么。想象一下以下场景:1) 为我的 Go Web 应用程序编写代码并测试一些更改2) 在没有任何人当前使用先前版本被中断的情况下部署更新。我不知道如何确保第 2) 点可以被覆盖 - 当有人向服务器发送请求并且我就在此时重建/重新启动它时,他会收到错误 - 即使请求只使用了一部分我没有接触的代码或向后兼容的代码,或者我刚刚添加了一个新的请求处理程序。也许我错过了一些琐碎或众所周知的模式,因为我只是在学习 go 的过程中,而我以前的 Web 应用程序是 ASP.NET 或 php 应用程序,这没有问题,因为我不需要重新启动代码更改的网络服务器。
查看完整描述

1 回答

?
潇湘沐

TA贡献1816条经验 获得超6个赞

这不仅仅是 Go 的问题,但总的来说,我们可以将问题分为两个独立的问题:

  1. 确保当前请求不会被终止并影响用户体验。

  2. 确保没有无法处理新请求的停机时间。

第一个更容易解决:你只是不要猛烈地杀死你的服务器,而是告诉它退出,导致“排水阶段”,在这个阶段它不接受新请求,只完成当前正在运行的请求,然后退出。例如,这可以通过侦听信号并将应用程序进入特殊状态来完成。

Go 并不简单,因为默认的 http 服务器不支持关闭它,但是您可以使用 启动服务器net.Listener,然后保留对它的引用并在时间到期时关闭它。

现在,只执行一种方法然后再次启动服务将导致在此过程中不接受新请求,我们都知道在极端情况下这可能需要几秒钟。

所以我们需要的是另一个已经运行新代码的服务器实例,在旧代码没有响应新请求的那一刻,对吧?这可以通过多种方式完成:

  1. 拥有多个服务器,并且在它们之上有一个负载平衡器,允许一个(或多个)服务器在我们重新启动另一台服务器时承担负载。这是最简单的方法,也是大多数人的做法。如果您需要 N 个服务器来承担您的用户的负载,只需保留 N+1 并一次重新启动一个。

  2. 使用套接字共享技巧。在较新的 Linux 内核中,许多进程可以在同一个端口上侦听和接受。您所做的只是启动新实例,然后告诉旧实例完成并退出。这样就没有停顿。这是通过设置SO_REUSEPORT侦听套接字来完成的。

  3. 以上可以通过准备交付的解决方案自动化,例如 Einhorn,为您处理所有细节,请参阅https://github.com/stripe/einhorn

  4. 这篇博文中记录了另一种方法:http : //blog.nella.org/?p=879


查看完整回答
反对 回复 2021-09-10
  • 1 回答
  • 0 关注
  • 259 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信