הגדרת מגבלות מתארי קבצים לאפליקציות בעומס גבוה

תחת עומס שיא השירות מתחיל להיכשל סתם כך — והסיבה לעתים קרובות במגבלות שהוגדרו שגוי. אנו מגדירים מגבלות מתארי קבצים כפתרון מלא: מנתחים פרופיל עומס, מביאים את מגבלות המערכת והשירות למצב אחיד ומעבירים לצוות נהלים. לאחר העבודה הכשלים בשיא נעלמים, ומספר ההשבתות מצטמצם פי כמה.

היכולות שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1359
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    776
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1022
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113

מדוע האפליקציה נתקלת במגבלות של מתארי קבצים

כל חיבור, קובץ פתוח, socket או ערוץ — הוא מתאר קובץ, שנלקח מטבלת התהליך. הטבלה אינה אינסופית: גודלה נקבע על ידי מגבלה רכה וקשיחה, שעוברת בירושה מהאב בעת האתחול.

systemd קובע ערך משלו לשירות, המעטפת קובעת משלו דרך ulimit, ותהליכי עבודה מקבלים לעתים קרובות לא את המגבלה שהוגדרה «על הנייר».

כל עוד השירות עובד במצב רגוע, מתארי קבצים פנויים לא נגמרים — המגבלה נראית רק תחת עומס. כל חיבור נכנס, פנייה ל-cache, כתיבה ליומן או לתור תופסת עוד אחד.

אם חיבורים לא נסגרים בזמן — אין הגבלה על זמן ההחזקה, אובדן ענפים במקרה של שגיאות — נוצרת דליפת מתארי קבצים: המונה גדל באופן מונוטוני ואינו חוזר לרמה הבסיסית.

ביומנים זה נראה אותו דבר: שגיאה «יותר מדי קבצים פתוחים», סירוב לקבל חיבור חדש, בעוד התהליך חי ומדדי הבריאות מגיבים. כלפי חוץ — סירוב של השירות תחת עומס שיא: מאזן העומסים רואה פורט פתוח, אבל בקשות לא מטופלות. לקוחות עוברים לניסיונות חוזרים ומכלים את יתרת מתארי הקבצים הפנויים.

שיא מסוכן בכך שחיבורים לא סגורים וניסיונות חוזרים מצטברים: כל חיבור חדש דורש מתאר קובץ, והם מתפנים לאט יותר מקצב ההגעה. אנו מנתחים כיצד זה נסגר — מביקורת מגבלות ועד בקרת דליפות.

מה נותנות המגבלות המוגדרות: פחות סירובים והשבתות

מגבלה לא מוגדרת באה לידי ביטוי לא באתחול, אלא בשיא: תהליך העבודה נתקל במגבלה רכה, חיבורים חדשים נהדפים, ביומנים גדל שיעור השגיאות — בעוד השירות מגיב לבדיקת זמינות ונראה חי. האבחון הולך לכיוון האפליקציה והרשת, למרות שהסיבה היא בפרמטר אחד שאף אחד לא הגדיר לפרופיל עומס אמיתי. אנו מנתחים מה משתנה כאשר הוא מוגדר.

המגבלות מוגדרות במפורש — בנפרד soft ו-hard, הצמודות לשירות עצמו, ולא לסשן האינטראקטיבי של המנהל. ב-systemd זה LimitNOFILE בקובץ unit, עבור תהליכים מחוץ למנהל השירותים — כללים ב-limits.conf. אחרת, לאחר הפעלה מחדש הצומת יחזור לערך ברירת המחדל, והתקלה תחזור על עצמה באותו מקום.

ההשפעה ניתנת למדידה בשלושה צירים. הפחתת סירובים נראית בשיעור החיבורים הכושלים ובקוד החזרה בקבלה — היא יורדת לאפס בטווח המלאי המאומת. זמן ההתאוששות של השירות לאחר השיא מתקצר: אין צורך לחכות שמתארי קבצים, שתהליכים מחזיקים בהמתנה, יתפנו.

