Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python守护进程被(内核?)杀死_Python_Linux_Daemon_Rhel - Fatal编程技术网

python守护进程被(内核?)杀死

python守护进程被(内核?)杀死,python,linux,daemon,rhel,Python,Linux,Daemon,Rhel,我有一个python2.7守护进程,它使用来自 这个过程非常繁重,使用了大约40GB的RAM和9个子线程。服务器使用RHEL 6.3,具有192 GB RAM和足够的CPU功率 启动进程后,它会持续大约3-7个小时,但随后被人杀死,可能是内核。但我在dmesg和内核日志(我已经手动激活)中找不到任何提示,那里什么都没有。当不是作为守护进程启动时,我只是在终端中得到消息:“killed” 已采取以下预防措施: 在/proc//oom_score_adj中重置oom分数,以便oom杀手在对资源进行

我有一个python2.7守护进程,它使用来自

这个过程非常繁重,使用了大约40GB的RAM和9个子线程。服务器使用RHEL 6.3,具有192 GB RAM和足够的CPU功率

启动进程后,它会持续大约3-7个小时,但随后被人杀死,可能是内核。但我在dmesg和内核日志(我已经手动激活)中找不到任何提示,那里什么都没有。当不是作为守护进程启动时,我只是在终端中得到消息:“killed”

已采取以下预防措施:

  • 在/proc//oom_score_adj中重置oom分数,以便oom杀手在对资源进行排序时不会选择进程
  • 将所有RLIMIT(可增加的)增加到最大值
  • 将流程的优先级/优先级设置得更高(优先级-15)
这一问题在采取这些预防措施之前就已经存在,因此他们不对杀戮负责

我还有一种机制可以捕获所有异常、STDERR、STDOUT并将所有事情记录到一个旋转的日志文件中。但就在这个过程结束之前,没有什么有趣的事情发生

流程中使用的模块包括:oracle_cx、ibm_db、suds、wsgi_utils。但当发生错误时,它们都会写入日志

有人知道怎么追查凶手吗?谁和为什么


提前感谢

要查看进程终止时谁已登录,请使用命令
last

如果当时没有人登录,则进程将被某个信号终止

由于这是Python,要找出进程的死角,最简单的方法是为所有信号编写一个信号处理程序并记录它们。看见看

如果您得到一个内核转储,请连接一个有足够空间的外部硬盘。或者使用
ulimit
将内核大小限制为1GB;这可能足以看出它在哪里坠毁


或者,使用类似于
gdb
的调试器启动流程;当“核心转储”信号被发送到进程时,它将确保您得到一个提示。

我想我找到了根本原因,它可能是Python2.7中的一个bug 在捕获所有可捕获的信号并忽略它们之后,我可以跟踪更多的错误消息并得到socket.error的提示。问题是,这样的错误将首先触发SIGTERM(trus尝试终止进程),然后写入STDERR。我捕获所有STDOUT和STDERR的机制可能会记录消息,因为主进程已被终止。无论如何,这是守护进程中的一个问题。这些是进程终止前日志中的最后几行

2013-05-07 11:05:53,194 - STDERR - ERROR - Traceback (most recent call last):
2013-05-07 11:05:53,304 - STDERR - ERROR -   File "/var/lib/netcam_epd/lib/python2.7/SocketServer.py", line 582, in process_request_thread
2013-05-07 11:05:53,415 - STDERR - ERROR -     self.finish_request(request, client_address)
2013-05-07 11:05:53,489 - STDERR - ERROR -   File "/var/lib/netcam_epd/lib/python2.7/SocketServer.py", line 323, in finish_request
2013-05-07 11:05:53,587 - STDERR - ERROR -     self.RequestHandlerClass(request, client_address, self)
2013-05-07 11:05:53,684 - STDERR - ERROR -   File "/var/lib/netcam_epd/lib/python2.7/SocketServer.py", line 640, in __init__
2013-05-07 11:05:53,835 - STDERR - ERROR -     self.finish()
2013-05-07 11:05:53,887 - STDERR - ERROR -   File "/var/lib/netcam_epd/lib/python2.7/SocketServer.py", line 693, in finish
2013-05-07 11:05:54,084 - STDERR - ERROR -     self.wfile.flush()
2013-05-07 11:05:54,182 - STDERR - ERROR -   File "/var/lib/netcam_epd/lib/python2.7/socket.py", line 303, in flush
2013-05-07 11:05:54,326 - STDERR - ERROR -     self._sock.sendall(view[write_offset:write_offset+buffer_size])
2013-05-07 11:05:54,387 - STDERR - ERROR - error: [Errno 32] Broken pipe
很明显,这是由于试图写入不可写入的套接字造成的。我认为库应该使用适当的返回值更好地处理这个问题,而不仅仅是抛出错误/异常,因为套接字可以在正常运行时随时关闭


我将验证这是否确实是根原因。

您是否启用了coredump以查看是否在kill上得到转储?不,我没有。问题是,我们使用的SSD大约为128 GB,当进程有40 GB RAM时,没有足够的空间用于核心转储。考虑到您的RAM很大,并且假设您的进程不会立即填满整个内存(这会导致内核杀死它),您可以将核心转储存储在RAM上(通过tmpfs).可能是没有人的复制品扼杀了这个过程,我很确定。无法修改SIGKILL处理程序。如果在终端中看到“killed”,这并不意味着它被
SIGKILL
杀死。将针对任何未处理的信号打印消息。而且“相当确定”不会被切断:-)守护进程已经处理了SIGTERM、SIGABRT、SIGINT和SIGSTOP。其他信号将产生其他消息,然后“终止”。我现在正试图按照Mansour的建议使用ramdisk获取内核转储。我已经看到一个没有处理SIGCHLD的进程被“杀死”。还要寻找那些试图保护系统的过分热心的监视进程。你能说出一些这样的监视进程吗?我确实想过,但我不知道。顺便说一句,如果进程死机,我也会使用monit尝试重新启动进程,但当进程死机时,它会停止监视,但这是另一个问题。