Как найти источник нерестового процесса?

12

У меня есть процесс Java, работающий на экземпляре RedHat Linux.

Проблема в том, что он продолжает появляться после того, как я его убил. Я не уверен, где искать. Я уже ходил в crontab, но не повезло.

Я посмотрел на PPID, но он указывает на init (1).

Любая идея, как я могу узнать источник?

Хосе
источник
1
Можете ли вы дать нам что-нибудь, чтобы продолжить? Процесс пишет в какие-нибудь файлы, например? Можете ли вы показать нам вывод ps xfпоказа дерева процессов? В нынешнем виде у нас очень мало дела.
Terdon
Вы сказали, что ходили в crontab ... Вы также проверили, есть atли один из них?
YoMismo
Можете ли вы сказать нам, какое программное обеспечение Java вы на самом деле используете. Я видел такие инструменты, как Cassandra, которые на самом деле имеют встроенный сторожевой таймер в некоторых настройках, который просто запускает другой экземпляр базы данных, когда первый экземпляр вышел из строя (не был корректно остановлен).
Матиас Стейнбауэр,

Ответы:

15

Есть ряд возможностей (некоторые упоминаются в других ответах):

  1. Системный или пользовательский cronjob, выполняющийся часто,
  2. В init SysV, /etc/inittabзапись для службы с respawnдирективой,
  3. В Systemd, блок файл с Restartнабором опций на значение , отличное no,
  4. В Upstart, файл конфигурации службы с respawnдирективой,
  5. Инструмент мониторинга процесса, такой как monit, или
  6. Специальный контрольный процесс для этой конкретной службы.

Sysdig - интересный новый инструмент (только для Linux), который может дать более полное представление о том, где запускается процесс .

Sysdig использует функции трассировки ядра Linux, чтобы обеспечить быстродействие всей системы strace.

Например, если я хочу увидеть запуск каждого процесса ls, я могу выдать:

sudo sysdig evt.type=execve and evt.arg.exe=ls

Когда lsгде-то запускается, я получу сообщение, подобное этому:

245490 16:53:54.090856066 3 ls (10053) < execve res=0 exe=ls args=--color=auto. tid=10053(ls) pid=10053(ls) ptid=9204(bash) cwd=/home/steved fdlimit=1024 pgft_maj=0 pgft_min=37 vm_size=412 vm_rss=4 vm_swap=0 env=...

Я обрезал возвращаемую информацию об окружении, но, как вы можете видеть, в ptid я вижу имя и pid программы, вызывающей execve. execveсистемный вызов, используемый в Linux для выполнения новых команд (все остальные вызовы exec являются только внешними интерфейсами для выполнения).

Стивен Д
источник
2
sysdig - отличный совет! Кстати, теперь он доступен для Windows (и Mac, я думаю) с ограниченной функциональностью.
Neowizard
Как Монит помогает здесь? Я начал читать руководство, но оно похоже на альтернативу или резервную копию чего-то вроде Nagios. Я не вижу, как это поможет вам отследить процесс возрождения.
Джефферсон Хадсон
7

Я считаю, что вы могли бы использовать pstree. Вы можете указать команду как,

pstree -p PID

Выше приведен список всех родителей Java-приложений.

Рамеш
источник
1
Это совсем не поможет, так как ОП уже сказал, что он посмотрел на PPID, который равен 1.
Гунтрам Блом поддерживает Монику
@GuntramBlohm, пожалуйста, посмотрите на оригинальный вопрос, прежде чем он будет отредактирован. Это не было упомянуто в первой версии вопроса.
Рамеш
2
вздох. Другой постер, который делает свой вопрос движущейся мишенью, не помечая свои правки :(
Гунтрам Блом поддерживает Монику
5

Вы можете взглянуть на его PPID (идентификатор родительского процесса):

$ ps -eo pid,ppid,args | grep java

Как только вы получите PPID (второй столбец) вашего Java-процесса, используйте psснова, чтобы найти связанный процесс:

$ ps -p [PPID]

Редактировать : если родитель - 1 (init), то первый родитель вашего Java-процесса умер сразу после «рождения» (как печально). Из-за этого вы не можете использовать текущую иерархию процессов, чтобы найти ее. Первое, что я бы порекомендовал вам сделать, это проверить ps -ef. Вы можете найти виновника, просто прочитав вывод.

Затем взгляните на crontabs (вы уже сделали это, но это не повредит):

$ for user in $(cut -f1 -d: /etc/passwd); do echo $user; crontab -u $user -l; done

Это потребует привилегий суперпользователя.

Все еще не видите запланированный процесс Java? Черт возьми. Давайте попробуем что-нибудь еще. Если ваш Java-процесс присутствует с момента загрузки, посмотрите на программы, запланированные во время загрузки. Я бы предложил что-то вроде ...

$ grep -iR java /etc/rc*

Если вы все еще не можете найти что-то, то ... Я признаю, что у меня заканчиваются идеи. Вам действительно нужно по-другому взглянуть ps -efи найти процессы, связанные с Java-программами. Вы должны столкнуться с демоном или «пусковой установкой», ответственной за постоянное возрождение вашего Java-процесса.

Джон У. Смит
источник
Я попытался найти родительский процесс, но он просто указывает на init (PPID = 1). Я изменю вопрос с помощью этой информации.
Хосе
@JoseChavez, если ваш PPID равен 1, то создаваемые java-процессы являются зомби-процессами. Проверьте этот ответ здесь .
Рамеш
@JoseChavez Я отредактировал свой ответ еще несколькими треками, чтобы расследовать ваше дело.
Джон У. С. Смит,
2
@Ramesh Если PPID равен 1, они могут быть или не быть зомби . Если они на самом деле не были initсозданы, они, по крайней мере, сироты . Спецификатор stateto psпокажет, являются ли они зомби (например, ps -eo pid,ppid,state,comm); состояние будет Z.
Златовласка
1
@goldilocks: если PPID равен 1, они не являются зомби , если процесс инициализации не работает; он должен запустить цикл ожидания, который немедленно пожинает всех осиротевших зомби.
Хмакхольм покинул Монику
1

Если вы не знаете, кто является родителем, вам следует использовать какой-нибудь системный трейсер, например, audd

Вы бы включили регистрацию с помощью:

auditctl -a exit,always -S execve -F path=/usr/bin/rrdtool

а затем в /var/log/audit/audit.logстроке найти, как:

type=SYSCALL msg=audit(1414027338.620:6232): arch=c000003e syscall=59
success=yes exit=0 a0=7fdea0e4db23 a1=7fffec7c5220 a2=7fffec7c87d0
a3=7fdea1b559d0 items=2 ppid=17176 pid=18182 auid=1000 uid=1000 gid=1000 
euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 fsgid=1000 tty=pts8 
ses=2 comm="sh" exe="/bin/dash" key=(null)

(разбит на несколько строк для удобства чтения). Вы интересуетесь exe="/bin/dash"и / или pid=18182которые идентифицируют ваш процесс румян, который вы хотите найти, и ppid=17176который определяет родителя, который его выполнил.

Матия Налис
источник