איך חיבורי Keep-Alive מפחיתים את העומס שמאט כל בקשה

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

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

מה בעצם קורה בלי Keep-Alive

בלי חיבורים מתמשכים, כל בקשה עוברת את התהליך הבא:

  • לחיצת יד TCP (SYN, SYN-ACK, ACK)
  • לחיצת יד TLS אם אתם ב-HTTPS (עוד כמה סבבי תקשורת)
  • הבקשה והתגובה בפועל של HTTP
  • סגירת החיבור

בחיבור מהיר, זה יכול להוסיף 50-150 מילישניות לכל בקשה. ברשתות סלולריות או בחיבורים למרחקים ארוכים, זה יכול בקלות להוסיף 300 מילישניות או יותר. עכשיו תכפילו את זה בכל קובץ CSS, קובץ JavaScript, תמונה וגופן שהעמוד שלכם טוען. עמוד עם 40 משאבים ובלי חיבורים מתמשכים יכול לאבד מספר שניות רק על הקמת חיבורים, לפני שבכלל הגיע בייט אחד של תוכן אמיתי.

למה זה חשוב ל-TTFB

Time to First Byte מקבל הרבה תשומת לב כמדד ביצועים, אבל בעצם הוא מודד כמה מהר השרת שלכם מגיב ברגע שהחיבור כבר נוצר. אם השרת שלכם כל הזמן הורס ובונה מחדש חיבורים, אתם מוסיפים השהיה נסתרת שמדידות TTFB לא תמיד תופסות בצורה נקייה, במיוחד בעמודים עם הרבה משאבי משנה. כתבנו על זה בהרחבה בלמה זמן ה-TTFB שלכם עולה לכם בהמרות ואיך לתקן את זה.

איך Keep-Alive פותר את זה

חיבור Keep-Alive אומר לשרת וללקוח: אל תסגרו את חיבור ה-TCP הזה אחרי התגובה, השאירו אותו פתוח כדי שנוכל להשתמש בו שוב לבקשה הבאה. במקום לחיצת יד חדשה לכל קובץ, הדפדפן שולח כמה בקשות באותו צינור.

ב-HTTP/1.1, Keep-Alive הוא בעצם התנהגות ברירת המחדל. הכותרת נראית כך:

Connection: keep-alive
Keep-Alive: timeout=5, max=100

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

הגדרת Keep-Alive ב-Nginx

הנה נקודת התחלה סבירה עבור קונפיגורציית Nginx:

keepalive_timeout 15;
keepalive_requests 1000;

  • keepalive_timeout קובע כמה זמן השרת ממתין לבקשה נוספת באותו חיבור לפני שהוא סוגר אותו.
  • keepalive_requests קובע את המספר המרבי של בקשות המותרות לכל חיבור.

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

גם Keep-Alive במעלה הזרם (upstream) חשוב

רוב האנשים חושבים על Keep-Alive רק בין הדפדפן לשרת הקצה. אבל אם האפליקציה שלכם יושבת מאחורי reverse proxy, למשל Nginx שמדבר עם PHP-FPM או backend של Node.js, גם החיבור בין ה-proxy לאפליקציה שלכם נהנה מכך שהוא נשאר פתוח.

הנה קונפיגורציית upstream טיפוסית שמאפשרת את זה:

upstream backend {
  server 127.0.0.1:8080;
  keepalive 32;
}

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

חידוש session של TLS מוסיף עוד שכבה

אם אתם ב-HTTPS (וכדאי שתהיו), חידוש session של TLS פועל יחד עם Keep-Alive כדי לחסוך עלויות חוזרות של לחיצות יד. הגדרת ssl_session_cache ו-ssl_session_timeout מאפשרת ללקוחות חוזרים לדלג על משא ומתן TLS מלא בחיבור מחדש. זו תוספת קטנה, אבל היא מצטברת יחד עם שימוש חוזר בחיבורים כדי לחסוך עוד מילישניות. אם לא בדקתם את הגדרות ה-SSL שלכם בזמן האחרון, סקירת ניהול תעודות SSL שלנו היא מקום טוב לבדוק את הקונפיגורציה הנוכחית שלכם.

מדידת ההבדל

אתם לא צריכים לנחש אם Keep-Alive עובד. כמה דרכים לבדוק:

  • פתחו את לשונית ה-Network בדפדפן שלכם והסתכלו על העמודה "Connection ID", בקשות שחולקות ID משתמשות מחדש באותו חיבור.
  • השתמשו ב-curl -v וחפשו את הכותרת "Connection" בתגובה.
  • הריצו בדיקת waterfall ב-WebPageTest ובדקו שלבים חוזרים של DNS/חיבור/SSL בבקשות לאותו host, מה שמסמן שחיבורים לא נעשה בהם שימוש חוזר.

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

איפה אחסון מנוהל נכנס לתמונה

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

לסיכום

חיבורי Keep-Alive הם אחד מאותם פרטים ברמה נמוכה שלא מופיעים ישירות בציון Lighthouse, אבל הם מצטברים על פני כל בקשה בודדת שהעמוד שלכם עושה. אם אתם מנסים להשיג הפחתת זמן תגובת שרת, בדקו את הגדרות ה-Keep-Alive שלכם לפני שאתם פונים למשהו מסובך יותר. ודאו שערכי ה-timeout וה-max requests שלכם הגיוניים עבור דפוס התעבורה שלכם, בדקו שגם החיבורים ב-upstream שלכם מתמשכים, וצרפו לזה caching תקין של session TLS. זה שינוי קונפיגורציה קטן עם השפעה גדולה מאוד על זמני טעינה בעולם האמיתי.