目前,我有一个 tomcat
Web 服务器,它托管多个 .war
微服务(如果重要的话:spring-boot
应用程序)。升级应用程序时,我通过添加 myapp##005.war
、myapp##006.war
来使用 tomcat 并行部署
功能> 等实现零停机部署。
我想对应用程序进行 Docker 化。但是什么最适合 Java 应用程序 Web 服务应用程序呢?
直接将war文件打包到容器中是不是更好,这样每次重新部署都需要一个新的docker容器?或者 tomcat 应该作为没有应用程序的容器运行,并从共享主机系统文件夹挂载 war 文件(从而提供无需重新部署 dockerimage 的重新部署)?
我可以想到以下三种可能性:
- 将每个 war 文件作为
jar
运行,而不是使用嵌入式 tomcat,每个文件都作为自己的 docker 容器?然后每个应用程序都是解耦的,但我不能再使用并行部署功能,因为我必须在另一个应用程序取代它之前杀死该 jar。如果这是最好的方法,那么问题是:如何使用 docker 容器实现零停机部署? - 将每个 war 文件作为独立的 tomcat 运行,每个文件作为自己的 docker 容器?然后,每个应用程序将被解耦,并且还可以利用并行部署。但我必须为每个 docker 容器中的每个应用程序启动一个显式的 tomcat Web 服务器,这可能会对主机系统性能产生负面影响?
- 作为 docker 运行独立的 tomcat,并将所有 *.war 文件放在共享文件夹中进行部署?这里我仍然可以使用并行部署功能。但这不是违背了docker的理念吗? war应用程序不应该打包在容器内吗?性能和资源要求可能在这里最好,因为这只需要一个 tomcat。
哪种方法适合 Java 微服务?
最佳答案
为每个 Docker 容器使用单个 Jar 进行部署绝对是最好的方法。正如您所提到的,低耦合是您希望从微服务中获得的东西。使用 Docker Swarm 和 Kubernetes 等容器编排工具可以轻松完成滚动部署/金丝雀发布等。
如果您想尝试这些概念,Docker Swarm 相当简单:
在您的撰写文件中:
version: '3'
services:
example:
build: .
image: example-image:1.0
ports:
- 8080:8080
networks:
- mynet
deploy:
replicas: 6
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
您编写的文件中的部署部分就是 Docker Swarm 所需要的。
- 副本告诉您应用程序的 6 个实例将部署在集群中
- 并行性会告诉您将同时更新 2 个实例(而不是 6 个)
- 两次更新之间会有 10 秒的宽限期(延迟)
Lot's of other things you can do. Take a look at the documentation.
如果您更新服务,将不会出现停机,因为 Docker Swarm 将通过仍然运行的 4 个容器来服务所有请求。
我不推荐在生产环境中使用 Docker Swarm,但它是体验容器编排概念的好方法。
Kubernetes 的学习曲线相当陡峭。如果您在云中,例如 AWS,EKS、Fargate 等服务可以为您消除很多复杂性。
关于带有嵌入式或独立tomcat的Java docker容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58954900/