עודכן לפני חודש
חיבורי TCP מתוכננים להיות אמינים, אך לאמינות יש נקודת עיוורון: מה קורה כשהצד השני פשוט נעלם?
נפילת חשמל. קריסת ליבה. מישהו מועד על כבל רשת. המחשב המרוחק לא סוגר את החיבור בצורה תקינה — הוא לא יכול. הוא נעלם. והאפליקציה שלך? היא עדיין מחזיקה את החיבור פתוח, ממתינה לנתונים שלעולם לא יגיעו.
זוהי בעיית החיבור החצי-פתוח. ללא התערבות, חיבורי זומבי אלה נמשכים ללא הגבלת זמן, צורכים מתארי קבצים, זיכרון, ומקומות במאגרי חיבורים. TCP keep-alive קיים כדי לפתור זאת: פעימת לב לחיבורים לא-פעילים שמדי פעם שואלת, "האם אתה עדיין שם?"
מדוע חיבורים לא-פעילים הם עיוורים
מנגנוני האמינות הרגילים של TCP — אישורי קבלה, שידורים חוזרים, פסקי זמן — מופעלים רק כשמנסים לשלוח נתונים. אם החיבור שלך לא פעיל, ממתין במאגר לשימוש, אין מה שיפוג. החיבור נראה בריא לחלוטין עד שמנסים להשתמש בו ומגלים שהצד השני מת לפני שעות.
Keep-alive משנה זאת. בתקופות שבהן לא זורמים נתוני אפליקציה, מערכת ההפעלה שולחת מדי פעם בדיקה זעירה. אם מגיעה תשובה, החיבור חי. אם השקט נמשך לאחר מספר ניסיונות, מוכרז החיבור כמת ומנוקה.
כיצד הבדיקות עובדות
חבילת הבדיקה היא תעלול — היא שולחת מספר רצף שגוי מבחינה טכנית, במיוחד כדי לגרות תיקון. מחסנית ה-TCP המרוחקת לא יכולה לעצור עצמה; היא חייבת להגיב עם "למעשה, אני מצפה לבית X". אותה חובה לתקן היא הדרך שבה יודעים שמישהו עדיין שם.
כשמאפשרים TCP keep-alive על שקע, מערכת ההפעלה מפעילה טיימר לאחר חילופי הנתונים האחרונים. כשהטיימר פוג ללא פעילות, נשלחת בדיקה. אם העמית מגיב, הטיימר מתאפס. אם לא, נשלחת בדיקה נוספת. לאחר מספיק בדיקות כושלות, החיבור מסומן כמת.
הבדיקות זעירות — רק כותרות TCP, ללא מטען. הן אינן מפריעות לזרימת נתונים רגילה ומופעלות רק כשהחיבור אחרת היה שקט.
ברירות המחדל של הטיימרים הן מגוחכות
כאן התיאוריה פוגשת את המציאות: הגדרות ברירת המחדל של keep-alive שמרניות להחריד.
בלינוקס, זמן keep-alive ברירת המחדל הוא 7200 שניות. זה שעתיים לפני הבדיקה הראשונה. לאחר מכן 75 שניות בין בדיקות, עם 9 בדיקות נדרשות לפני הכרזת מוות. עשה את החשבון: חיבור מת לוקח יותר משעתיים לזיהוי.
ברירות מחדל אלה הגיוניות כשרוחב הפס היה יקר והאינטרנט היה שביר. הן לא הגיוניות למאגר חיבורי מסד נתונים שבו צריך לדעת תוך דקות — או שניות — שהשרת האחורי נכשל.
שלושה פרמטרים שולטים בהתנהגות:
- זמן Keep-Alive: כמה זמן להמתין לפני הבדיקה הראשונה (ברירת מחדל: 7200 שניות)
- מרווח Keep-Alive: זמן בין בדיקות עוקבות (ברירת מחדל: 75 שניות)
- בדיקות Keep-Alive: בדיקות כושלות לפני הכרזת מוות (ברירת מחדל: 9)
מערכות ייצור בדרך כלל דורסות אלה דרך אפשרויות שקע (TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT). תצורות נפוצות בודקות לאחר 60–300 שניות של חוסר פעילות, עם מרווחים של 10–30 שניות בין בדיקות. זה מזהה חיבורים מתים תוך דקות ולא שעות.
למה Keep-Alive מתאים
זיהוי עמיתים מתים: מקרה השימוש המרכזי. שרת שמאבד חשמל, קורס, או מנותק לא יכול לשלוח FIN או RST. בדיקות keep-alive מגלות את ההיעדרות.
מניעת תשישות משאבים: חיבורים חצי-פתוחים מצטברים. בשרת שמטפל באלפי חיבורים, אפילו אחוז קטן של זומבים יוצר לחץ על מתארי קבצים, זיכרון, ומגבלות חיבורים.
שמירת מיפויי NAT פעילים: מכשירי NAT וחומות אש עם ניהול מצב עוקבות חיבורים. אם חיבור יושב ללא פעילות זמן רב מדי, המכשיר הביניים שוכח אותו — חבילות עתידיות נשמטות גם אם שתי נקודות הקצה חושבות שהן מחוברות. בדיקות keep-alive מייצרות בדיוק מספיק תעבורה כדי לשמור על המיפוי טרי.
אימות חיבורים במאגר: לפני מסירת חיבור ממאגר לקוד האפליקציה, רוצים ביטחון שהוא אכן עובד. Keep-alive מספק אימות פסיבי — אם החיבור שרד במאגר, כנראה שהוא שמיש.
מה Keep-Alive לא יכול לומר לך
TCP keep-alive מאשר דבר אחד: מחסנית ה-TCP של הליבה המרוחקת מגיבה. זהו.
הוא לא יכול לומר לך אם האפליקציה בריאה. מסד נתונים עשוי להגיב לבדיקות TCP בעודו תקוע לחלוטין, לא מסוגל לבצע שאילתות. שרת אינטרנט עשוי לאשר keep-alive בעוד תהליכי העובד שלו תקועים בלולאה אינסופית.
זוהי המגבלה הבסיסית. Keep-alive פועל בשכבת התעבורה. הוא רואה את הרשת. הוא לא רואה את האפליקציה שלך.
לזיהוי כשלים ברמת האפליקציה — תהליכים תקועים, מאגרי חוטים מותשים, מצבי מבוי סתום — נדרשות פעימות לב ברמת האפליקציה. לקוח מסד נתונים שמריץ מדי פעם SELECT 1 מאמת את כל המחסנית: קישוריות רשת, זמינות מסד הנתונים, ביצוע שאילתות, רכישת נעילות. TCP keep-alive לא מאמת שום דבר מזה.
הגישה הנכונה משלבת את שניהם. השתמש ב-TCP keep-alive כבסיס לתפיסת כשלי רשת ושרתים מתים. השתמש בפעימות לב של האפליקציה לתפיסת כל השאר.
הפשרות
עומס רשת: בדיקות צורכות רוחב פס. עבור אלפי חיבורים לא-פעילים, התעבורה מצטברת. לעיתים רחוקות משמעותי ברשתות מודרניות, אך שווה לשקול בסביבות מוגבלות.
ניקוז סוללה: במכשירים ניידים, בדיקות תכופות מונעות מממשקי הרשת להירדם. אפליקציות ניידות לרוב מבטלות או מפחיתות בצורה משמעותית את תדירות keep-alive.
חיוביות כוזבות: תזמון אגרסיבי מסתכן בהכרזת חיבורים כמתים בזמן הפרעות רשת חולפות שהיו מסתדרות מאליהן. מרווח בדיקה של 10 שניות עם 3 בדיקות אומר ש-30 שניות של הפרעת רשת יהרגו את החיבורים שלך — גם אם הקישוריות חוזרת בשנייה ה-31.
מורכבות תצורה: ההגדרות הנכונות תלויות במצבי הכשל שלך, במאפייני הרשת, ובסבילות לחיבורים ישנים. אין תשובה אוניברסלית.
שורת התחתית
TCP keep-alive מזהה חיבורים מתים על ידי בדיקה בתקופות חוסר פעילות. מערכת ההפעלה מטפלת בהכל — אפליקציות רק מאפשרות את התכונה ומגדירות את התזמון.
ברירות המחדל שמרניות מדי לרוב שימושי הייצור. שעתיים לפני הבדיקה הראשונה הן נצח כשצריך לזהות כשלים במהירות. דרוס את הטיימרים.
Keep-alive תופס כשלי רשת ושרתים מתים. הוא לא תופס כשלי אפליקציה. לבדיקת בריאות מקיפה, שלב keep-alive בשכבת התעבורה עם פעימות לב בשכבת האפליקציה.
חיבורים חצי-פתוחים הם דליפות משאבים שקטות. הם לא מכריזים על עצמם. הם פשוט מצטברים עד שמשהו מתקלקל. Keep-alive הוא הדרך שבה מוצאים אותם לפני שהם מוצאים אותך.
שאלות נפוצות על TCP Keep-Alive
האם הפעלת TCP keep-alive משפיעה על הביצועים?
במינימום. הבדיקות קטנות — רק כותרות TCP — ונשלחות רק בתקופות חוסר פעילות. לרוב האפליקציות, העומס זניח. הדאגה מתעוררת בקנה מידה: אלפי חיבורים לא-פעילים אומרים אלפי בדיקות תקופתיות. גם אז, רוחב הפס הנצרך בדרך כלל זניח בהשוואה לתעבורת האפליקציה הממשית.
מדוע TCP לא מפעיל keep-alive כברירת מחדל?
מסיבות היסטוריות ועקרון ההפתעה המינימלית. Keep-alive יכול לסיים חיבורים שאולי היו שורדים תקלות רשת חולפות. אפליקציות מסוימות מעדיפות לטפל בזיהוי כשלים בעצמן. ברירת המחדל השמרנית (כבוי, עם טיימרים ארוכים אם מופעל) מונעת התנהגות בלתי צפויה לאפליקציות שלא בחרו בכך במפורש.
כיצד מפעילים TCP keep-alive באפליקציה?
הגדר את אפשרות השקע SO_KEEPALIVE כדי להפעיל אותה, ואז קבע את התזמון עם TCP_KEEPIDLE (זמן לפני הבדיקה הראשונה), TCP_KEEPINTVL (מרווח בין בדיקות), ו-TCP_KEEPCNT (מספר בדיקות כושלות לפני הכרזת מוות). רוב שפות התכנות ומסגרות העבודה חושפות אלה דרך ממשקי ה-API של השקעים. לספריות חיבורים מסוימות ול-ORM יש אפשרויות תצורה ברמה גבוהה יותר.
האם TCP keep-alive יכול לזהות קריסת תהליך על המחשב המרוחק?
כן ולא. אם התהליך קורס אך המחשב נשאר פעיל, הליבה שולחת חבילת RST כשבדיקות מגיעות לחיבור שכבר לא קיים — הצד שלך לומד על כך מיד. אם המחשב כולו קורס או מאבד קישוריות רשת, בדיקות keep-alive אינן נענות ובסופו של דבר מפעילות פסק זמן. המקרה הראשון מהיר; השני לוקח כפי שתזמון הבדיקה שלך מאפשר.
האם להשתמש ב-TCP keep-alive או בפעימות לב של אפליקציה?
שניהם. TCP keep-alive תופס כשלים ברמת הרשת בזול ואוטומטית. פעימות לב של אפליקציה מאמתות פונקציונליות מקצה לקצה — שהאפליקציה שלך יכולה לבצע עבודה שימושית בפועל, לא רק שהליבה מגיבה לבדיקות. הם משלימים זה את זה: keep-alive כרשת ביטחון, פעימות לב כבדיקת בריאות.
האם דף זה היה מועיל?