שומר הסף שלנו הפעיל מחדש את השירותים שעצרנו בכוונה
תפעול
אחד משומרי הסף שלנו מפעיל כל שירות שלנו שמוגדר כפעיל אך לא רץ. פעמיים באוקטובר הוא הפעיל שירותים שעצרנו בכוונה. בפעם השנייה, מבקרים באחד מהאתרים שלנו קיבלו שגיאות במשך כ-45 דקות.
למה שומר הסף הזה קיים
שירות שיוצא בצורה תקינה כשהוא מקבל SIGTERM, למשל כי מישהו הרג אותו לפי שם, אינו מוגדר כ-"failed" מבחינת systemd. Restart=on-failure לא מחזיר אותו, ו-systemctl --failed לא מציג אותו. הוא נשאר כבוי עד שמישהו בטעות שם לב. לכן שומר הסף מחפש שירותים שמוגדרים כפעילים אך לא רצים, ומפעיל אותם.
הבעיה היא ששירות שעצרת ידנית נראה בדיוק אותו הדבר.
הפעם הראשונה
ב-7 באוקטובר עצרנו עובד וידאו עם systemctl stop ב-12:47 כדי לערוך את תור המשימות שלו. ב-12:55 הוא כבר רץ שוב: שומר הסף הפעיל אותו.
הפעם השנייה
ב-21 באוקטובר היינו זקוקים לזיכרון של המכונה שמשרתת גם שניים מהאתרים שלנו עבור בדיקת מודל. סקריפט עצר את אפליקציות האינטרנט של האתרים, משימת סנכרון ומיכל מסד נתונים, שוב עם systemctl stop. כעבור חמש דקות בערך, טיימר שעוקב אחר האתרים, וב-19:14 שומר הסף, החזירו את המנהרה ואת אפליקציות האינטרנט.
המנהרה קיבלה תעבורה שוב, אבל אפליקציות האינטרנט לא יכלו לענות: המודל בבדיקה תפס 114 GiB מזיכרון המכונה. משעה 19:14 בערך ועד 20:00, חלק מהמבקרים קיבלו שגיאות 502. ב-20:00 ביטלנו את ההפעלה האוטומטית של המנהרה, אפליקציות האינטרנט ומשימת הסנכרון, ועצרנו את הטיימר של שומר הסף.
הכלל שאנחנו משתמשים בו עכשיו
- השהו שירות על ידי ביטול ההפעלה האוטומטית שלו:
sudo systemctl disable --now <unit>. החזירו אותו עםsudo systemctl enable --now <unit>. שומר הסף שלנו מסתכל רק על שירותים שמוגדרים כפעילים, ולכן שירות שבוטלה ההפעלה האוטומטית שלו נשאר בשקט. - השהו כל דבר שיכול להפעיל אותו מחדש: המנהרה שמולו וכל טיימר שעוקב אחריו.
- עצירה קצרה היא מרוץ נגד הזמן. אם אתם משתמשים רק ב-
stop, סיימו לפני הבדיקה הבאה, שמתרחשת במכונות שלנו תוך דקות.
עוד שתי מלכודות systemd מאותם חודשים
systemctl mask --runtimeלא עושה דבר עבור קובץ יחידה ב-/etc/systemd/system. יחידות ב-/etc מקדימות למסכת הריצה ב-/run, ולכן הפקודה מצליחה והשירות עדיין מתחיל. כדי לעצור שירות, אנו משתמשים בקובץ drop-in עםConditionPathExists=!/etc/<name>.hold: כל עוד הקובץ הזה קיים, השירות לא יתחיל, לא באתחול ולא ידנית.systemctl is-activeמחזיר "inactive" עבור שירות oneshot שרץ. בזמן ששירותType=oneshotרץ, המצב שלו הוא "activating", ולכןis-activeמדפיס זאת ומחזיר 3. לולאה כמוwhile systemctl is-active --quiet job.service; do sleep 60; done, שנועדה להמתין למשימת לילה, יוצאת מיד. במקום זאת, קראו את המצב: active, activating, reloading או deactivating – כולם אומרים שהוא עדיין פועל.
Factory Floor מנטר שירותים מופעלים שאינם רצים. כברירת מחדל הוא רק מדווח עליהם, ומפעיל אותם רק אם תאפשרו זאת. מאז גרסה 1.0.3, ההתראה שלו גם מציינת כיצד לעצור שירות בכוונה, וספר ההפעלה שלו אומר את אותו הדבר.