Java 应用程序的零停机时间部署

我正在尝试构建非常轻量级的解决方案,以实现Java应用程序的零停机时间部署。为了简单起见,让我们假设我们有两台服务器。我的解决方案是使用:

  1. 在“前面” - 一些负载平衡器(软件) - 我在这里考虑HAProxy。

  2. 在“背面” - 两台服务器,两台服务器都运行已部署应用程序的Tomcat。

当我们即将部署新版本时

  1. 我们使用HAProxy禁用其中一个服务器,因此只有一个服务器(我们称之为服务器A,它运行旧版本)可用。

  2. 在其他服务器(我们称之为服务器B)上部署新版本,运行生产单元测试(以防万一我们有它们:-)并使用 HAProxy 启用服务器 B,同时禁用服务器 A。

  3. 现在,我们再次只有一个服务器处于活动状态(服务器 B,新版本)。在服务器 B 上部署新版本,然后重新启用它。

任何建议如何改进?自动化程度如何?

任何现成的解决方案,还是我必须最终使用自己的自定义脚本?

谢谢!


答案 1

我从本文中找到了一些关于零停机时间的有趣解决方案。我想在那篇文章中只强调几个解决方案。

1. A/B交换机:滚动升级+回退机制) )

我们应该有一组处于待机模式的节点。我们将新版本部署到这些节点,并立即将流量切换到它们。如果我们将旧节点保持在原始状态,我们也可以进行即时回滚。负载均衡器位于应用程序前面,并根据请求负责此开关。

缺点:如果您需要X台服务器来运行您的应用程序,那么使用此方法需要2X台服务器

2. 零停机时间

使用这种方法,我们不会保留一组机器;相反,我们延迟端口绑定。共享资源获取将延迟,直到应用程序启动。端口在应用程序启动后切换,旧版本也保持运行(没有接入点)以在需要时立即回滚。

3. 并行部署 – Apache Tomcat:(仅适用于 Web 应用程序)

Apache Tomcat已将并行部署功能添加到其版本7版本中。它们允许应用程序的两个版本同时运行,并将最新版本作为默认值。

4. 延迟端口绑定:

我们在这里提出的是启动服务器的能力,而无需绑定端口,基本上无需启动连接器。稍后,将启动一个单独的命令并绑定连接器。软件版本 2 可以在版本 1 正在运行且已绑定时进行部署。稍后启动版本 2 时,我们可以解绑版本 1 并绑定版本 2。使用此方法,节点仅在几秒钟内有效脱机。

5. 高级端口绑定:

通过打破神话:'',*旧进程和新进程都将绑定到同一端口。ON 模式下SO_REUSEPORT选项允许两个(或多个)进程绑定到同一端口。新进程绑定到端口后,终止旧进程。Address already in use

SO_REUSEPORT选项解决了两个问题:

  1. 应用程序版本切换之间的小故障:节点可以始终为流量提供服务,有效地为我们提供了零停机时间。

  2. 改进的调度:

enter image description here

综上所述:

通过结合后期绑定端口重用,我们可以有效地实现零停机时间。如果我们保留待机进程,我们也将能够进行即时回滚。


答案 2

滚动升级确实是一个很好的解决方案,前提是负载均衡器支持此选项(服务器匮乏)。另一种解决方案是使用支持 OSGi 的应用程序服务器来热替换部分或整个应用程序。

我会推荐第一个。SpringSource的AMS监督控制台可以取下一组tcServer(类固醇上的自定义tomcat),IIRC会自动进行滚动升级(但检查文档)。


推荐