2013-05-06 2 views
1

У меня есть процесс демона python2.7 с помощью модуля из http://www.jejik.com/files/examples/daemon.pyпитон демон убил (ядро?)

Процесс тяжелого один с использованием оперативной памяти около 40 ГБ и 9 дочерних потоков. Сервер использует RHEL 6.3 с 192 ГБ оперативной памяти и достаточную мощность процессора.

После запуска процесс длится около 3-7 часов, но затем он был убит кем-то, может быть ядром. Но я не мог найти никаких советов в dmesg и журнале ядра (который я активировал вручную), там нет. Когда я не начинаю в качестве демона, я просто получил сообщение в терминале: «убил».

следующих меры предосторожности был сделано:

  • сброса счета ООМА в/Proc // oom_score_adj так что ОАЯ убийца не выбирает процесс, когда вид ресурсов
  • растут все rlimits (что может быть увеличена) до максимального
  • установить процесс хороший/приоритет выше (PRIO -15)

Эта проблема уже существует, прежде чем применять эти меры предосторожности, чтобы они не повторно точный удар для убийцы

У меня также есть механизм, позволяющий поймать все исключения, STDERR, STDOUT и записывать все в файл с повернутым логом. Но перед самым процессом не было ничего интересного.

Модули, используемые в процессе среди других: oracle_cx, ibm_db, suds, wsgi_utils. Но все они всегда записывают журналы при возникновении ошибок.

Кто-нибудь знает, как отследить убийство? Кто и почему?

Спасибо заранее

+0

Вы включили coredump, чтобы увидеть, если вы получаете свалку при убийстве? – Mansour

+0

Нет. Проблема в том, что мы используем SSD с объемом около 128 ГБ, и для ядра дампа недостаточно свободного места, когда процесс имел 40 ГБ оперативной памяти. –

+1

Учитывая вашу большую ОЗУ и предполагая, что ваш процесс не мгновенно заполнит все (что заставляет ядро ​​его убить), вы можете сохранить coredump в ОЗУ (через tmpfs). – Mansour

ответ

0

Чтобы узнать, кто был зарегистрирован в то время, когда процесс был убит, используйте команду last.

Если в тот момент никто не был зарегистрирован, процесс был убит некоторым сигналом.

Поскольку это Python, самый простой способ узнать, что убил процесс, - написать обработчик сигналов для всех сигналов и записать их. См. here how to write a signal handler. См. this question how to catch them all.

Если вы получаете дамп ядра, подключите внешний жесткий диск с достаточным пространством. Или ограничьте размер ядра до 1 ГБ, используя ulimit; этого может быть достаточно, чтобы увидеть, где он разбился.

В качестве альтернативы, запустите процесс, используя отладчик, например gdb; он будет убедиться, что вы получите приглашение, когда сигналы «core dump» были отправлены в процесс.

+0

Ни один человек не убил процесс, m уверенно в этом. Нельзя изменить обработчик SIGKILL. –

+0

Если вы видите «убитый» в терминале, это не значит, что он был убит «SIGKILL». Сообщение печатается для любого сигнала, который не обрабатывается. И «довольно уверен» не режет :-) –

+0

Демон уже обрабатывает SIGTERM, SIGABRT, SIGINT и SIGSTOP. Другие сигналы будут давать другое сообщение, а затем «убить». Теперь я пытаюсь получить базовый дамп, используя ramdisk, как это предложил Мансур. –

0

Я думаю, что я нашел основную причину, и это может быть ошибка в Python2.7 После того, как вы поймали все захватывающие сигналы и проигнорировали их, я мог отслеживать еще несколько сообщений об ошибках и получать подсказку 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 

Apperently, это было вызвано, пытаясь написать на перезаписываемый гнездо. Я думаю, что библиотека должна справиться с этим лучше с приемлемым возвращаемым значением, а не просто бросать ошибку/исключение, потому что сокет может быть закрыт в любое время в обычном режиме.

Я проверю, действительно ли это корневая кошка.

Смежные вопросы