我知道检查Docker容器健康状况的其中一种方法是使用以下命令
HEALTHCHECK CMD curl --fail http://localhost:3000/ || exit 1
但是对于工人来说,没有这样的URL可以访问,在这种情况下如何检查容器的健康状况?
celery inspect ping
命令非常方便,它可以完成整个流程:将一个“ping”任务发送到代理程序,工作进程响应并且 celery 获取响应。
假设您的应用程序命名为tasks.add
,则可以向所有工作进程发送 ping 命令:
/app $ celery inspect ping -A tasks.add
-> celery@aa7c21dd0e96: OK
pong
-> celery@57615db15d80: OK
pong
使用 aa7c21dd0e96
作为 Docker 主机名,因此可在 $HOSTNAME
中获得。
要对单个节点进行ping测试,您需要运行:
celery inspect ping -A tasks.add -d celery@$HOSTNAME
这里,d代表目标地(destination)。
要添加到您的Dockerfile中的行:
HEALTHCHECK CMD celery inspect ping -A tasks.add -d celery@$HOSTNAME
示例输出:
/app $ celery inspect ping -A tasks.add -d fake_node
Error: No nodes replied within time constraint.
/app $ echo $?
69
如果节点不存在或未响应,则是不健康的
/app $ celery inspect ping -A tasks.add -d celery@$HOSTNAME
-> celery@d39b3d31cc13: OK
pong
/app $ echo $?
0
当节点回复 pong
时是健康的。
/app $ celery inspect ping -d celery@$HOSTNAME
Traceback (most recent call last):
...
raise socket.error(last_err)
OSError: [Errno 111] Connection refused
/app $ echo $?
1
当代理不可用时是不健康的 - 我删除了应用程序,因此它尝试连接到本地AMPQ并失败了。这可能不适合您的需求,代理出现问题,而不是工作人员。
worker:
build:
context: .
dockerfile: Dockerfile
image: myimage
links:
- rabbitmq
restart: always
command: celery worker --hostname=%h --broker=amqp://rabbitmq:5672
healthcheck:
test: celery -b amqp://rabbitmq:5672 inspect ping -d celery@$$HOSTNAME
interval: 30s
timeout: 10s
retries: 3
$
,这样$HOSTNAME
才能传递到容器中。我也没有使用-A
标志。curl guest:guest@localhost:15672/api/overview
,因为docker无法区分worker是否停止或代理是否停止,而celery inspect ping
则可以。SomeGuyOnAComputer
提供的解决方案,使用kill -0 $PID
来检查PID是否存活。user:pass@rabbitmq:5672
来提供用户名和密码。你甚至可以使用你为应用设置的环境变量,例如:celery inspect ping -b amqp://$${RABBITMQ_USER}:$${RABBITMQ_PASS}@$${RABBITMQ_HOST}:5672 -d celery@$$HOSTNAME
。 - luckydonald错误:没有这个选项:-b
- Martin Thomacelery inspect ping -b amqp://rabbitmq:5672
- Martin ThomaRabbitMQ
,在Alpine版本中可能没有curl
可用,或者RabbitMQ管理插件可能被禁用:最好的解决方案是使用类似于rabbitmq-diagnostics -q status && rabbitmq-diagnostics -q check_local_alarms
的命令。请参阅文档:https://www.rabbitmq.com/rabbitmq-diagnostics.8.html - undefined对于 celery 5.2.3 版本,我使用 celery -A [celery 应用名称] status
进行健康检查。这是我的 docker-compose 文件的样子。
worker:
build: .
healthcheck:
test: celery -A app.celery_app status
interval: 10s
timeout: 10s
retries: 10
volumes:
- ./app:/app
depends_on:
- broker
- redis
- database
0
和1
之外的退出代码对应于未定义的行为,所以这里有一个小改进:celery -A [celery app name] status || exit 1
。来源:https://docs.docker.com/engine/reference/builder/#healthcheck 和 https://www.atatus.com/blog/health-check-command-in-docker/ - undefined# docker-compose.yml
worker:
image: ...
hostname: local-worker
entrypoint: airflow celery worker
...
healthcheck:
test: [ "CMD-SHELL", 'celery --app airflow.executors.celery_executor.app inspect ping -d "celery@$${HOSTNAME}"' ]
interval: 5s
timeout: 10s
retries: 10
restart: always
...
我从Airflow的快速启动Docker Compose中获得了灵感。
为正在运行Celery任务的Docker容器配置健康检查,并确保另一个容器依赖其健康状态:
在您的Docker Compose文件中:
version: "3.8"
services:
celery:
# Celery container config
healthcheck:
test: celery inspect ping
interval: 1m
timeout: 10s
retries: 10
start_period: 1m
dependent_container:
# Dependent container config
depends_on:
celery:
condition: service_healthy
这将使用celery inspect ping
为celery
容器设置健康检查。
dependent_container
依赖于具有condition: service_healthy
的celery
,确保只有在celery
健康时才启动。
就是这么简单:
...
healthcheck:
test: sh -c 'celery -A your_celery_module inspect ping'
...
您的日志文件将具有类似于ping日志的以下内容:
[2023-05-05 11:18:47,309:DEBUG / MainProcess] pidbox收到方法ping()[reply_to:{'exchange':'reply.celery.pidbox','routing_key':'8195241f-122a-3dc4-9841-739f55804b82'} ticket:bada7609-ce6b-499a-b3c2-c80911e0fe09]
此外,您可能希望在已运行的容器中自行检查它。 在这种情况下,它看起来会像这样:
--pidfile /opt/celery/celery_pid
指定pidfile,并使用kill -0 $(cat /opt/celery/celery_pid)
检查进程是否仍在运行。这是从运行masterpoint.io的人那里得到的。 - SomeGuyOnAComputerkill -0
的技巧很不错,谢谢! - pangyuteng