העמידות תחת עומס מפסיקה להיות תלויה במזל — תור החיבורים לא גדל באופן מפולתי, ההידרדרות מתרחשת בהדרגה ונעלמת מעצמה.

הצפיות בעבודה נובעת מכך שהמגבלה מתוארת במאגר ומופצת לכל צומת באופן זהה: מופע חדש באשכול מתנהג כמו האחרים. את המלאי אנו מאמתים בהרצת עומס עם פרופיל קרוב לשיא, ושומרים על הסף מעל למקסימום המחושב במקדם מובן. מניעת השבתות נשענת בדיוק על מלאי זה, ולא על כוננות מסביב לשעון.

אפשרויות הגדרת מגבלות: מה מתאים לעומס

מגבלת מתארי קבצים לא נקבעת במקום אחד: לתהליך יש מגבלה רכה וקשיחה, למערכת יש תקרה כוללת, ושירותים וסשנים של משתמשים מקבלים ערכים בדרכים שונות. סדר ההחלה תלוי במי שמפעיל את התהליך: המעטפת בכניסה, מנהל השירותים או האב שהעביר ערכים בירושה.

לכן הגדרה תחת עומס היא בחירת רמה, ולא חיפוש אחר «הקובץ הנכון». עריכה ברמה אחת לא משפיעה על תהליכים שעולים אחרת, והמגבלה נשארת בשקט כשהייתה: האפליקציה נתקלת בסירוב בעת פתיחת חיבורים, למרות שבהגדרות הכל נראה תקין.

רמת הגדרה מתי מתאים הגבלות
תקרה מערכתית מלאי כולל של מתארי קבצים לכל תהליכי הצומת קובע גבול עליון, אך לא מחלק אותו בין שירותים
מגבלה רכה של התהליך האפליקציה עצמה מעלה את המגבלה באתחול לא יכולה לעלות על המגבלה הקשיחה
מגבלה קשיחה של התהליך גבול עליון, שמעליו התהליך לא יעלה חל רק על תהליכים חדשים או לאחר הפעלה מחדש
מגבלות לשירותים דמונים שעולים ללא כניסת משתמש לא עוברות בירושה לסשנים אינטראקטיביים ולהפעלות ידניות
מגבלות לסשנים של משתמשים ניפוי שגיאות והפעלה ידנית מתוך המעטפת לא חלות על שירותים שעולים לפני הכניסה

התוצאה נבדקת לפי הערך בפועל בתהליך פעיל, ולא לפי קובץ ההגדרות: הפעלה מחדש של השירות וסשן חדש נותנים תמונה שונה. עבור פרופיל עומס מעלים גם את התקרה המערכתית — אחרת השירות יתקל במגבלה הכוללת לפני שיתקל במגבלה שלו.

כיצד מתבצעת ההטמעה: מביקורת ועד מסירת נהלים

מגבלות של מתארי קבצים עוברות בירושה לתהליך ברגע האתחול, לכן עריכת קונפיגורציה «על חי» לא משנה דבר, וערך שהוגדר עם מלאי גדול מדי לא פותר את הבעיה — הוא רק דוחה את הסירוב ומסתיר דליפה. את העבודה אנו מבצעים בסדר קבוע: תחילה מדידה ותרשים, אחר כך שינויים.

  1. ביקורת קונפיגורציה. אנו אוספים ערכים בפועל בכל השכבות: הגבלות kernel, ספי מערכת, פרמטרים של השירות שמפעיל את האפליקציה, והגבלות של סשן המשתמש. פער בין השכבות — סיבה טיפוסית לכך שהתהליך רואה לא את מה שנכתב בקובץ.
  2. מדידת מצב קיים. אנו בודקים כמה מתארי קבצים התהליך מחזיק במנוחה ובשיא, כיצד גדל מספר החיבורים והקבצים הפתוחים, מה נשאר ביומנים לאחר סירובים קודמים. זה נותן נקודת מוצא, לא ניחוש.
  3. תרשים הגדרה. אנו קובעים היכן בדיוק עורכים, אילו תהליכים מקבלים חריגים, כיצד הערך יחול גם על השירות וגם על הפעלה ידנית. מפרידים בין ספים רכים לקשיחים, וקובעים מלאי ביחס לצריכה בשיא.
  4. הגדרה. אנו מבצעים עריכות בקונפיגורציה ובתיאור השירות, מפעילים מחדש לפי תוכנית, ולא ברגע של תקלה, ובודקים שהערך החדש באמת נקלט בתהליך.
  5. בדיקה תחת עומס. אנו משחזרים פרופיל עבודה: תעבורה בשיא, פרץ חיבורים, כשל של צומת סמוך. בנפרד בודקים את התנהגות האפליקציה כשהיא מתקרבת לסף.
  6. נצפות. אנו מגדירים מדדים לפי מספר מתארי הקבצים והחיבורים הפתוחים והתראה לפי קצב הגדילה — אז הדליפה נראית הרבה לפני שהתהליך נתקל בתקרה.
  7. מסירת נהלים. אנו מוסרים מסמך עם ערכי יעד, סדר החלה על צומת חדש, רשימת בדיקה לאחר שינויים וטבלת «תסמין → מה לבדוק».

