Tornado子进程立即退出时如何获取错误信息?
Tornado子进程异常退出(状态码9)的调试方案
背景:接手一个老旧Tornado项目做更新,调用tornado.process.fork_processes()启动循环后,子进程持续退出重启,日志如下:
child 2 (pid 28921) exited with status 9, restarting
child 1 (pid 28920) exited with status 9, restarting
child 0 (pid 28919) exited with status 9, restarting
以下是几种直接获取错误信息的方法:
临时关闭自动重启:修改
fork_processes的调用参数,加上max_restarts=0,这样子进程退出后不会反复重启,能看到单次退出的完整错误输出:tornado.process.fork_processes(num_processes=3, max_restarts=0)重定向子进程的输出到文件:在子进程执行逻辑的最开头,把标准输出和错误输出定向到日志文件,捕获启动时的报错:
import sys # 给文件名加上PID避免覆盖 log_path = f'/tmp/tornado_child_{tornado.process.task_id()}.log' sys.stdout = open(log_path, 'a') sys.stderr = open(log_path, 'a')给子进程逻辑加全局异常捕获:把子进程的启动代码用try-except包裹,打印完整的异常栈信息:
def child_main(): try: # 原有的子进程启动逻辑,比如创建Application、启动IOLoop app = make_app() app.listen(8888) tornado.ioloop.IOLoop.current().start() except Exception as e: import traceback traceback.print_exc() raise # 保留退出状态,不影响状态码排查 if __name__ == '__main__': tornado.process.fork_processes(3) # 只有子进程会执行下面的逻辑 child_main()排查系统层面的原因:状态码9对应SIGKILL信号,大概率是进程被强制杀死,比如系统OOM(内存不足)触发了内核的OOM Killer。可以运行
dmesg | grep -i kill查看系统日志,或者检查/var/log/messages里的相关记录。直接单进程启动调试:暂时注释掉
fork_processes调用,直接以单进程模式启动服务,看控制台是否会输出明确的报错信息,排除多进程相关的初始化问题。
内容的提问来源于stack exchange,提问作者Adair
相关产品推荐
相关产品推荐

