多个 Docker 容器和 Celery

2024-04-26

我们现在的项目结构如下:

  1. 处理来自客户端的传入请求的 Web 服务器。
  2. 向用户提供一些建议的分析模块。

我们决定保持这些模块完全独立,并将它们移动到不同的 docker 容器中。当用户的查询到达网络服务器时,它会向分析模块发送另一个查询以获取推荐。

为了使建议保持一致,我们需要定期进行一些后台计算,例如当新用户在我们的系统中注册时。此外,一些后台任务纯粹与 Web 服务器逻辑相关。为此,我们决定使用分布式任务队列,例如 Celery。

任务创建和执行可能有以下几种场景:

  1. 在网络服务器上排队并在网络服务器上执行的任务(例如,处理上传的图像)
  2. 在网络服务器上排队的任务,在分析模块上执行(例如,计算新用户的推荐)
  3. 任务在分析模块中排队并在那里执行(例如,定期更新)

到目前为止,我看到在这里使用 Celery 的 3 种相当奇怪的可能性:

I. 芹菜放在单独的容器中,可以做所有事情

  1. 将 Celery 移至单独的 docker 容器。
  2. 提供网络服务器和分析中执行任务所需的所有包。
  3. 与其他容器共享任务代码(或在网络服务器和分析中声明虚拟任务)

这样,我们就放松了隔离,因为功能是由 Celery 容器和其他容器共享的。

二.芹菜放在单独的容器中,作用要少得多

Same as I,但任务现在只是对 Web 服务器和分析模块的请求,这些请求在那里异步处理,结果在任务内部轮询直到准备好。

这样,我们就可以从代理中获益,但所有繁重的计算都从 Celery 工作线程中转移。

三.将芹菜分别放入每个容器中

  1. 在 Web 服务器和分析模块中运行 Celery。
  2. 将(分析任务的)虚拟任务声明添加到 Web 服务器。
  3. 添加 2 个任务队列,一个用于 Web 服务器,一个用于分析。

这样,在网络服务器上安排的任务就可以在分析模块中执行。然而,仍然必须在容器之间共享任务代码或使用虚拟任务,此外,还需要在每个容器中运行 celery 工作线程。

做到这一点的最佳方法是什么,或者应该完全改变逻辑,例如,将所有内容移动到一个容器内?


首先,让我们澄清一下 celery 库(你可以用它得到的)之间的区别pip install或者在你的setup.py)和芹菜worker- 这是从代理中取出任务并处理它们的实际过程。当然你可能想要多个workers/processes(例如,用于将不同的任务分离给不同的工作人员)。

假设您有两个任务:calculate_recommendations_task and periodic_update_task并且您想在单独的工作人员上运行它们,即recommendation_worker and periodic_worker。 另一个过程将是celery beat这只是排队periodic_update_task每 x 小时进入经纪商。

另外,假设您有一个简单的 Web 服务器,使用以下方法实现bottle https://bottlepy.org/docs/dev/.

我假设您也想将 celery 代理和后端与 docker 一起使用,我将选择 celery 的推荐用法 -RabbitMQ https://www.rabbitmq.com/作为经纪人和Redis https://redis.io/作为后端。

现在我们有 6 个容器,我将它们写在docker-compose.yml:

version: '2'
services:
  rabbit:
    image: rabbitmq:3-management
    ports:
      - "15672:15672"
      - "5672:5672"
    environment:
      - RABBITMQ_DEFAULT_VHOST=vhost
      - RABBITMQ_DEFAULT_USER=guest
      - RABBITMQ_DEFAULT_PASS=guest
  redis:
    image: library/redis
    command: redis-server /usr/local/etc/redis/redis.conf
    expose:
      - "6379"
    ports:
      - "6379:6379"
  recommendation_worker:
    image: recommendation_image
    command: celery worker -A recommendation.celeryapp:app -l info -Q recommendation_worker -c 1 -n recommendation_worker@%h -Ofair
  periodic_worker:
    image: recommendation_image
    command: celery worker -A recommendation.celeryapp:app -l info -Q periodic_worker -c 1 -n periodic_worker@%h -Ofair
  beat:
    image: recommendation_image
    command: <not sure>
  web:
    image: web_image
    command: python web_server.py

两个 dockerfiles,它构建了recommendation_imageweb_image应该安装芹菜library。只有recommendation_image应该有任务代码,因为工作人员将处理这些任务:

推荐 Dockerfile:

FROM python:2.7-wheezy
RUN pip install celery
COPY tasks_src_code..

WebDocker 文件:

FROM python:2.7-wheezy
RUN pip install celery
RUN pip install bottle 
COPY web_src_code..

其他图像(rabbitmq:3-management & library/redis可以从 docker hub 获得,当你运行时它们会自动拉取docker-compose up).

现在事情是这样的:在你的网络服务器中,你可以通过字符串名称触发 celery 任务,并通过任务 ID 提取结果(无需共享代码)网络服务器.py:

import bottle
from celery import Celery
rabbit_path = 'amqp://guest:guest@rabbit:5672/vhost'
celeryapp = Celery('recommendation', broker=rabbit_path)
celeryapp.config_from_object('config.celeryconfig')

@app.route('/trigger_task', method='POST')
def trigger_task():
    r = celeryapp.send_task('calculate_recommendations_task', args=(1, 2, 3))
    return r.id

@app.route('/trigger_task_res', method='GET')
def trigger_task_res():
    task_id = request.query['task_id']
    result = celery.result.AsyncResult(task_id, app=celeryapp)
    if result.ready():
        return result.get()
    return result.state

