Odotussilmukamme odotti itseään 35 tuntia: pgrep -f ja pkill -f SSH:n yli
Ylläpito
31. lokakuuta käynnistimme pienen silmukan SSH:n yli: odota, kunnes toisella koneella oleva käännöstyö valmistuu, ja aja sitten jatkotyö. Käännöstyö valmistui sinä yönä. Kun tarkistimme tilanteen kahden päivän kuluttua, silmukka oli odottanut 35 tuntia, eikä jatkotyötä ollut koskaan ajettu.
Mitä silmukka oli
ssh build-host 'while pgrep -f "i18n_job.py example.com" >/dev/null; do sleep 30; done; ./follow-up.sh'
pgrep -f vertaa kaaviota jokaisen prosessin koko komentoriviin. SSH suorittaa lainatun komennon muodossa bash -c 'while pgrep -f "i18n_job.py example.com" …', ja tuo komentorivi sisältää kaavion. pgrep jättää oman prosessinsa tuloksista pois, mutta ei kuorta, joka käynnisti sen. Niin kauan kuin silmukka oli elossa, se löysi osuman: itsensä.
Sen kaksoset: pkill -f tappaa kuoren, jossa se ajetaan
Sama tapahtuu pkill -f:n kanssa, ja seuraukset ovat vielä pahemmat:
ssh build-host 'pkill -f "worker.py --queue a"; nohup python3 worker.py --queue a &'
Kuoren oma komentorivi sisältää kaavion, joten pkill tappaa kuoren. Työntekijä pysähtyy eikä sitä enää käynnistetä uudelleen, ja SSH poistuu koodilla 255 ilman virheilmoitusta. Se näyttää lainausmerkkiongelmalta, mikä oli myös meidän tulkintamme ensimmäisellä kerralla.
Syyskuun ja lokakuun lopun välillä jouduimme toiseen tai toiseen tilanteeseen vähintään kymmenen kertaa: uudelleenkäynnistyksiä, jotka eivät koskaan tapahtuneet, silmukka, joka piti tarkistusta kolme ja puoli tuntia, toinen, joka piti käännösjonoa 50 minuuttia, ja tämä.
Mitä teemme nyt
- Sulje kaavio:
pgrep -f "[i]18n_job.py example.com". Säännöllisenä lausekkeena[i]vastaa kirjainta i, joten työ osuu edelleen; kuoren komentorivi sisältää merkit[i], joita lauseke ei vastaa. Tämä auttaa vain, jos pelkkä kaavio ei esiinny muualla samalla rivillä: samalla rivillä oleva uudelleenkäynnistyskomento osuu uudelleen. - Etsi, pysäytä ja käynnistä erillisissä SSH-kutsuissa. Yksi kutsu listaa prosessit komennolla
pgrep -af, seuraava tappaa sen tulostamat PID:t, kolmas käynnistää uuden prosessin. - Odota PID:iä, älä kaaviota:
tail --pid=1234 -f /dev/nulltaiwhile kill -0 1234; do sleep 30; done. - Anna mieluummin systemdin hoitaa tehtävä. Suorita se yksikkönä ja kysy tila komennolla
systemctl is-activetai käynnistä se komennollasystemd-run --wait. Tässä ei ole kaavaa, jossa voisi erehtyä. - Jokaisella odotuksella on määräaika (
timeout 3h), ja se kertoo, milloin se luovuttaa. Silmukka ilman määräaikaa epäonnistuu hiljaa.
Factory Floor, paketti, joka pyörittää koneitamme, toimii systemd-yksiköiden kautta: se ei koskaan etsi prosessia komentoriviltä. Ne silmukat, jotka meidät yllättivät, olivat niitä, jotka kirjoitimme käsin.