לאחר המסירה, צוות הלקוח יכול בעצמו להפיץ את המגבלות בשרתים חדשים ולהבין מתי גידול במספר מתארי הקבצים הוא נורמה, ומתי הוא אות לבעיה.

קונפיגורציות, תרשימים ותיעוד לאחר סיום העבודה

הגדרת מגבלות אינה נחשבת להסתיימה כל עוד היא חיה רק בהיסטוריית הפקודות בשרת מסוים. אנו משאירים לצוות שלכם סט ארטיפקטים, שבאמצעותם מהנדס ישחזר את אותה קונפיגורציה במיתקן אחר, יסביר את הערכים הנבחרים בעוד חצי שנה, ויבין היכן לחפש את הסיבה אם המונים שוב יתקלו בתקרה.

  • קובצי קונפיגורציה עם ערכים רכים וקשיחים נפרדים עבור שירותי מערכת וסשנים של משתמשים, עם הערות: מהיכן בא המלאי ומה יקרה אם יופחת.
  • פרופילי אתחול של אפליקציות — היכן בדיוק מועלית המגבלה: בתיאור השירות, בעטיפת ההפעלה או בסביבת הקונטיינר, כדי שהערך לא יאבד בהפעלה מחדש ובפריסה.
  • תרשים תשתית עם תפקידי צמתים וסימון באילו מכונות המגבלות הועלו, ובאילו נשארו בסיסיות ומדוע.
  • מדיניות גישה: אילו תפקידים יכולים לשנות פרמטרים של kernel ולהפעיל מחדש שירותים, וכיצד זה קשור להרשאות על הקונפיגורציה.
  • נהל תחזוקה: כיצד לבדוק את הערך בפועל בתהליך פעיל, אילו מונים לבדוק בעת גידול בעומס ובאיזו תדירות.
  • חישוב ערכי יעד: חיבורים סימולטניים בשיא לתהליך, מספר מטפלים, חיבורים שירותיים ומלאי להתאוששות.
  • רשימת בדיקה לקבלה לאחר ההחלה וסדר חזרה לערכים קודמים, אם הקונפיגורציה החדשה תיתן אפקט בלתי צפוי.

בנוסף, תזכיר למשמרת התורנית: תסמינים טיפוסיים של התקלות במגבלה וקו הפעולה הראשון לפני הסלמה. כל זה נמסר במאגר הקונפיגורציות שלכם, ולא במכתבים נפרדים.

מקרה בוחן: הסרנו סירובים של השירות תחת עומס שיא

איך זה היה

השירות בשיא הפסיק לקבל חיבורים חדשים: ביומנים — סירוב לפתוח קובץ או socket, כלפי חוץ — פרץ שגיאות וקטיעות חיבורים. התורן ראה תסמין, לא סיבה: מדדים עקבו אחרי קודי תגובה, אבל לא אחרי מספר מתארי הקבצים הפתוחים, לכן כל בירור התחיל בסריקה ידנית של יומנים. מרגע האות הראשון ועד ההתאוששות עברו עשרות דקות, וכל אותו זמן חלק מהבקשות אבדו.