最后一个文件配置.celeryconfig.py:

CELERY_ROUTES = {
    'calculate_recommendations_task': {
        'exchange': 'recommendation_worker',
        'exchange_type': 'direct',
        'routing_key': 'recommendation_worker'
    }
}
CELERY_ACCEPT_CONTENT = ['pickle', 'json', 'msgpack', 'yaml']
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多个 Docker 容器和 Celery 的相关文章

随机推荐

  • Android Studio v 1.1 / 1.2 中的渲染问题

    当我添加android support v7 widget Toolbar或其他android support v7 widget 存在渲染问题 But 支持库已是最新 我正确地编译了依赖项 我可以将它们导入MainActivity jav
  • 我可以为第二个侧边栏使用多个

    我可以使用多个吗
  • 安装Python时出错

    击中后 make install 我收到以下错误 usr bin install cannot create regular file usr local bin python2 6 Permission denied make altbi
  • 如何更改每个 Gradle 构建类型的应用程序名称

    我正在尝试找出一种方法来更改 gradle 中每个构建类型的应用程序的应用程序名称 例如 我希望调试版本具有
  • Winforms RichTextBox 中的两列

    在 C 中 我需要能够在单个 RichTextBox 中至少给出 2 列的印象 出于我的目的 它可能看起来像这样 1 1 2 70 8 5 565 1000000 300000 700000 76 10 66 对于左栏中的每个 问题 都会有
  • Aurelia 中的多个触发器

    我想在 aurelia 中触发两种不同的方法 实现此目的的最佳方法是什么 a 我可能会做以下事情 HTML a JavaScript yourFunction event parts this toggleSize size parts t
  • 在触发器上传递 JSON 数据

    我正在调用返回 JSON 数据的服务 Script ajax type POST url some service dataType json success function response if response status ok
  • MongoDB 推文数据库的日期范围查询失败

    我正在尝试对 mongo 数据库中的推文集合执行范围查询 由于某种原因 以下查询将起作用 db posts find created at gte Fri Nov 25 00 00 00 0000 2011 lt Fri Nov 25 23
  • 从节点子进程检索值

    var fp ffprobe fileName show streams grep var width exec fp width function err stdout stderr return stdout alert stdout
  • NgbDropdown autoClose“外部”不起作用

    我正在使用 Angular4 和 ng bootstrap 我想在下拉菜单外部单击时关闭下拉菜单 文档的其余部分 查看文档后我发现autoClose 类型 boolean 外面 里面 但是当我尝试将其设置为参数 config autoClo
  • 是否可以在浏览器中使用 javascript 对用户系统进行基准测试

    随着 Html5 开始普及 我们看到更多关于视频或画布元素等的实验 当使用画布进行实验时 例如用粒子制作烟花 1000 个粒子可能在现代机器上运行良好 但在 3 年机器上可能会运行得很慢 无论如何 是否可以对用户系统进行基准测试以动态更改画
  • 当摘要具有嵌入文本输入并且用户按空格键时,如何防止 html 详细信息元素切换

    我在处于打开状态的详细信息元素的摘要标签内有一个文本输入 目的是捕获用户输入 该输入最终将显示为详细信息元素 见下文 但是 当用户在输入文本时按空格键时 详细信息元素会切换 我想阻止这种情况 我预计这可以在按键事件中使用 stopPropa
  • xgboost中的eval_metric和feval有什么区别?

    有什么区别feval and eval metric在xgb train中 这两个参数仅用于评估目的 Kaggle 的帖子提供了一些见解 https www kaggle com c prudential life insurance as
  • Java、类路径、类加载 => 同一 jar/项目的多个版本

    我知道对于经验丰富的程序员来说这可能是一个愚蠢的问题 但我有一个库 一个 http 客户端 我的项目中使用的一些其他框架 jar 需要它 但它们都需要不同的主要版本 例如 httpclient v1 jar gt Required by c
  • 迭代器后继者

    我想用另一个迭代器 同类 的后继者初始化一个迭代器 任意类型 以下代码适用于随机访问迭代器 但不适用于前向或双向迭代器 Iterator i j 1 一个简单的解决方法是 Iterator i j i 但这不起作用初始化语句for 循环的
  • 如何通过分页从附加页面中提取数据

    我成功返回了第一页数据 并获得了 API 调用中存在的附加数据页数 这是我尝试提取附加数据页的代码 try const response UrlFetchApp fetch root endpoint params const respon
  • 如何从右向左对齐日期选择器?

    datepicker dob on click function datepicker datepicker format dd mm yyyy autoclose true
  • 设计评论表

    基本上我想创建一个评论系统 其中评论可能有也是评论的父母 但我也希望他们可能有可能是其他东西的父母 例如用户或产品 即 我希望能够对产品发表评论 用户 其他评论或几乎任何资源 我该怎么做呢 当前表 标签 产品 用户 评论 编辑 这将适用于流
  • jQuery 获取容器的 html,包括容器本身

    我如何获取 container 上的 html 包括 container 而不仅仅是其中的内容 div div test 1 div div test 2 div div test 3 div div test 4 div div 我有这个
  • 多个 Docker 容器和 Celery

    我们现在的项目结构如下 处理来自客户端的传入请求的 Web 服务器 向用户提供一些建议的分析模块 我们决定保持这些模块完全独立 并将它们移动到不同的 docker 容器中 当用户的查询到达网络服务器时 它会向分析模块发送另一个查询以获取推荐