将变更推送至生产环境的同时保持服务器正常运行

将变更推送至生产环境的同时保持服务器正常运行

我使用 EC2 作为实时生产服务器,并使用 git 进行源代码控制。目前,当我将更改推送到网站时,我有一个 bash 脚本,它会运行并从 git 中提取最新的更改,然后重新启动服务器。这会导致网站在发生这种情况时停机约十秒钟。

我希望能够推送更改并保持网站正常运行。(我最初的想法是启动一个带有现有代码的额外 EC2 实例,同时将这些更改推送到正在更新的服务器。)有哪些方法可以在推送更改的同时保持网站正常运行?

答案1

我喜欢使用负载平衡器从运行旧代码的服务器转换到运行新代码的服务器。

如果您有足够的实时服务器来处理两倍的当前流量,您可以:

  1. 让一半的服务器停止服务
  2. 升级这些服务器。
  3. 将运行旧代码的服务器切换出服务,并将运行新代码的服务器切换入服务(原子方式)。
  4. 下半场升级。
  5. 使所有服务器投入使用。

如果您没有足够的空闲服务器,您可以按照以下步骤操作:

  1. 使用新代码启动新服务器。
  2. 将新服务器添加到负载均衡器并投入使用,同时让旧服务器停止使用。
  3. 丢弃旧服务器或让其处于待命状态,以便在必要时快速回滚。

这对于无状态实例(如 Web 服务器)最有效。数据库需要采用不同的方法,但通常您的 Web 服务器使用的是单个数据库,不需要经常更改,并且您的数据库更改可以同时适用于新旧代码以进行转换。

我们发现,在使用 Amazon 的 Elastic Load Balancer (ELB) 进行上述类型的实时切换到新服务器时,存在一个问题。当您停止使用旧实例时,ELB 会粗暴地断开所有活动连接。根据您的应用程序,您可能能够忍受这种情况,特别是如果您之前的行为是服务器重新启动后完全中断。

以下是我们在 Amazon 上报告此错误的线程。您可以关注它以获取更新:

当实例脱离 ELB 时,现有连接被粗暴地断开
https://forums.aws.amazon.com/thread.jspa?threadID=61278

如果这对您来说是一个问题,请立即 +1,因为亚马逊已在此要求您提供进一步的反馈。

答案2

您可能想要“优雅重启”而不是正常的“重启”。在 Apache 中,您可能可以执行/etc/init.d/apache2 graceful(Ubuntu) 或/etc/init.d/apache graceful(RHEL/CentOS) 来使新连接使用新更新的应用程序实例。另一个好处是,在重启完成时,现有请求不会被中断。

man apachectl从您的描述来看,这应该可以解决您的问题。有关“优雅”含义的更多详细信息,请参阅“优雅”部分。

相关内容