Debug

使用pdb远程Debug

Basics:基础

celery.contrib.rdbopen in new windowpdbopen in new window的扩展版本,对于没有terminal访问权限的人开启了对进程的远程调试。

使用示例:

from celery import task
from celery.contrib import rdb

@task()
def add(x, y):
    result = x + y
    rdb.set_trace()  # <- set break-point
    return result

set_trace()open in new window方法在其所在位置设置了一个断点,并创建了一个socket以便可以通过telnet远程调试你的任务。

调试器可能会在多个进程同时运行,因此调试器会从6900端口开始搜索可用端口而不是使用固定端口。该端口可以通过环境变量CELERY_RDB_PORTopen in new window进行修改。

默认情况下调试器只能被本机访问,要开启外部访问,需要设置CELERY_RDB_HOSTopen in new window变量

当worker遇到断点后会输出下面的信息:

[INFO/MainProcess] Received task:
    tasks.add[d7261c71-4962-47e5-b342-2448bedd20e8]
[WARNING/PoolWorker-1] Remote Debugger:6900:
    Please telnet 127.0.0.1 6900.  Type `exit` in session to continue.
[2011-01-18 14:25:44,119: WARNING/PoolWorker-1] Remote Debugger:6900:
    Waiting for client...

如果您telnet指定的端口,您将看到一个pdb shell

$ telnet localhost 6900
Connected to localhost.
Escape character is '^]'.
> /opt/devel/demoapp/tasks.py(128)add()
-> return result
(Pdb)

输入help获取可用命令列表。如果你从未用过pdb,那你最好先阅读Python Debugger手册open in new window

为了演示,我们将读取result变量的值,修改它,然后继续执行任务:

(Pdb) result
4
(Pdb) result = 'hello from rdb'
(Pdb) continue
Connection closed by foreign host.

我们破坏的结果可以在worker日志中看到:

[2011-01-18 14:35:36,599: INFO/MainProcess] Task
    tasks.add[d7261c71-4962-47e5-b342-2448bedd20e8] succeeded
    in 61.481s: 'hello from rdb'

Tips

启用断点信号

如果设置了**CELERY_RDBSIG**环境变量,worker会在收到 SIGUSR2 信号时生成一个rdb实例。该操作可以用于主线程和worker线程。

比如以下面的命令启动worker:

$ CELERY_RDBSIG=1 celery worker -l INFO

你可以对任何worker进程执行下面的命令来启动一个rdb会话:

$ kill -USR2 <pid>