У нас есть серверное приложение 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 | меньше
полезно просматривать иерархию процессов для поиска родительских и дочерних процессов. strace -p [pid]
может рассказать вам что-нибудь полезное о текущем системном вызове, который еще не вернулся.
--
EDIT: Ваш процесс запущен с помощью startd? Похоже, у некоторых людей с этим возникают проблемы (например, Как убить "выходящий" процесс на OS X (состояние = E)) и, как было предложено выше, вам, вероятно, нужно убить родительский процесс, которым в данном случае является launchd. Возможно, это не лучше перезапуска.
Предположительно, запуск поддерживает связь с вашим приложением, чтобы перезапустить его, если оно умрет, но это еще не все.
А убийство -15 работает лучше? т.е. до того, как вы войдете в описанное состояние, а не как выход из него.
.State E
, похоже, означает, что процесс завершает работу. Но ваш процесс, по сути, является зомби, который никогда не выходит. Всё, что я нашёл в интернете, показывает, что мало что можно сделать, кроме перезагрузки, например, Как убить "выходящий" процесс на OS X (состояние = E). Если вы не хотите перезагружать сервер OSX из-за воздействия других служб, вы можете рассмотреть (как обходные пути):
Перенести только эту java-службу на отдельную машину OSX, которую вы можете перезагрузить при необходимости с минимальным воздействием
Если у вас достаточно оперативной памяти на этом сервере, вы можете сделать виртуальную машину и запустить эту службу изнутри ВМ. Если процесс становится невосприимчивым и не будет убит, вы можете просто откатить ВМ и не влиять на операционную систему хоста. Поскольку это выглядит как Java, вам не обязательно делать гостевую ВМ OSX. Может быть, попробовать его в ВМ Ubuntu или CentOS? Вы можете скачать любой из них как устройство (OVA/VDI файл) и запустить его в VirtualBox менее чем за 30 минут. Возможно, даже не будет проблемы с зомби на Linux VM. Смотрите http://virtualboximages.com/Free.VirtualBox.VDI.Downloads