У нас есть серверное приложение Java, работающее на Mac OS X.
Время от времени это приложение перестало отвечать, и мы прибегали к его закрытию с помощью kill -9
. Однако процесс не исчезает; это все еще кажется ps
, с круглыми скобками вокруг имени и вопросительным знаком в столбце STAT:
$ ps u -p 776
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
camadmin 776 0.0 0.0 0 0 ?? ?E 5:12PM 0:00.00 (java)
Более того, порт, используемый сервером, все еще привязан:
$ netstat -na | grep 9902
tcp4 0 0 *.9902 *.* LISTEN
даже если это не видно lsof
:
$ sudo lsof -P -i tcp | grep 9902
$
Поскольку порт все еще привязан, мы не можем перезапустить серверное приложение. Что можно сделать, не считая перезапуска машины, чтобы освободить порт и действительно убить этот процесс?
Ваш процесс чего-то ждет, прежде чем он сможет выйти.
Может системный вызов. Типичный пример - попытка получить доступ к размонтированному файлу или к недоступному сетевому ресурсу.
Есть ли родительский или дочерний процесс, который тоже нужно убить?
Я не пользователь MacOS, но пользуюсь linux ps wwauxf | less
полезен для просмотра иерархии процессов в поисках родительских и дочерних процессов. strace -p [pid]
может рассказать вам что-нибудь полезное о текущем системном вызове, который еще не вернулся.
-
РЕДАКТИРОВАТЬ: Ваш процесс запущен с помощью launchd? Кажется, у некоторых людей с этим проблемы (например, Как убить "выходящий" процесс в OS X (состояние = E)) и, как было предложено выше, вам, вероятно, нужно убить родительский процесс, который в этом случае запускается. Может быть, это не лучше перезагрузки.
Предположительно, launchd поддерживает соединение с вашим приложением, чтобы перезапустить его, если оно умирает, но здесь это не так уж и полезно.
Убил -15 работает лучше? т.е. до того, как вы войдете в описываемое вами состояние, а не как выход из него.
государство E
означает, что процесс завершается. Но ваш процесс - это, по сути, зомби, который никогда не выходит. Все, что я нашел в Интернете, показывает, что вы мало что можете сделать, кроме перезагрузки, например Как убить "выходящий" процесс в OS X (состояние = E). Если вы не хотите перезагружать сервер OSX из-за того, что затронуты другие службы, вы можете рассмотреть (как обходные пути) либо:
Перенесите только эту java-службу на отдельную машину OSX, которую вы можете перезагрузить в любое время с минимальным воздействием.
Если у вас достаточно оперативной памяти на этом сервере, вы можете создать виртуальную машину и запустить эту службу внутри виртуальной машины. Если процесс перестанет отвечать и не будет остановлен, вы можете просто отскочить от виртуальной машины и не повлиять на ОС хоста. Поскольку это похоже на Java, вам не обязательно создавать гостевую виртуальную машину OSX. Может быть, попробовать это на виртуальной машине Ubuntu или CentOS? Вы можете загрузить любой из них как устройство (файл OVA / VDI) и запустить его в VirtualBox менее чем за 30 минут. Может даже не быть проблемы с зомби на виртуальной машине Linux. Видеть http://virtualboximages.com/Free.VirtualBox.VDI.Downloads