将Web应用程序的工作进程放在单独的容器中是否合适

31次阅读
没有评论

问题描述

设置基于一个Flask应用程序,其中包含一个PostgreSQL和Redis数据库。此外,还启动了一个工作进程来处理异步任务,如发送电子邮件。用户使用Gunicorn创建多个应用程序进程。从应用程序进程传递作业到工作进程是通过Redis完成的。

问题是,尽管基于相同的代码,工作进程是否应该在单独的容器中启动?目前,用户使用了一个带有相关部分的启动脚本:

gunicorn --bind=0.0.0.0:8000 --workers=3 manage:app &python -u manage.py run_worker

另外,如果它们需要分开,如何确保它们重用共享的文件系统容器?此外,在扩展Gunicorn与主应用程序或工作进程时,应该创建额外的容器实例还是增加容器内的进程数量?

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

在大多数情况下,将Web应用程序的工作进程放在单独的容器中并不是必需的。除非你的设置使用Docker Swarm进行集群部署,否则这样做的开销是不合理的。

如果你的应用程序和工作进程共享相同的代码库,并且它们属于同一个领域,那么将它们放在同一个容器中是更简单和更直观的做法。这样可以避免管理容器之间的连接和增加本地开发环境的复杂性。

方案2

如果你决定将工作进程放在单独的容器中,你可以使用Docker Compose来管理它们之间的关系。以下是一个示例的docker-compose.yml文件:

version: '3'
services:
  app:
    build: .
    # 定义应用程序容器的其他配置
  worker:
    build: .
    # 定义工作进程容器的其他配置
    depends_on:
      - app

在上面的示例中,我们定义了两个服务:appworkerapp服务是应用程序容器,worker服务是工作进程容器。通过使用depends_on属性,我们指定了工作进程容器依赖于应用程序容器。这将确保应用程序容器在工作进程容器之前启动。

请注意,depends_on属性并不能保证应用程序容器的完全可用性。如果应用程序容器需要一些额外的时间来准备并变为可连接状态(如数据库启动时间),则还需要在工作进程容器连接之前等待适当的时间。

方案3

如果你需要在扩展Gunicorn与主应用程序或工作进程时创建额外的容器实例,你可以使用Docker Swarm或Kubernetes等容器编排工具来管理容器的扩展。这些工具可以自动处理容器的创建和销毁,并根据负载情况进行动态调整。

具体来说,如果你使用Docker Swarm,你可以使用以下命令来扩展应用程序容器的实例数量:

docker service scale app=5

这将创建5个应用程序容器实例。类似地,你可以使用相同的命令来扩展工作进程容器的实例数量。

请注意,扩展容器的实例数量可能会增加资源消耗,因此需要根据实际需求和可用资源进行权衡。

总结

在大多数情况下,将Web应用程序的工作进程放在单独的容器中并不是必需的。除非你的设置使用Docker Swarm进行集群部署,否则将应用程序和工作进程放在同一个容器中是更简单和更直观的做法。如果你决定将工作进程放在单独的容器中,你可以使用Docker Compose来管理它们之间的关系。如果需要扩展容器的实例数量,可以使用容器编排工具如Docker Swarm或Kubernetes来自动处理。

正文完