지속적으로 실행되는 Java 프로세스가 있는데 아직 완전히 디버깅하지 않은 이유로 충돌이 발생하는 경우가 있습니다. 따라서 5분마다 프로세스를 찾는 cron 작업도 있으며, 프로세스가 실행되고 있지 않은 것으로 확인되면 스크립트를 호출하여 다시 시작합니다.
문제는 때때로 검사 스크립트가 때때로 거짓 긍정을 얻는다는 것입니다. 실제로는 프로세스가 실행 중인데도 프로세스가 실행되고 있지 않다고 생각합니다. 나는 이 일을 할 때 어떤 일관성도 보지 못했습니다. 하지만 프로세스가 실행 중인지 확인하는 완전히 확실한 방법이 필요합니다.
내가 현재 하고 있는 일은 이렇습니다.
if ! pgrep -f '/path/to/XML2DB.jar -n' > /dev/null
then
nice -n 19 java -Xmx2024M -jar /path/to/XML2DB.jar -n > /dev/null 2>/dev/null &
echo "" | mail -s "$HOST: xml2db was found not running, is being started" [email protected]
fi
pgrep 이전에는 이를 사용했지만 ! ps ax | grep -v grep | grep "XML2DB.jar -n" > /dev/null
이 역시 거짓 긍정을 생성했습니다.
Scientific Linux SL release 3.0.9 (SL)
현재 리눅스 버전 은 LSB Version
1.3입니다.
미리 감사드립니다!
답변1
이 기술에는 ps ax | grep -v grep | grep "XML2DB.jar -n"
경쟁 조건이 있습니다 . grep
인스턴스가 시간에 맞춰 시작되거나 시작되지 않을 수 ps
있으므로 부정확한 개수를 얻게 됩니다.여기그리고여기. 당신은 그것을 사용하는 데 어려움을 겪는 첫 번째 사람이 아닙니다.
무슨 일이 일어나고 있는지 strace pgrep somepattern
확인하기 위해 RHEL 상자에서 테스트를 수행했습니다 . pgrep
이는 디렉토리의 모든 프로세스 수를 계산 /proc
하고 /proc/<PID>/cmdline
일부 PID를 열고 내용을 읽습니다. 아마도 pgrep
명령줄에 제공된 패턴과 일치할 것입니다. 나는 여기서 손을 흔들고 있지만 거기에도 경쟁 조건이 있을 것이라고 확신합니다.
이에 대한 유일한 확실한 해결책은 Java 프로세스가 "디렉토리 잠금". 디렉토리 생성은 사용자 프로세스에 대해 원자적입니다. 잠긴 디렉토리가 이미 존재하는 경우 오류 메시지와 함께 종료하고, 그렇지 않으면 시작합니다. 생성 후디렉토리 잠금, 잠긴 디렉터리의 파일에 PID를 써야 합니다.
파일의 PID를 사용하여 Java 프로그램이 실행 중인지 확인할 수 있습니다 kill -0 $(cat /whatever/lockdir/PIDfile)
. 프로세스가 존재하지 않으면 kill
0이 아닌 상태로 종료됩니다.
비결은 명령줄에서 PID를 Java 프로그램에 전달하는 것입니다.
exec java blah blah -mypid $$
PID 파일을 생성, 해석, 삭제하고 디렉터리를 잠글 때 여전히 오류나 예외에 대해 매우 주의해야 kill -0
하지만 다른 방법을 사용하면 문제가 발생합니다.
답변2
관련 없는 프로세스가 실행 중인지 여부를 안정적이고 효율적으로 확인할 수 있는 방법은 없습니다. 경쟁 조건은 항상 가능합니다. 관심 있는 프로세스가 실행 중인지 감지하는 방법을 찾았더라도 보자마자 해당 프로세스가 종료될 수도 있고, 반대로 놓치자마자 시작될 수도 있습니다.
프로그램이나 실행 방법을 제어하면 파일 잠금과 같은 고유한 리소스를 유지하도록 할 수 있습니다. 그러나 프로그램 호출 방법을 제어하는 경우 프로그램을 추적하는 더 쉬운 방법이 있습니다. 즉, 상위 프로그램에서 모니터링하는 것입니다. 하위 프로세스가 종료되면 프로세스에 알림이 전송됩니다.
프로세스가 항상 실행되도록 하는 가장 쉬운 방법은 루프에서 프로세스를 다시 시작하는 것입니다.
# sleep 1 avoids a tight loop if the process systematically fails to start
while sleep 1; do
nice …
ret=$?
if [ $ret -le 127 ]; then
msg="… exited with status $ret"
else
msg="… exited on signal $((ret-128))"
esac
mail -s "$msg" "$USER"
done
더 강력하고 강력한 모니터링 소프트웨어가 있습니다. 바라보다내 서비스를 자동화된 방식으로 적절하게 모니터링하려면 어떻게 해야 합니까? 그러면 충돌이 발생하면 자동으로 다시 시작됩니까?