我正在尝试在 docker 容器中运行 celery,但由于某种原因它从不更新。每当我在 tasks.py 中添加新函数或更新现有函数时,即使在我重新启动容器后,它也永远不会向 celery 注册。
这是我的dockerfile:
# start with a base image
FROM python:3.4-slim
ENV REDIS_IP 1.1.1.111
ENV REDIS_PORT 6379
ENV REDIS_DB 0
# install dependencies
RUN apt-get update && apt-get install -y \
apt-utils \
nginx \
supervisor \
python3-pip \
&& rm -rf /var/lib/apt/lists/*
RUN echo "America/New_York" > /etc/timezone; dpkg-reconfigure -f noninteractive tzdata
# update working directories
ADD ./app /app
ADD ./config /config
ADD requirements.txt /
# install dependencies
RUN pip install --upgrade pip
RUN pip3 install -r requirements.txt
# setup config
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
RUN rm /etc/nginx/sites-enabled/default
RUN ln -s /config/nginx.conf /etc/nginx/sites-enabled/
RUN ln -s /config/supervisor.conf /etc/supervisor/conf.d/
EXPOSE 80
CMD ["supervisord", "-n"]
然后是我的supervisor.conf:
[program:app]
command = uwsgi --ini /config/app.ini
autostart=true
autorestart=true
[program:nginx]
command = service nginx restart
autostart=true
autorestart=true
[program:celery]
directory = /app
command = celery -A tasks.celery worker -P eventlet -c 1000
autostart=true
autorestart=true
我的tasks.py:
import os
from celery import Celery
from app import app as flask_app
def make_celery(app):
celery = Celery(app.import_name, backend='redis://{0}:{1}/{2}'.format(os.environ['REDIS_IP'],os.environ['REDIS_PORT'],os.environ['REDIS_DB']),
broker='redis://{0}:{1}/{2}'.format(os.environ['REDIS_IP'],os.environ['REDIS_PORT'],os.environ['REDIS_DB']))
celery.conf.update(
CELERY_ENABLE_UTC=True,
CELERY_TIMEZONE='America/New_York'
)
TaskBase = celery.Task
class ContextTask(TaskBase):
abstract = True
def __call__(self, *args, **kwargs):
with app.app_context():
return TaskBase.__call__(self, *args, **kwargs)
celery.Task = ContextTask
return celery
celery = make_celery(flask_app)
@celery.task()
def add_together(a, b):
return a+ b
@celery.task()
def multiply(a,b)
return a*b
出于某种原因:
- 我有 21 名 worker 注册了,但
multiply从未注册过, - 同样,当我对
add_together进行更改时,它也永远不会注册,即使我重新启动容器也是如此。
我开始我的容器:
docker build --rm -t myapp .
docker run -d -p 88:80 -v $(pwd)/app:/app --name=myapp myapp
并重新启动:
docker restart myapp
我也试过
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
然后重新构建应用程序。没有任何帮助。任何想法将不胜感激。
请您参考如下方法:
我认为这可能是问题所在:
@celery.task() # <-- you shouldn't call this decorator directly
def add_together(a, b):
return a+ b
尝试将其更改为:
@celery.task
def add_together(a, b):
return a+ b
原因:只需检查 source code of decorator task :
def task(self, *args, **opts):
"""Creates new task class from any callable."""
# ... handling named options
if len(args) == 1:
if callable(args[0]):
return inner_create_task_cls(**opts)(*args)
raise TypeError('argument 1 to @task() must be a callable')
if args:
raise TypeError(
'@task() takes exactly 1 argument ({0} given)'.format(
sum([len(args), len(opts)])))
return inner_create_task_cls(**opts)
它接受的唯一未命名参数是要修饰的函数。否则它会引发 TypeError 并被 supervisord 吞没,因为你没有配置 the loglevel to debug .
