celery在执行schedule类型任务时,有个中断回传机制:celery worker接到任务后,如果worker被中断了(ctrl+c),那么这个这个任务会重新回到队列中,但你强制中断worker(kill -9),则不会再回到队列中。(具体可以参考Celery + Redis交互过程探究)
当用docker启动celery时,也会遇到同样的问题:强制退出容器时(docker kill),会导致任务丢失,即使用(docker stop),也会导致任务丢失。
这时候你可以研究一下docker的stop_signal参数.
默认的stop-signal是SIGTERM,在docker stop的时候会给容器内PID为1的进程发送这个signal,通过--stop-signal可以设置自己需要的signal,主要的目的是为了让容器内的应用程序在接收到signal之后可以先做一些事情,实现容器的平滑退出,如果不做任何处理,容器将在一段时间之后强制退出,会造成业务的强制中断,这个时间默认是10s.
以docker-compose为例设置平滑退出容器:
services:
redis:
image: redis:6.0.8
container_name: redis
networks:
networks:
restart: always
celery:
image: django_image
command: celery worker -A xxx.main -l info
container_name: celery
networks:
- networks
depends_on:
- django
stop_signal: TERM # 容器终止信号,TERM信号平滑退出
restart: on-failure