יש לכם אתר אינטרנט שמתארח ב – IIS6 ונמצא מאחורי NLB והדפים שלכם לפעמים עולים לאט ולפעמים יותר מהר ?!
יכולות להיות מספר סיבות להתנהגות (מעצבנת) שכזו. אני רוצה לדבר כאן על גורם אחד חמקמק…
(ממליץ לקרוא פוסט קודם שעוסק בנושא של caching ל- static contents).
ETag
אז מה זה Etag?
בקצרה – חלק מפרוטוקול HTTP. השרת מייצר ETag Header שאמור לייצג “גרסה” של ה- resource שאותו הוא מספק (בד”כ רלוונטי יותר ל- static contents – תמונות, JS וכיו”ב) והדפדפן משתמש ב- Header הזה לבדיקת caching.
ה”גרסה” של resource, בד”כ, מיוצגת ע”י תאריך עדכון של ה- resource.
אז איפה הבעייה?
נניח שיש לי תצורה של שני שרתי IIS מאחורי NLB. אני מבצע request לדף – page1.aspx וה- NLB מפנה אותי לשרת א’. בתוך הדף יש “קבצים” מקושרים – תמונות, JS וכו’. הדפדפן מוריד גם אותם משרת א’ ושם עותק ב- cache המקומי.
בפעם הבאה שהדפדפן מבקש את הדף page1.aspx הוא צריך שוב את ה”קבצים” המקושרים, הוא בודק האם הם קיימים ב- cache המקומי שלו וכשהוא פונה לשרת לקבל את הקובץ המקושר, הוא מוסיף ב- request את ה – ETag של הקובץ מה – cache. השרת בודק האם ה – Etag שנשלח ב – request זהה ל – Etag השייך ל- resource המתאים על השרת.
אם זהה – מחזיר HTTP 304, אחרת, מחזיר לדפדפן את הקובץ המלא.
בהנחה שיש לי שרת אחד, אחרי הפנייה הראשונה לדף, כל שאר ה – static content יגיע מה – cache, שכן השרת יזהה שה – ETag זהה.
טוב, אז מה הבעייה? הרי אם שמתי לדוגמא, את אותו קובץ תמונה על שני שרתים, ה-ETag יהיה זהה בשניהם, שהרי לשניהם אותו תאריך עדכון אחרון…
אז ככה…
ב – IIS הערך של ה – ETag בנוי משני חלקים בערך במבנה הבא: ComputedValue:ChangeNumber.
ComputedValue – זה הערך שהשרת מייצר לפי תאריך עדכון אחרון.
ChangeNumber – זהו ערך קבוע.
OK, ובכל זאת איפה הבעייה?
ב – IIS6, הערך של ה – ChangeNumber לא בהכרח זהה בכל שרת…, לכן, הערך של ה – ETag כולו, עלול להיות שונה עבור אותו קובץ בשני שרתים שמאחורי NLB אחד. כך שלמרות שלכאורה ה- resource שנמצא ב – cahce של הדפדפן עדכני, אם הערך הקיים ב – cache שייך לקובץ משרת א’, אם ה – NLB מפנה אותי ב – request אחר לשרת ב’, במקום לקבל את הקובץ מה – cache, הקובץ ירד מהשרת.
ולכן, כאשר ה – NLB מפנה אותי לשרת אחר, אני עלול להרגיש שהדף יורד לאט יותר ואילו כאשר הוא מפנה אותי לשרת שהייתי בו קודם, הדפים יורדים מהר יותר.
אז אחרי שהבנו (אני מקווה) את מקור הבעייה, בואו נדבר על פתרונות:
1. sticky session – פותר את הבעייה ברמת session. יתכן שבהתחברות הבאה, הדפדפן יופנה לשרת אחר ושוב יצטרך להוריד את הקבצים הסטטים.
2. לעבור ל – IIS7 – למה? ב – IIS7, כברירת מחדל, הערך של ה – ChangeNumber הוא 0. ומאחר ואני מניח שאף אחד לא מתעסק עם הערך הזה, ניתן להניח שכל השרתים ייצרו את אותו ETag לאותו דף.
3. לעדכן בכל שרתי ה – IIS6 את הערך של ה – ChangeNumber לערך זהה. איך? ככה.
יש לכם בעיות אחרות/נוספות עם caching? עם ביצועים באפליקציה שלכם? אתגרו אותי.
בהצלחה,
טל
שירותי MCS רלוונטיים
· (PDF) שירות ניתוח פערים ושיפור ביצועים
· (PDF) שירות תכנון וניתוח בדיקות ביצועים
· (PDF) סדנת פיתוח מערכות מונחה ביצועים