מה שינינו ומה קיבלנו

תחילה הסרנו קו בסיס: כמה מתארי קבצים השירות מחזיק בשיא וכמה הוא פותח לכל בקשה. התברר שתקרת המגבלה הרכה נוצלה במלואה כבר בעבודה שגרתית — לא היה מלאי, והמגבלה עצמה נקבעת לתהליך, לכן עם כמה תהליכי עבודה התקרה מנוצלת מהר יותר מכפי שמצפים, פי כמה.

העלינו את המגבלות הרכות והקשיחות לתהליך, ובנפרד — את התקרה המערכתית, עם מלאי לגידול, והסרנו את הדליפה: חיבורים חוזרים לשימוש חוזר, ולא נשארים פתוחים עד הפעלה מחדש.

את הנצפות העברנו לסיבה. מספר מתארי הקבצים הפתוחים וחלקו מהמגבלה מוצגים בגרף לצד התעבורה ב-Prometheus ובלוחות משותפים, התראה מופעלת בהתקרבות לתקרה, ולא לאחר סירוב.

לאחר השינויים השיא עובר ללא סירובים מהסוג הזה: תפוסת המגבלה נשמרת בתוך שני שלישים במקום להיתקל בגבול, זמן האבחון הצטמצם משעות לדקות, והפעלה מחדש ידנית של השירות תחת עומס אינה נדרשת עוד.

במה שונה המגבלה המערכתית ממגבלת השירות

מגבלת מתארי קבצים נקבעת בשתי רמות שונות, ובלבול ביניהן הוא המקור לרוב הסירובים ה«מיסטיים». המגבלה המערכתית — תקרה כוללת לכל המכונה, אותה מחזיק ה-kernel. מגבלת התהליך והשירות — כמה מתארי קבצים תהליך מסוים יכול לפתוח; היא תמיד נמוכה מהמערכתית ועוברת בירושה בעת ההפעלה.

העדיפות נקבעת לפי מי שהוליד את התהליך: תהליך בן לא קורא את הקונפיגורציה מחדש, אלא מקבל ערכים מהאב, לכן התוצאה תלויה בשרשרת ההפעלה.

רמת הגבלה היכן נקבעת על מה משפיעה מה עוקפת
מערכתית פרמטרים של kernel סה"כ על המארח תקרה לכל השירותים
שירות תיאור unit ב-systemd רק השירות הזה ערכים של פרופילי משתמשים
סשן משתמש limits.conf דרך PAM כניסות אינטראקטיביות מגבלה רכה של הסשן
תהליך ulimit בעת ההפעלה התהליך הנוכחי ותהליכי הבן דבר מעל המגבלה הקשיחה

ניואנס מרכזי: שירותים שמועלים על ידי מנהל השירותים לא עוברים דרך PAM, לכן עריכות עבור סשנים של משתמשים לא משפיעות עליהם — מכאן הפער הקלאסי «בטרמינל המגבלה אחת, ומתחת לשירות אחרת».

בתוך אותה רמה, המגבלה הרכה היא ערך עבודה, והקשיחה היא הגבול העליון: ניתן להעלות את הרכה, אבל לא מעל הקשיחה, והקשיחה לא מעל המערכתית.

את הערך בפועל בודקים לפי /proc/<pid>/limits של תהליך מסוים, ולא לפי קובצי קונפיגורציה. סדר ההחלה: תקרה מערכתית → פרמטרים של unit או של האב → ירושה לתהליכי בן → הערך שאיתו התהליך באמת עובד.

ספקות טכניים נפוצים בהגדרת מגבלות

ניתוח מגבלות כמעט תמיד נתקל לא בשאלה «להעלות או לא», אלא בהסתייגויות של צוות ההנדסה: ממה זה מאיים על שירות פעיל, ואיך אחר כך להוכיח שהשתפר. להלן מה שעולה לרוב בדיונים.

