Մեր սպասման ցիկլը 35 ժամ սպասել է իրեն՝ pgrep -f և pkill -f՝ SSH-ի միջոցով
Օպերացիաներ
Հոկտեմբերի 31-ին մենք SSH-ի միջոցով փոքրիկ ցիկլ գործարկեցինք՝ սպասել, մինչև մեկ այլ մեքենայի վրա թարգմանության աշխատանքը ավարտվի, ապա գործարկել հաջորդական աշխատանքը։ Թարգմանության աշխատանքն այդ գիշեր ավարտվեց։ Երբ երկու օր անց նորից նայեցինք, ցիկլը 35 ժամ էր սպասում, իսկ հաջորդական աշխատանքը երբեք չէր գործարկվել։
Ինչ էր ցիկլը
ssh build-host 'while pgrep -f "i18n_job.py example.com" >/dev/null; do sleep 30; done; ./follow-up.sh'
pgrep -f-ը համապատասխանեցնում է նմուշը բոլոր գործընթացների ամբողջական հրամանային տողերի հետ։ SSH-ը մեջբերված հրամանը գործարկում է որպես bash -c 'while pgrep -f "i18n_job.py example.com" …', և այդ հրամանային տողը պարունակում է նմուշը։ pgrep-ը իր սեփական գործընթացը արդյունքներից դուրս է թողնում, բայց ոչ այն shell-ը, որը գործարկել է այն։ Այսպիսով, քանի դեռ ցիկլը կենդանի էր, այն գտնում էր համընկնում՝ ինքն իրեն։
Դրա երկվորյակը՝ pkill -f-ը սպաննում է այն shell-ը, որում գործարկվում է
Նույն բանը տեղի է ունենում pkill -f-ի դեպքում՝ ավելի վատ արդյունքներով.
ssh build-host 'pkill -f "worker.py --queue a"; nohup python3 worker.py --queue a &'
Shell-ի սեփական հրամանային տողը պարունակում է նմուշը, ուստի pkill-ը սպաննում է shell-ը։ Worker-ը կանգնեցվում է և այլևս երբեք չի գործարկվում, իսկ SSH-ը դուրս է գալիս 255 կոդով՝ առանց սխալի հաղորդագրության։ Դա նման է մեջբերման խնդրի, ինչպես մենք առաջին անգամ մտածեցինք։
Սեպտեմբերից մինչև հոկտեմբերի վերջ մենք առնվազն մեկ տասնյակ անգամ ընկանք այս կամ այն խնդրի մեջ՝ չիրականացված վերագործարկումներ, ցիկլ, որը ստուգումը պահել է երեք ու կես ժամ, մեկ այլ ցիկլ, որը թարգմանությունների հերթը պահել է 50 րոպե, և սա։
Ինչ ենք անում հիմա
- Փակագիծ նմուշում.
pgrep -f "[i]18n_job.py example.com"։ Որպես կանոնավոր արտահայտություն՝[i]-ը համապատասխանում է i տառին, ուստի աշխատանքը դեռ համընկնում է; shell-ի հրամանային տողը պարունակում է[i]նիշերը, որոնք արտահայտությունը չի համապատասխանեցնում։ Դա օգնում է միայն այն դեպքում, եթե պարզ նմուշը այլևս ոչ մի տեղ չի հանդիպում այդ տողում. վերագործարկման հրամանը նույն տողում ավելի ուշ նորից համընկնում է։ - Գտնել, կանգնեցնել և գործարկել առանձին SSH կանչերով. Մեկ կանչը ցուցակում է գործընթացները
pgrep -af-ով, հաջորդը սպաննում է տպված PID-երը, երրորդը գործարկում է նոր գործընթացը։ - Սպասել PID-ին, ոչ թե նմուշին.
tail --pid=1234 -f /dev/null, կամwhile kill -0 1234; do sleep 30; done։ - Ավելի լավ է՝ թող systemd-ը ստանձնի առաջադրանքը։ Գործարկեք այն որպես միավոր և հարցրեք
systemctl is-active-ին, կամ մեկնարկեքsystemd-run --wait-ով։ Սխալվելու հնարավորություն չկա։ - Յուրաքանչյուր սպասում ունի վերջնաժամկետ (
timeout 3h) և նշում է, թե երբ է այն դադարեցնում։ Առանց վերջնաժամկետի ցիկլը լռությամբ ձախողվում է։
Factory Floor-ը՝ մեր մեքենաները կառավարող հավաքածուն, աշխատում է systemd միավորների միջոցով. այն երբեք չի փնտրում պրոցեսը հրամանային տողով։ Մեզ խաբեած ցիկլերը այն ցիկլերն էին, որոնք մենք ձեռքով էինք գրել։