java web项目如何做到升级不停止服务器?
现在容器用的是tomcat,做维护比较多,因为程序老是要升级,更新了class文件,必须要重启环境,这样的话用户体验就非常差,而且耽误时间
实际开发中我用了jrebel插件倒是没什么问题,但是生产环境好像都不推荐这个东西,想问下大型的项目是如何做到的呢
jetty吗
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(23)
影响有多大,你一台Tomcat,估计用户也不会多到哪里去吧,凌晨进行。几秒种而已。
单台服务器的话,shell或bat定时脚本,凌晨执行更新重启就好了。多台的,以上的都是解决方案。
1、session可以挂Redis或者Memcached.应用服前面挂nginx或者haproxy做负载均衡。或者只做反向代理也行,nginx和haproxy基本是秒起的,不过不建议这么做。
2、tomcat是可以开启热加载的,不过一般不建议开启,热加载易导致PermGen space溢出。
3、jdk7以后开始可以做classloader的卸载,jdk8以后从permgen替换到了metaspace,理论上可以避免permgen的溢出问题,有兴趣可以试试自己写一个应用服务器实践一下。
自己实现个ClassLoader
为什么要那么复杂?不管单机还是多机,部署两个tomcat,或者压根不用tomcat启动,直接jar启动,前面加nginx或apache进行七层转化(反向代理),如果一台机器怕起两个内存等资源不够,那就进行主备方式就行,只有一个web服务在工作,另外一个是闲着的,这样上线的时候切换成备,主进行停机服务升级,然后切回主,备进行升级
回复
java不是不能解决,而是需要其它语言或脚本辅助,正如C++、Unity3D中经常用lua分离出业务减少代码的维护量是一个道理,其实java中也能使用lua,只是有点麻烦。 你那边改服务器代码无非就是业务变更或者业务逻辑有漏洞需要修正等一些问题,完全可以把业务分离出来,Drools业务规则引擎就是干这个的
回复
我可以说没有任何一门语言做的项目能尽善尽美,就算php本身能很好的支持热更新,但也会有它的问题和局限性,java的弊端很早就有很多人认识到,但还是这么多人在用,就证明它有它的价值。
回复
都比较笼统,我建议还是在网上多查查资料,你要分离业务就可以看看java的脚本语言或者规则引擎、工作流引擎相关的资料,不过用好这些也不是那么容易,有得有失,还得你个人、团队或公司去衡量有没有必要了。web项目用脚本的不多,用规则引擎的还是不少。
回复
@BoXuan : 那有没有这方法详解的书籍或者资料推荐下 我现在对这些研究非常感兴趣 谢谢啦
回复
@BoXuan : 嗯 非常感谢你的帮助
tomcat、glassfish、jboss等都是支持热部署的,修改一个类是不用自己手动重启web服务器的,只有修改外部jar包中的类则必须重启,不然jar包会冲突,不会替换,当然这种热部署是重新加载web容器,性能不佳。生产环境是不建议开启热部署的。
你可以在网上搜索一下java服务器代码class类热更新,有一大堆资料,当然你也可以用groovy、jruby、scale这些本身运行于jvm而且可热更新的脚本语言,甚至jdk自带一套解析运行js脚本的引擎,还有一种方案就是用业务规则引擎,比如Drools,不过这个也要学习另外一种脚本。
大且稳健和高并发的项目往往不是单一的语言能做好的,需要多方面的结合,java组件框架这么多,就需要优秀的架构师去利用整合了。我们并不一定能生成开发出多么优秀的东西,但应该合理利用其它优秀的东西。
有没有成熟的解决方案或者心得
回复
我听红薯说过,OSC部署的时候,是直接切换Nginx upstream后面的Tomcat实例,也就是部署了新的代码的Tomcat启动,然后关闭旧代码的Tomcat,不过这就要求你不能把session数据存储在Tomcat上.
深入探索 Java 热部署
在 Java 开发领域,热部署一直是一个难以解决的问题,目前的 Java 虚拟机只能实现方法体的修改热部署, 对于整个类的结构修改,仍然需要重启虚拟机,对类重新加载才能完成更新操作。 而PHP在开发时就友好多了,修改代码立即生效。 在生产环境运行时,开启了OPcache,只要设定了opcache.revalidate_freq=60,在60秒后修改的代码同样会自动生效。可以利用opcache实现原子发布,简单来说就是关闭PHP文件时间戳验证,发布代码后清空并重新生成opcache。
热部署/热插拔(HotSwap)是在不重启 Java 虚拟机的前提下,能自动侦测到 class 文件的变化,更新运行时 class 的行为。 Java 类是通过 Java 虚拟机加载的,某个类的 class 文件在被 classloader 加载后,会生成对应的 Class 对象,之后就可以创建该类的实例。 默认的虚拟机行为只会在启动时加载类,如果后期有一个类需要更新的话,单纯替换编译的 class 文件,Java 虚拟机是不会更新正在运行的 class。 如果要实现热部署,最根本的方式是修改虚拟机的源代码,改变 classloader 的加载行为,使虚拟机能监听 class 文件的更新,重新加载 class 文件, 这样的行为破坏性很大,为后续的 JVM 升级埋下了一个大坑。
在进行Java Web程序开发过程中,经常遇到这种问题,修改一个java文件(*.java),需要重启Web服务器(如Tomcat等)部署项目。而重启服务浪费了大量的时间。在小项目中,也许我们感觉不到。但对于大型项目:如数据中心,生产等系统开发而言,往往起/停需要等待几分钟时间。更浪费时间的是,对于一个类中的方法的调试过程,如果修改多次,Tomcat需要反复重载容器,那么浪费的时间更多。
使用过Hibernate, Spring或其他大型组件,写过50个类以上的Web应用程序的开发者应该知道,当系统中有很多类时,如果开启了Tomcat的reloadable=true,那么每当相关文件改变时,Tomcat会停止Web应用并释放内存,然后重新加载Web应用,这实在是个浩大的工程。
那应该怎么玩 来回切换可以实现用户不掉线嘛?或者正在处理中的业务不受影响?
回复
用户信息存cookie,如果非得用服务端,建议用缓存
别这么玩
受限于jvm的内存划分,有个permgen space(java8开始叫meta space),这块存储class的元数据,基本不会被gc掉,只会越来越大,所以建议用反向代理两台tomcat来回切换重启。
那现在2/3的服务器上是新代码,1/3的服务器上是老代码。 访问这两组的用户看到的功能是不是不一样?这个怎么解决呢
不太懂部分服务下架是什么意思?例如我只有一个单一的服务,我现在该怎么办呢?
回复
是会不一样,但是大部分应用应该不在乎这件事吧。
回复
一台服务器很麻烦,你可以开多个tomcat或者开几个虚拟机或容器之类的。不过既然是大型项目,有多台服务器才比较正常吧。
回复
可以使用nginx做一台backup服务器,先更新backup服务器,测试完成以后,更新其他非backup服务器
一般是这样,首先,网站架设成,负载均衡器+应用服务器+Session服务器的模式。Session服务器常见的用redis、memcache都有。
更新的时候,先把一部分(比如1/3)应用服务器下线,更新应用,再重新上线。之后再逐步更新剩下的部分。一次更新1/3的话就分三次上线完成。