问题 在生产中顺利重新部署WAR?


我想知道是否有一种“平滑的方式”将Java WAR重新部署到生产服务器(没有集群,没有OSGi)?

我能想到的就是停止服务器,更新文件,重启服务器。事先10分钟,我需要在网站上显示维护警告。

你的方法是什么?


4088
2018-05-31 14:59


起源

为什么停止服务器,更新文件,重新启动服务器而不仅仅是取消部署/部署?我们的生产服务器上有几个.war webapps,通常只需要取消部署/重新部署:不需要将整个服务器都放在所有的webapps下面! - NoozNooz42
@nooz:好吧,我只在服务器上运行1个应用程序。我无法找到关于使用Jetty重新部署的任何教程/指南,我发现如何为快速开发做到这一点 - stephanos
哦,我明白了...我不知道Jetty(也许其他人会发表评论)。但是使用Tomcat有几种方法可以取消部署/重新部署单个.war(我曾经从Ant任务中执行此操作,但现在我正在使用管理器应用程序)。这节省了关闭/重启Tomcat所需的时间。 - NoozNooz42


答案:


首先,热部署并不总是有效。我们花了很多时间来确保每个新模块都被加载并确定它不值得麻烦。所以你所做的事情可能听起来不错,但这是部署新WAR的最可靠方式。

我们当前的方法是在所有服务器前使用带负载均衡器的交换机。我们运行至少2个应用程序服务器实例。当我们关闭一台服务器进行维护时,流量会自动转到另一台服务器。

有些开关真的很便宜。如果您没有足够的负载来证明新盒子的合理性,那么您的2个实例可以在同一个盒子上运行。

在某些情况下,交换机实际上可以节省资金。例如,我们有一个SSL页面,过去常常使用6个盒子,现在它可以在交换机中使用SSL加速的2个盒子上正常运行。


8
2018-05-31 15:38



听起来非常聪明 - 但我想知道:你如何处理国家?当你拿下一个时,所有的状态显然必须在另一个资源(DB,缓存,第二个应用程序?)上可用。其次,这有多好? - 基于我简陋的java框架体验(jsf,seam,wicket),我希望你不必在群集中使用“粘性会话”时跳出一些箍。 - stephanos
好问题。无状态服务器在这里需要很长时间,以至于我认为它是理所当然的。如果服务器中有状态,则必须在负载均衡器中执行一些技巧,例如基于源IP或cookie的粘性路由。 - ZZ Coder


你可以看看 JRebel的虽然我不会在生产中使用它。在生产中我们基本上做同样的事情,尽管我们的老板一直梦想着热重新演绎。不幸的是,他们主要是在纸上支持 - 在大多数复杂的应用程序中,热重新部署总会出现问题。对于增量热重新计算来说,这同样更为真实......


1
2018-05-31 15:01





某些应用程序服务器确实支持重新部署,而不会中断服务。对于WebLogic,这至少是正确的,请参阅 使用生产重新部署来更新应用程序。请注意,这是  热部署(我永远不会使用生产服务器的热部署)。

如果没有应用程序服务器支持,我担心您将无法进行真正“顺利”的重新部署。如果要最大限度地减少停机时间,一种方法是并行部署新应用程序(在同一服务器或另一台服务器上),并在完成后更改路由规则。但是客户会放松他们的会话。


1
2018-05-31 15:51





通常可以优化启动时间。我们的Web应用程序在5-7秒内从Jetty开始。其他Java Web服务器更糟糕,因为它们开始非常慢。

另外,正如我所知(不是我做过的),前端Web服务器(例如apache,我们使用lighttpd)可以配置为在Jetty的某段时间(我们的最多30秒)保持请求尚未准备好。因此,我们只需在部署时轻松重启Jetty,并且在最坏的情况下用户只有几秒钟的延迟,这通常看起来像是因特网连接故障。


1
2017-09-03 07:51



超时的好主意!谢谢 - stephanos


通常情况下, mv old.war new.war 让AS从那里拿走它,尽管有非常繁忙的24/7服务,我想这不是一个选择。


0
2018-05-31 15:27



嗯,我曾经和Jetty试过一次,也许我做过了......错了,但几分钟后什么都没发生;可能每个AS处理它的方式不同。你在哪个AS上实际做到了这一点? - stephanos
它是可配置的:你可以让Tomcat和JBoss以这种方式工作。我会惊讶地发现Jetty不允许你以类似的方式设置它。就像术语问题一样,Tomcat和Jetty是servlet容器,JBoss(和Glassfish,JOnAS等)是应用程序服务器。 - Tomislav Nakic-Alfirevic


正如ZZ Coder已经提到的,负载均衡器是一个很好的解决方案,尤其适用于大型部署。对于我自己的项目,我使用nginx web服务器的反向http代理功能。它将所有HTTP数据包从指定的Web上下文(从Internet看到)重定向​​到网络中的服务器。配置非常简单:

location /best-app-ever/ { proxy_pass host-address:8080/some-app-1.1 root /home/www/some-app-1.1 }

切换版本也应该是平滑的。假设您已经部署了新版本的应用程序,只需更改nginx配置文件并应用更改:

location /best-app-ever/ { proxy_pass host-address:8080/some-app-1.2 root /home/www/some-app-1.2 }

sudo nginx -t 
sudo service nginx restart

请注意,如果您的Web应用程序是有状态的和/或包含某些正在运行或已调度的进程,则部署和取消部署可能不会那么顺利。


0
2017-07-30 08:44