【问题标题】:Java docker container with embedded or standalone tomcat?带有嵌入式或独立 tomcat 的 Java docker 容器?
【发布时间】:2020-03-16 04:53:18
【问题描述】:

目前我有一个 tomcat 网络服务器,它托管多个 .war 微服务(如果重要:spring-boot 应用程序)。升级应用程序时,我通过添加 myapp##005.warmyapp##006.war 等来使用 tomcat parallel deployment 功能,以实现零停机部署。

我想 dockerize 应用程序。但是什么最适合 java 应用 webservice 应用呢?

将war文件直接打包到容器中是否更好,这样每次重新部署都需要一个新的docker容器?或者 tomcat 应该作为没有应用程序的容器运行,并从共享的主机系统文件夹中挂载 war 文件(从而提供重新部署而无需重新部署 dockerimage)?

我能想到以下三种可能性:

  • 将每个war文件作为jar运行,而不是使用嵌入式tomcat,每个作为自己的docker容器?然后每个应用程序被解耦,但我不能再使用并行部署功能,因为我必须在另一个可以取代它之前杀死 jar。如果这是最好的方法,那么问题是:如何使用 docker 容器实现零停机部署?
  • 将每个war文件作为独立的tomcat运行,每个作为自己的docker容器?然后每个应用程序将被解耦,并且还可以使用并行部署。但是我必须在这里为每个 docker 容器中的每个应用程序启动一个显式的 tomcat 网络服务器,这可能会对主机系统性能产生负面影响?
  • 作为docker运行一个独立的tomcat,并将所有*.war文件放在一个共享文件夹中进行部署?在这里,我仍然可以使用并行部署功能。但这不是与 docker 的想法背道而驰吗?战争应用程序不应该打包在容器内吗?性能和资源要求在这里可能是最好的,因为这只需要一个 tomcat。

哪种方法适合 java miroservices?

【问题讨论】:

  • 我认为微服务需要“蓝绿色部署”,它允许以零停机时间重新部署容器。共享一个war文件不是一个好主意,因为你需要跟随docker容器,你所需要的必须是内部镜像,除了docker-compose文件。
  • 虽然这是一个真正“主要基于意见”的问题,但它仍然是一个很好的问题。

标签: java spring spring-boot docker tomcat


【解决方案1】:

为每个 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 所需要的。

  • replicas 告诉您,您的应用程序的 6 个实例将部署在 swarm 中
  • parallelism 会告诉您将同时更新 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 等服务可以为您消除很多复杂性。

【讨论】:

  • 感谢您的示例和详细说明!对我来说,拥有 1 个正在运行的容器就足够了,并且只需热切换它们而无需停机。 docker swarm 也可以吗?除此之外,您是否知道运行嵌入式 tomcat 而不是专用的独立设备是否有任何缺点?
  • 您需要暂时扩展到至少两个。在新实例启动时,旧版本仍需要启动以服务请求。我的意思是,如果在某个时间点不存在服务的实例,则服务在物理上不可能为请求提供服务。但是您可以使用一个额外的 docker 命令来执行此操作,因此它不需要是您在 docker-compose 文件中定义的永久内容。
  • 至于你的第二个问题,我猜它不太稳定。如果你只是要部署一个容器,我真的看不出容器化的意义。您没有利用容器和容器编排可以为您提供的优势(负载平衡、可用性、自动重启崩溃的应用程序......)
  • 我的全部目标是解耦应用程序。如果使用单个 jar,我需要 docker 来提供零停机时间部署。无论如何,我对单个实例很好。当然,如果将来需要,专业人士能够进行负载平衡和扩大规模。是否可以告诉 docker-swarm 启动第二个实例进行部署,然后只返回 1,杀死旧版本?
  • "docker service scale exampleservice=2",就可以了。用于更新的“docker service update --image newexampleserviceimage”。默认情况下,docker swarm 将一一更新您的服务实例-我认为-如果不是,您可以在 compose-file 或使用 --update-parallelism 标签创建服务时指定它
猜你喜欢
  • 2014-01-11
  • 2018-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-30
  • 1970-01-01
  • 2015-12-19
相关资源
最近更新 更多