gpt4 book ai didi

azure - 工作人员使用 celery、redis 和rabbitMQ 发回结果有 2 分钟延迟

转载 作者:行者123 更新时间:2023-12-03 03:44:24 29 4
gpt4 key购买 nike

我拥有的:

我使用rabbitMQ作为代理运行celery,并使用redis作为结果后端。我有一个发送任务的应用程序和处理任务的工作人员。

我的部署如下:

  • 应用程序、redis、rabbitMQ 和工作人员(我们称他为“local_worker”)使用 docker-compose 在 azure VM 上运行,因此我使用 docker 版本的rabbitMQ 和 redis (6.2.5)。 rabbitMQ 和 redis 端口在虚拟机上打开,并且这些容器配置有用户名和密码。
  • 我使用连接到虚拟机上运行的 redis 和rabbitMQ 的 azure 容器实例添加工作人员。

首先,如果您对此架构有建议,我将很高兴获得建议。

问题:

一切正常,任务被分配给不同的工作人员,这些工作人员会发回结果等...

当任务在 30 分钟后发送且没有任务运行时,当任务未发送到“local_worker”时,我观察到 Redis 延迟为 2 分钟。

  • 我知道这一定来自redis,因为发送任务后我可以立即在工作容器实例中看到任务的日志。
  • 我使用flower和graphana以及celery prometheus导出器来监控这个架构,这样我就可以监控任务的延迟。在开花时,潜在任务保持“正在处理”状态。
  • 任务还剩 120 秒,这是无任务间隔后的第一个任务,且未由“local_worker”处理。
  • 当任务由与 redis 在同一虚拟机上运行的“local_worker”处理时,不会发生这种情况。

这就像redis或VM在发送回结果之前休眠了2分钟。因为它正好是 120 秒(2 分钟),所以我希望它是 redis、celery 或 azure 想要的东西(确定性的东西)

我不使用redis conf文件,仅使用默认设置(密码除外)来运行redis服务器。

感谢您对我的架构和问题的帮助和反馈。

这是我在花中看到的屏幕截图。这三个任务是相同的(删除目录)。 My flower view of tasks that have been sent with a 25 minutes delay (the three tasks are the same).

第一个和第三个任务已由本地工作人员处理。第二个已由外部工作人员处理。在外部工作人员的日志上,我在返回结果之前放置了一条打印行,该行已在 14:14:23 打印。因此,此打印与任务正式结束之间相隔 120 秒。

编辑:

我发现redis_socket_timeout的默认值为120秒。

我删除了行 redis_retry_on_timeout = True 并在我的 celery 配置文件中添加了行 redis_socket_keepalive = True 。现在我得到的错误是任务失败,并出现 redis.exceptions.TimeoutError: Timeout Reading from socket。我不知道为什么结果已准备好,套接字却超时。是不是我的容器实例的网络有问题?

这是我的 docker-compose:

version: "3.5"
services:

rabbitmq:
image: rabbitmq:3.8-management
restart: always
ports:
- 5672:5672
labels:
- traefik.enable=true
- traefik.http.services.rabbitmq-ui.loadbalancer.server.port=15672
- traefik.http.routers.rabbitmq-ui-http.entrypoints=http
- traefik.http.routers.rabbitmq-ui-http.rule=(Host(`rabbitmq.${HOSTNAME?Variable not set}.example.app`))
- traefik.docker.network=traefik-public
- traefik.http.routers.rabbitmq-ui-https.entrypoints=https
- traefik.http.routers.rabbitmq-ui-https.rule=Host(`rabbitmq.${HOSTNAME?Variable not set}.example.app`)
- traefik.http.routers.rabbitmq-ui-https.tls=true
- traefik.http.routers.rabbitmq-ui-https.tls.certresolver=le
- traefik.http.routers.rabbitmq-ui-http.middlewares=https-redirect
env_file:
- .env
environment:
- RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER}
- RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS}

networks:
- traefik-public


redis:
image: redis:6.2.5
restart: always
command: ["redis-server", "--requirepass", "${RABBITMQ_DEFAULT_PASS:-password}"]
ports:
- 6379:6379
networks:
- traefik-public

flower:
image: mher/flower:0.9.5
restart: always
labels:
- traefik.enable=true
- traefik.http.services.flower-ui.loadbalancer.server.port=5555
- traefik.http.routers.flower-ui-http.entrypoints=http
- traefik.http.routers.flower-ui-http.rule=Host(`flower.${HOSTNAME?Variable not set}.example.app`)
- traefik.docker.network=traefik-public
- traefik.http.routers.flower-ui-https.entrypoints=https
- traefik.http.routers.flower-ui-https.rule=Host(`flower.${HOSTNAME?Variable not set}.example.app`)
- traefik.http.routers.flower-ui-https.tls=true
- traefik.http.routers.flower-ui-https.tls.certresolver=le
- traefik.http.routers.flower-ui-http.middlewares=https-redirect

- traefik.http.routers.flower-ui-https.middlewares=traefik-admin-auth

