您是否在生产中部署和取消部署基于JVM的应用程序(无论JVM容器/无容器)? 也就是说,当您拥有某个应用程序或服务的新版本时,是否通过“取消部署”和“热部署”该应用程序的新更新版本来更改正在运行的JVM? 或者,您是否尝试在运行时将应用程序的部署从一个JVM“移动”到另一个JVM?
许多流行的JVM的功能使您可以执行此操作。 无论是高级Java EE容器,流行的servlet容器,甚至是OSGI容器,由于各种原因,我们都可以在运行时轻松地取消部署和部署应用程序。 但是,我问,这是一个好习惯吗? 也许只有我一个人,但是我真的认为这是绝对可怕的做法。 但是您的运营/ DevOps团队在做什么?
我想从“不可变基础架构”的角度快速撰写博客,该基础随着Linux容器格式开始的DevOps工具更改而得以保持。
James Strachan最近在他的博客中写了关于Docker对JVM生态系统的影响的文章,他在使用Docker 容器时Java应用服务器的数量下降 。 如果您还没有阅读,我鼓励您。
他谈到的一件事是当动态取消部署和热部署应用程序时,JVM对内存泄漏的敏感性。 一次重新部署后,您可能最终会遇到由于泄漏的对象,类结构,数据库连接,套接字,线程,类加载器等原因而导致不稳定或不可预测的系统。
在某些情况下,泄漏这些物体很 容易 做到
因此,也许通过热部署/重新部署破坏我们的运行时部署是一件坏事。
那么我们有什么选择呢? 如何使用新配置和部署的应用程序来启动有问题的JVM的新实例,控制我们有关启动顺序和部署配置的一切。 然后,我们可以将流量从较旧的实例定向到较新的实例,并在适当的时间终止较旧的实例。
这够了吗?
好吧,这个问题直接针对新应用程序和服务的新排列(新版本,新配置以及未更改的事物,例如,代码部署的服务等)是否经过了正确的测试。 。 我个人将要部署到生产环境中的应用程序和服务的任何组合所做出的假设是,已经对相同的排列进行了完全测试, 就像在较低环境中一样。 也就是说,确切的集合已经部署在DEV,QA,IST,UAT,产品镜像,产品等中。更改生产中服务的唯一方法是在较低的环境中正确测试它们。
这种思路是基于强大的自动化,一致的测试,以及一套将变更从最初的系统移植到生产系统的既定学科和流程。 Linxu容器和图像格式为实现此目的而对工具进行了巨大改进,但即使在今天(即,甚至在您能够使用Docker / Rocket /图像格式之前),也都可以灌输思维定势和这些最佳实践。 :
- 不要在运行时热部署/重新部署/迁移生产中的Java服务
- 确实非常关注您的交付管道/自动化/测试,以快速更改系统
翻译自: https://www.javacodegeeks.com/2015/05/immutable-infrastructure-hotdeploys-and-the-jvm.html