Celery用户指引--Workers启动、重启

Celery用户指引–Workers启动、重启

1.启动worker

通过下面的命令在前台启动worker

$ celery -A proj worker -l info
 
  • 1

通过下面的命令查看worker命令的所有相关选项

$ celery worker --help
 
  • 1

你也可以在同一台机器上启动多个worker。
如果这样做你需要用包含hostname参数的节点名来使每个worke有r唯一的名字。

$ celery -A proj worker --loglevel=INFO --concurrency=10 -n worker1.%h
$ celery -A proj worker --loglevel=INFO --concurrency=10 -n worker2.%h
$ celery -A proj worker --loglevel=INFO --concurrency=10 -n worker3.%h
 
  • 1
  • 2
  • 3

hostname参数可以扩展成以下变量:
%h:包括域名的主机名
%n:只包含主机名
%d:只包含域名
举例,如果当前的主机名是george.example.com,则分别可以扩展成以下几种形式:

worker1.%h -> worker1.george.example.com
worker1.%n -> worker1.george
worker1.%d -> worker1.example.com
 
  • 1
  • 2
  • 3

注意:
要使用%需要使用2个%,比如%%h.

2.停止worker

终止worker是通过TERM信号实现的。

向worker发送了shutdown命令后,worker在实际终止前会执行完当前所有正在执行的任务。所以如果这些任务很重要,你需要等待worker结束而不要采取其它极端手段(如发送KILL信号)。
如果worker在一段时间后仍然没有停止,比如因为task中有死循环,你可以使用KILL信号强制终止worker.但是注意当前正在执行的任务将会丢失(除非task设置了acks_late选项)。
因为KILL信号不能捕获,所以worker不能捕捉子进程的状态,你需要手工确认。下面是常用的技巧:

$ ps auxww | grep 'celery worker' | awk '{print $2}' | xargs kill -9
 
  • 1

3.重启worker

重启一个worker,你需要发送TERM信号然后启动一个新实例。在开发过程中最简单的管理workers的方法是使用”celery multi”:

$ celery multi start 1 -A proj -l info -c4 --pidfile=/var/run/celery/%n.pid
$ celery multi restart 1 --pidfile=/var/run/celery/%n.pid
 
  • 1
  • 2

在生产环境中,你需要使用初始化脚本或者其它进程管理系统( Running the worker as a daemon)。
除了停止worker再启动它,你还可以使用HUP信号来重启worker。但是注意worker会负责重启自己,所以使用HUP可能会引起问题,不建议在生产环境中使用。

$ kill -HUP $pid
 
  • 1

注意:
通过HUP重启worker仅适用于在后台运行的worker,因为它没有控制终端。
HUP在macOS上是禁用的,因为平台的限制。

4.进程信号

worker主进程会处理以下信号:
TERM 热重启,等待任务运行结束.
QUIT 冷重启,尽快终止进程
USR1 dump所有活动线程的堆栈.
USR2 远程调试, 查看 celery.contrib.rdb.
文件路径中可以使用的变量
–logfile,–pidfile,–statedb中的文件路径参数可以包含一些被worker扩展的变量:
节点名替换:
%p: 节点全名.
%h: 包含域名的主机名.
%n: 只有主机名.
%d: 只有域名.
%i: Prefork 进程池中的进程索引,如果是主进程则为0.
%I: Prefork 进程池中的进程索引,包含分隔符 .
比如当前的主机名是 george@foo.example.com 下面的变量将会被扩展为:
–logfile-%p.log -> george@foo.example.com.log
–logfile=%h.log -> foo.example.com.log
–logfile=%n.log -> george.log
–logfile=%d -> example.com.log
Prefork进程池索引
prefork进程池索引将会根据进程实需要打开的文件扩展成不同的文件名。
这可以用来为每个子进程指定唯一的日志文件。
注意,进程池索引的数字与进程上限有关,不管进程是否退出还是设置了时间段内的每个子进程的最大任务数。所以,这个数字是进程索引而不是进程的数量或者pid。
%i - 进程池索引,主进程是 0 .
Where -n worker1@example.com -c2 -f %n-%i.log将会产生以下3个日志文件:
worker1-0.log (主进程)
worker1-1.log (进程1)
worker1-2.log (进程2)
%I - 包含分隔符的进程索引.
Where -n worker1@example.com -c2 -f %n%I.log 将会产生以下3个日志文件:
worker1.log (主进程)
worker1-1.log (进程1)
worker1-2.log (进程2)

5.并发

默认情况下,使用multiprocessing实现任务的并发执行,但是你也可以使用Eventlet.worker的进程和线程数量可以通过concurrency参数来改变。默认情况下,这个数量和可用的CPU个数相同。

进程的数量 (multiprocessing/prefork pool)
通常情况下进程越多越好, 但是会有一个临界点增加更多的进程会导致相反的效果。有迹象表明运行多个worker实例会比运行单个worker有更好的效果。比如3个worker,每个worker有10个进程. 你需要经验来找到最适合你的worker数量, 这通常与你的应用,任务负载和任务运行时间和其它因素有关。

6.远程控制

2.0中的新特性
通过一个高优先级的广播消息队列,worker可以被远程控制。远程控制命令可以直接作用在所有的worker上或者指定workers列表。
命令也可以有应答,客户端可以等待应答。由于没有一个中心控制的worker,所以没有办法知道集群中有多少个workers,也没有办法估计有多少workers会返回一个应答,所以客户端有一个超时的配置---等待应答的截止期限—这个期限以秒为单位,默认为1秒。如果worker在截止期限内没有收到应答,也不一定说明worker不会应答,更坏的情况是worker挂掉了,但是也有可能仅仅是因为网络延迟或者是worker在很慢的处理命令,所以可以适当的调整这个超时时间。
除了超时时间,客户端还可以指定等待的最大应答个数。如果指定了目标,这个限制会被设置为目的主机的个数。

注意

单一进程也支持控制命令, 但是所有的任务将会阻塞等待控制命令的执行,所以在worker忙碌时需要限制此命令的使用。在这种情况下,你必须增加客户端等待应答的超时时间.

转自:http://blog.csdn.net/happyanger6/article/details/51793490

上一篇:Celery的使用


下一篇:python教程:python基于celery实现异步任务周期任务定时任务