Apache tomcat 相当于 apachectl Graceful

Sco*_*ott 2 tomcat

在基本的 LAMP 堆栈上,至少在我们的 RHEL5/6 服务器上,我们能够跨负载平衡的 Web 服务器将滚动代码更新应用到我们的文档管理系统,而不会通过使用 和 终止用户的连接(以及可能的文档下载apachectl gracefulapachectl graceful-stop。我们正在迁移到基于 Tomcat Web 服务器的应用程序,我们希望新系统具有这种功能,但我找不到 tomcat6 的任何等效功能。tomcat6有这样的功能吗?

Tom*_*Tom 5

简答

如果您有负载平衡的 tomcat 实例,并且负载平衡器支持粘性会话和实时配置,那么您可以通过 1 1 轮换 tomcat 实例来实现您正在谈论的那种滚动和透明升级(在某种程度上)。

长(呃)答案

关于其他答案正确描述 tomcat 作为应用程序服务器与 httpd 以及相关问题,实际上有多种方法可以实现您想要的,即最终用户透明重启。

鉴于 tomcat 通常需要 30 秒或更长时间,具体取决于您的应用程序从冷部署的庞大程度和臃肿程度,因此能够透明地完成此操作通常很有用。

我将解释的这种方法的另一个好处是,在将新应用程序交付给客户之前能够在生产中检查新应用程序,这是令人放心的。

所以... apache 的优雅重启建议其子进程在当前请求完成后退出,并用重新读取新配置文件的新生成的进程/线程替换它们。因此,长时间运行的连接可以完成下载,同时新请求获取新内容。在由 apache 管理的平稳重启过渡期间,实际上有 2 个版本的应用程序正在运行:旧版本和新版本。

不幸的是,对于 tomcat,如果设置了 autodeploy=true,对配置文件或 war 内容的任何更改都会导致上下文的相当不优雅的重新部署,我猜 Catalina Web 容器会等待一些指定的时间,然后再杀死所有未完成的线程和请求。它不是很透明,你最终会遇到可怕的 500 个错误,直到应用程序重新站稳脚跟:-(

因此,为了实现透明的最终用户体验,您需要在短时间内同时运行 2 个版本的应用程序,一个用于旧连接,一个用于新连接。(这些方法有很多注意事项,我将在下面介绍......)

简单的方法是拥有一个前端负载均衡器,例如 apache、haproxy 或带有 2 个或更多 tomcat 实例的 Cisco CSM - 其中负载均衡器支持粘性会话和热负载均衡器配置部署。

例如 tomcat1、tomcat2 和平衡器

  1. 将负载均衡器中服务器场中的 tomcat2 首选项级别更改为零。(haproxy 当然,我认为 mod_proxy 允许您实时更改实例首选项。)
  2. 等待所有连接都命中 tomcat1(使用 jmx 或 netstat 监控网络连接)
  3. 在tomcat2上重新部署Web应用程序
  4. 等待 tomcat2 出现,亲自测试应用程序的完整性!
  5. 将 tomcat2 的首选项交换为 0,将 tomcat1 的首选项交换为高
  6. 等到所有连接都在 tomcat1 上,
  7. 反之亦然。部署其他节点,然后重复等等。

请注意,是更改节点首选项级别而不是删除节点将允许负载均衡器优雅地管理到新 Web 应用程序的连接转换。

显然,如果您只有 1 个服务器,因此只有 1 个 tomcat,您可以想出类似的东西,但这需要为您的 web 应用程序进行一些巧妙的命名。我从来没有必要在 1 个 tomcat 上部署到生产环境中,但我会使用 2 个版本的 Web 应用程序来完成此任务,这些版本具有不同的战争名称和安装在同一个 tomcat6 上的文档路径,如下所示;

/var/lib/tomcat6/webapps/mywebapp_0_1.war => http://localhost:8080/mywebapp_0_1
/var/lib/tomcat6/webapps/mywebapp_0_2.war => http://localhost:8080/mywebapp_0_2
Run Code Online (Sandbox Code Playgroud)

并通过使用 apache mod_proxy 或 haproxy 优雅地迁移两个应用程序之间的连接来使更改透明。

即我将 apache httpd 和 tomcat6 安装在同一个盒子上,httpd mod_proxy 指向如下;

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so

<Location /balancer-manager>
SetHandler balancer-manager
</Location>

<Proxy balancer://cluster>
BalancerMember http://localhost:8080/webapp_0_1
BalancerMember http://localhost:8080/webapp_0_2
</Proxy>

<Location />
ProxyPass balancer://cluster/webapp stickysession=JSESSIONID
</Location>
Run Code Online (Sandbox Code Playgroud)

需要注意的是,如果您必须升级数据库模式,那么除非您想开始进行一些疯狂的命名并将 sh*t 与数据库(例如database_0_1)链接起来,否则您将不得不忍受一些停机时间。

如果您的用户有很长的会话,那么 tomcat6 支持使用各种后端的会话集群