בנפרד ראויה לציון ההתנהגות תחת עומס: בתעבורה ממוצעת המלאי נראה מוגזם, ובשיא אותו תהליך נתקל במגבלה, כי חלק ממתארי הקבצים מוחזקים על ידי חיבורים וקבצים זמניים. לכן את החישוב אנו מבצעים לפי פרופיל שיא, ולא לפי ממוצע יומי.

האם יהיה צורך להפעיל מחדש את השירות?

לא תמיד, אבל צריך לתכנן חלון. חלק מהפרמטרים חלים על תהליך פעיל, חלק — רק באתחול או בכניסה חדשה לסשן, ומגבלות מערכתיות משתנות ברמת ה-kernel. הסדר הוא כזה: תחילה עורכים את תיאורי השירותים ואת הערכים המערכתיים, ואחר כך מפעילים מחדש צומת אחר צומת, כדי לא לאבד זמינות.

האם המגבלה החדשה תסתיר דליפה אמיתית?

הסיכון קיים, והוא העיקרי. אם מתארי קבצים לא נסגרים במטפלים, מגבלה גבוהה רק תדחה את הסירוב. לכן לפני השינוי ניקח תמונת מצב של מתארי קבצים פתוחים בכמה תהליכים: גידול הקשור למספר הבקשות — זו דליפה, פרופיל יציב — חוסר במלאי. את האבחון עושים לפני העריכות, ולא אחריהן.

איך להשתכנע שהמלאי באמת נחוץ?

לפי ניטור: אנו אוספים את מספר מתארי הקבצים הפתוחים לפי תהליכים, את שיעור השימוש מהמגבלה ואת מונה סירובי הפתיחה. התראה שמים על 75–80% מהמגבלה, כדי שיהיה מלאי עד להידרדרות, ומשווים אותה להיסטוריית הקריאות — כך רואים אם הצריכה גדלה עם הזמן או נתקלת בשיאים עונתיים.

האם זה מתנגש עם הקונפיגורציה הנוכחית?

מגבלות יכולות להיקבע בכמה מקומות — ברמת המערכת, בתיאור השירות, בפלטפורמת הקונטיינרים. חל לא הגדול ביותר, אלא זה שנקבע מאוחר יותר בשרשרת ההפעלה, לכן אנו מאחדים את הערכים למקור אחד ומקבעים בתיעוד. אחרת לאחר הפעלה מחדש ההתנהגות תהיה לא זו שנבדקה במיתקן.

נדון במשימה ונחזור עם הערכה ותוכנית עבודה

הערכת הגדרת מגבלות של מתארי קבצים לעתים רחוקות דורשת סקר ארוך — אבל הרכב העבודה ותוכנית ההטמעה תלויים ישירות במידת התיאור המלא של קווי המתאר. להלן נתוני הקלט, שמספיקים כדי לחזור עם לוחות זמנים וסדר שינויים.

  • הרכב השירותים: אילו תהליכים מחזיקים חיבורים וקבצים פתוחים — שרתי web, עובדי תורים, פרוקסי, בסיסי נתונים — וכמה מופעים פועלים על צומת אחד.
  • אופי העומס: מספר שיא של חיבורים סימולטניים, פרופיל יומי, כיצד המערכת מתנהגת ברגע השיא.
  • הגדרות נוכחיות: מגבלה רכה וקשיחה למשתמש ולתהליך, הגבלות ב-unit של השירות, מגבלה מערכתית על קבצים פתוחים.
  • תסמיני סירובים: טקסטי שגיאות מהיומנים, באיזה רגע מופיעים, מה בדיוק נופל ומופעל מחדש.
  • אופן ההפעלה: מי יוזם את התהליכים — שירות, סופרבייזר או קונטיינר — והאם המגבלות מועברות פנימה.
  • מה כבר שינו: אילו ערכים נערכו ומדוע התוצאה לא סיפקה.
  • הגבלות הסביבה: קונטיינרים, אורקסטרטור, האם יש הרשאות לשינוי פרמטרים מערכתיים.

עם סט זה אנו דנים במשימה ומקבעים סיכומים: אילו ערכים קובעים, כיצד בודקים תחת עומס ובאיזה סדר מבצעים חזרה לאחור.