env_file:
- .env
command:
- "--broker=amqp://${RABBITMQ_DEFAULT_USER:-guest}:${RABBITMQ_DEFAULT_PASS:-guest}@rabbitmq:5672//"
depends_on:
- rabbitmq
- redis

networks:
- traefik-public

local_worker:
build:
context: ..
dockerfile: ./setup/devops/docker/app.dockerfile
image: swtools:app
restart: always
volumes:
- ${SWTOOLSWORKINGDIR:-/tmp}:${SWTOOLSWORKINGDIR:-/tmp}
command: ["celery", "--app=app.worker.celery_app:celery_app", "worker", "-n", "local_worker@%h"]
env_file:
- .env
environment:
- RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER}
- RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS}
- RABBITMQ_HOST=rabbitmq
- REDIS_HOST=${HOSTNAME?Variable not set}
depends_on:
- rabbitmq
- redis
networks:
- traefik-public

dashboard_app:
image: swtools:app
restart: always
labels:
- traefik.enable=true
- traefik.http.services.dash-app.loadbalancer.server.port=${DASH_PORT-8080}
- traefik.http.routers.dash-app-http.entrypoints=http
- traefik.http.routers.dash-app-http.rule=Host(`dashboard.${HOSTNAME?Variable not set}.example.app`)
- traefik.docker.network=traefik-public
- traefik.http.routers.dash-app-https.entrypoints=https
- traefik.http.routers.dash-app-https.rule=Host(`dashboard.${HOSTNAME?Variable not set}.example.app`)
- traefik.http.routers.dash-app-https.tls=true
- traefik.http.routers.dash-app-https.tls.certresolver=le
- traefik.http.routers.dash-app-http.middlewares=https-redirect

- traefik.http.middlewares.operator-auth.basicauth.users=${OPERATOR_USERNAME?Variable not set}:${HASHED_OPERATOR_PASSWORD?Variable not set}
- traefik.http.routers.dash-app-https.middlewares=operator-auth

volumes:
- ${SWTOOLSWORKINGDIR:-/tmp}:${SWTOOLSWORKINGDIR:-/tmp}

command: ['waitress-serve', '--port=${DASH_PORT:-8080}', 'app.order_dashboard:app.server']
env_file:
- .env
environment:
- RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER}
- RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS}
- RABBITMQ_HOST=rabbitmq
- REDIS_HOST=${HOSTNAME?Variable not set}
networks:
- traefik-public
depends_on:
- rabbitmq
- redis
networks:
traefik-public:
external: true

和我的 celery 配置文件:

import os
import warnings
from pathlib import Path

# result backend use redis
result_backend_host = os.getenv('REDIS_HOST', 'localhost')
result_backend_pass = os.getenv('REDIS_PASS', 'password')

result_backend = 'redis://:{password}@{host}:6379/0'.format(password=result_backend_pass, host=result_backend_host)


# redis_retry_on_timeout = True
redis_socket_keepalive = True

# broker use rabbitmq
rabbitmq_user = os.getenv('RABBITMQ_DEFAULT_USER', 'guest')
rabbitmq_pass = os.getenv('RABBITMQ_DEFAULT_PASS', 'guest')
rabbitmq_host = os.getenv('RABBITMQ_HOST', 'localhost')




broker_url = 'amqp://{user}:{password}@{host}:5672//'.format(user=rabbitmq_user, password=rabbitmq_pass, host=rabbitmq_host)


include = ['app.worker.tasks', 'app.dashboard.example1', 'app.dashboard.example2']


#task events
worker_send_task_events = True
task_send_sent_event = True

所有环境变量都已定义,并且运行良好,除了我的套接字超时问题!当我在容器实例上部署新工作人员时,我设置了环境变量,以便它连接到在 docker-compose 上运行的rabbitmq 和 redis。

这是我的 celery 文件,它定义了 celery 应用程序:

from celery import Celery
from app.worker import celery_config

celery_app = Celery()
celery_app.config_from_object(celery_config)

最佳答案

我猜你的 Redis 实例和工作线程之间有一些防火墙。您可以登录到 SandboxHost... 并确保可以连接您的 Redis 吗?

您可以使用 telnet 来做到这一点,例如:

telnet <your_redis_hostname> <your_redis_port>

或者使用 redis-cli:

redis-cli -h <your_redis_hostname> -p <your_redis_port>

编辑:

似乎您缺少result_backend :

result_backend = f"redis://username:{result_backend_pass}@{result_backend_host}:6379/0"

并确保您的 REDIS_HOST=${HOSTNAME?Variable not set} 有效...

编辑2:

您能否将 bind 添加到您的 Redis 命令中:

["redis-server", "--bind", "0.0.0.0", "--requirepass", "${RABBITMQ_DEFAULT_PASS:-password}"]

请注意其安全隐患!

关于azure - 工作人员使用 celery、redis 和rabbitMQ 发回结果有 2 分钟延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69778299/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com