Wanneer je een Linux-systeem monitort met de top opdracht, kun je soms een regel in de 'taken (Tasks)' tegenkomen zoals 1 zombie (zombie).
top - 16:03:19 up 7:09, 1 gebruiker, gemiddelde belasting: 2.24, 2.21, 2.29
Taken: 392 totaal, 1 in uitvoering, 390 wachtend, 0 gestopt, 1 zombie
...
Wat is deze 'zombie' en welke impact heeft het op het systeem? In deze post leggen we duidelijk de identiteit van het zombieproces en hoe dit te identificeren en op te lossen uit.
Wat is een Zombieproces? 🧟
Laten we het vergelijken met de levenscyclus van een proces om het begrijpelijk te maken.
-
Geboren (Fork): het ouders proces (Parent Process) creëert een kind proces (Child Process) (
fork()). -
Uitvoeren (Exec): het kind proces voert zijn taak uit.
-
Beeindigen (Exit): het kind proces voltooit zijn taak en beëindigt (
exit()). -
Oogsten (Wait): wanneer het kind proces beëindigt, slaat het besturingssysteem (kernel) informatie zoals de PID van het proces en de beëindigingsstatus op in de proces tafel. Vervolgens stuurt het een
SIGCHLDsignaal naar het ouders proces (het kind is beëindigd). -
Het ouders proces ontvangt dit signaal en moet de
wait()systeemoproep aanroepen om de beëindigingsstatus van het kind "te oogsten". Pas wanneer deze informatie is geoogst, kan de kernel het item van het kind definitief uit de proces tafel verwijderen.
Een zombieproces is dus een proces dat vastzit tussen stap 4 en 5. Dit betekent dat het kind proces is beëindigd, maar het ouders proces heeft nog niet de wait() aanroep gedaan om de beëindigingsstatus te oogsten.
Zoals de naam al aangeeft, is dit proces in een dode staat (niet uitgevoerd). Het verbruikt daarom geen systeemresources zoals CPU of geheugen.
Waarom zijn zombieprocessen een probleem?
Zombieprocessen gebruiken zelf bijna geen systeemresources, maar ze bezetten wel een slot (PID) in de proces tafel.
Als er door een bug in het ouders proces zombieprocessen blijven stapelen zonder opgeruimd te worden, kan het maximum aantal PID's dat het systeem kan toewijzen bereikt worden. In dat geval kan het systeem geen nieuwe processen meer aanmaken, wat kan leiden tot ernstige storingen. Het is niet ongebruikelijk dat 1-2 zombies zichtbaar zijn in top, maar als dit aantal blijft toenemen, is actie vereist.
Hoe zombieprocessen te identificeren en te herkennen
De top opdracht toont alleen het _aantal_ zombies. Om te zien welk proces in de zombie-status is en wie de ouder is, moet je de ps opdracht gebruiken.
De eenvoudigste manier is om het STAT (status) veld van de ps opdracht te bekijken en te zoeken naar processen die gemarkeerd zijn met 'Z'.
# Bekijk alle processen in het systeem en filter voor status 'Z' (zombie)
ps -elf | grep ' Z '
# Of gebruik de 'aux' optie (de 8e kolom ($8) is de status (STAT))
ps aux | awk '$8=="Z"'
Voorbeeld output:
# ps -elf | grep ' Z '
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
0 Z user 5021 5000 0 80 0 - 0 exit 15:30 ? 00:00:00 [defunct]
Belangrijke informatie uit het bovenstaande voorbeeld is:
-
S (Status):
Z(betekent dat het in zombie status is) -
PID:
5021(dit is de PID van het zombieproces) -
PPID:
5000(dit is de PID van het ouder proces dat niet heeft geoogst) -
CMD:
[defunct](de naam die aangeeft dat het is beëindigd maar niet is opgeruimd)
Hoe zombieprocessen op te lossen
Het belangrijkste om te weten is dat je een zombieproces niet kunt 'doden' met het kill commando.
kill -9 5021(de zombie PID uit het bovengenoemde voorbeeld)
Dit commando werkt niet. Zombies zijn al in een "dode" staat. Er is niemand meer om het kill signaal te verwerken.
De enige manier om zombieprocessen op te lossen is door het ouders proces te laten wait() aanroepen.
Stap 1: Signaal naar het ouders proces sturen (aanbevolen)
De eerste stap die je kunt proberen, is het handmatig versturen van een SIGCHLD signaal naar het ouders proces (PPID) om hem te vragen de status van het kind te controleren.
# Stuur een SIGCHLD signaal naar het ouders PID (5000) uit het bovengenoemde voorbeeld
kill -s SIGCHLD 5000
Dit heeft het effect dat het ouders proces ontvangt "Een van jouw kind processen is beëindigd, kijk ernaar!". Normaal gesproken zal een goed geprogrammeerd ouders proces deze signaal ontvangen en de zombie opruimen.
Stap 2: Dood het ouders proces (laatste redmiddel)
Als stap 1 niet werkt, betekent dit dat het ouders proces (PPID 5000) zelf is vastgelopen of dat er een ernstige bug zit in de logica die wait() aanroept.
In dit geval is het doden van het ouders proces de enige oplossing.
# Dood het ouders proces (PPID 5000)
kill 5000
# Als het nog steeds niet stopt, gebruik dan geforceerd
kill -9 5000
Waarom lost het op als je de ouder doodt?
In Linux, wanneer een ouders proces sterft, worden de kind processen (weesprocessen) automatisch init proces (PID 1) of systemd geadopteerd. Het init proces is ontworpen om regelmatig de status van zijn kinderen te controleren en beëindigde kinderen (inclusief zombies) onmiddellijk op te ruimen.
Daarom, als de problematische ouder (PPID 5000) sterft, wordt de zombie (PID 5021) het nieuwe kind van init en zal init het onmiddellijk opruimen.
⚠️ Opmerking: Controleer vóór het beëindigen van het ouders proces met
ps -p 5000of dit proces geen belangrijke service in het systeem is (bijv. DB, webserver, enz.). Het geforceerd beëindigen van belangrijke services kan leiden tot grotere storingen.
Samenvatting
-
Zombieprocessen zijn resten van processen die zijn beëindigd maar waarvan de ouder de beëindigingsstatus niet heeft geoogst.
-
Ze verbruiken geen resources, maar bezetten een PID, en als ze in overmaat verschijnen, kunnen ze systeemstoringen veroorzaken.
-
ps -elf | grep ' Z 'opdracht kan gebruikt worden om de zombie (PID) en zijn ouder (PPID) te vinden. -
De oplossing richt zich niet op de zombie, maar op de ouder proces (PPID).
-
kill -s SIGCHLD <ouderPID>(aanbevolen) -
kill <ouderPID>(laatste redmiddel)
-
댓글이 없습니다.