פורום הסקופים של רוטר – יכול להיטען מהר יותר?

עריכה 03/06/2013: שנה אחרי שכתבתי את הפוסט, חל שיפור עצום במערכות של רוטר והיום האתר עובד מהר יותר ונכון להיום, הפוסט הזה לא רלוונטי לאתר רוטר. 

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

הפורום משתמש בסקריפט DC Forum, בגירסת ה-PERL (יש גם גירסת PHP), זה סקריפט מיושן (אם כי בעבר היתרון שלו על פורמים אחרים היה שאת הפוסטים עצמם הסקריפט שומר כ-HTML ללא קריאות ל-SQL וכו'), עם לא מעט באגים (פוסטים מאוד מבוקשים עם הרבה פעולות כתיבה פשוט קורסים ונעלמים), למרות זאת, המפעיל של האתר, לא ממהר להחליף את המערכת/עיצוב ומסביר כי: "מה שעובד לא מחליפים."

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

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

Time To First Byte:

ה-TTFB של עמוד הסקופים לאורחים עומד על 900 מילישנייה, הזמן הזה מורכב מ:

  • Apache מנתח את הבקשה.
  • מפעיל פרוסס perl.
  • הפרוסס מעבד את הקובץ ע"פ הפרמטרים שהתקבלו ומעביר את הפלט ל-Apache.
  • Apache מעביר את הפלט לגולש.

אני מניח שעיקר הזמן מושקע בשליפת הפוסטים, אין טעם לבצע את הפעולה כל פעם מחדש (במיוחד כשיש רגעים שיש 800 בקשות בשנייה), אפשר לייצא את פלט הפוסטים לקובץ סטטי ולעדכנו כל 2 שניות למשתמשים רשומים וליצור קובץ נוסף המכיל את כל העמוד לאורחים, ולעדכנו כל 3 שניות.

KeepAlive:

כתבתי על הפונקציה הזו בעבר, בקצרה, הפונקציה מאפשרת להשתמש באותו החיבור בין הגולש לשרת כדי להוריד קבצים נוספים, ברוטר, הפונקציה הזו מבוטלת. לכן, כל פעם שגולש מבקש את העמוד הראשי הוא יוצר 51 חיבורים לשרת, 51 פרוססים של Apache. במידה ורוטר יפעילו KeepAlive בשרתים שלהם, גולש ב-IE8 יפתח 6 חיבורים בלבד להורדת האלמנטים. 45 פרוססים פחות.

Gzip (דחיסת HTTP):

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

המשקל של פורום הסקופים עומד בממוצע על 80KB, במידה וה-Gzip יופעל, התעבורה בין השרת לגולש תעמוד על 12KB, חסכון עצום של 68KB.

הנה השוואה בין זמן טעינת הפורום עם אופטמזציה שלי למול הפורום:

מקרא:

כתום – יצירת חיבור.

ירוק – TTFB.

כחול – זמן הורדה.

הורדת הקובץ עם דחיסה: 80 מילישנייה.

הורדת הקובץ ללא דחיסה: 500 מילישנייה.

סה"כ שיפור: 420 מילישנייה בממוצע.

Cookieless domain:

כשגולש מבקש את העמוד הראשי ה-Header כולל 2 שורות Set-Cookie, מעתה, בכל בקשה נוספת לדומיין rotter.net, הגולש ישלח את הפלט Set-Cookie שהתקבלו בבקשה הראשונה, מדובר בתעבורה מיותרת לכל בקשות הקבצים הסטטים. אם נשתמש בכתובת אחרת לטעינת האלמנטים (או נגביל את ה-Cookie ליעד ספציפי), נחסוך תעבורה ונקבל זמן טעינה מהיר יותר.

Cache-Control:

כתבתי על Cache-Control בעבר, הפונקציה הזו מאפשרת לשרת להודיע לדפדפן בעת בקשת קובץ, לשמור את הקובץ במחשב ולא להוריד אותו שוב מהשרת למשך X שניות (יום/שבוע/חודש/שנה – תלוי מתי הקובץ מתחדש).

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

השוואה בין רוטר לאופטמזציה שלי:

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

*** בעת ביצוע ההשוואה בוטלו כל הפירסומות.

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

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

פורסם בקטגוריה כללי | 5 תגובות

פרצת אבטחה בפורטל דרושים Drushim.co.il – תוקן

בפורטל דרושים (Drushim.co.il) מאפשרים להירשם באמצעות האיימיל ולקבל לתיבה כל יום הודעות עם הצעות עבודה, במייל שמתקבל, יש קישור לעריכת העדפות אישיות (מיקום, סוג עבודה וכו') – הבעיה – הכתובת לא מוגנת באמצעות אסימון ולכן – כל אחד יכול לראות את ההעדפות של כל אחד, ואף לשנותם.

צירפתי צילום מסך (הפרטים מטושטשים):

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

http://www.drushim.co.il/smartalerts.aspx?arid=xxxxx

במקום האיקסים – הציבו מספר בין 6 ספרות.

איך פותרים את התקלה הזו? באמצעות אסימון,

אפשר לקחת את כתובת המייל של המשתמש, יחד עם תאריך ההרשמה של המשתמש לבצע hash md5 ולהוסיף ל-URL. ללא אסימון או עם אסימון שגוי תתקבל הודעת שגיאה.

עדכון: מיד לאחר פירסום הפוסט, פניתי לירון כהן מ-Drushim.co.il, סיפרתי לו על הפרצה והוא ביקש ממני להוריד את הפוסט עד אשר היא תתוקן, הפרצה תוקנה במהירות ועל כן, כל הכבוד!

פורסם בקטגוריה כללי | להגיב

חילוץ טבלה ממסד נתונים

אחד הלקוחות שלי ביצע לפני מספר ימים טעות קריטית במערכת שלו ומחק טבלה ש-90% מהאתר תלוי בה לעבודה שוטפת. התוצאה כמובן – שגיאה 500 (שגיאת שרת פנימית).

הוא עידכן אותי בתקלה ובדקתי את קובץ הגיבוי האחרון (חצי שעה לפני הטעות) לשמחתו הגיבוי התקין, לצערי הגיבוי שקל 10Gb.

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

השימוש בסקריפט מאוד פשוט:

perl extract_sql.pl -t table_to_export -r mysql_backup.sql > mysql_backup_table.sql

table_to_export – הטבלה לשחזור

mysql_backup.sql – קובץ הגיבוי המקורי

הסימן < – את כל הפלט (במקרה הזה – הטבלה) תכתוב לקובץ בשם mysql_backup_table.sql

mysql_backup_table.sql – הקובץ שאליו תיכתב הטבלה לשחזור

5 דקות לאחר הטעות הקריטית האתר היה שוב באוויר.

פורסם בקטגוריה לינוקס | עם התגים , , | להגיב

מחשבות על max-age ושרתי cache

נניח שיש לנו קובץ נתונים שמתעדכן כל יום ראשון ב-8 בבוקר, אנו נוסיף ל-Http header:
max-age: $cache-time

כאשר $cache-time = ה-timestamp ביום ראשון בשעה 8 פחות ה-timestamp ברגע זה.

הפתרון הזה יעבוד בצורה מעולה, אבל מה יקרה אם נשתמש בשרת cache/cdn/proxy (קאש) כדי להגיש את הקובץ?

שרתי קאש יודעים לקרוא את ה-Headers ולעדכן את התוכן בהתאם, כלומר שרת קאש קורא קובץ עם max-age של שבוע (604800 שניות), ישמור את הקובץ למשך שבוע אלא אם הוגדר אחרת.

הבעיה במקרה הזה, אם לדוגמא שרת הקאש שמר את הקובץ ביום שני, ה-max-age עומד על 6 ימים קדימה. כאשר גולש יגש לקובץ ביום שבת, הוא יקבל את אותו ה-Header המקורי מיום שני. כלומר, הדפדפן של הגולש ישמור את הקובץ עד יום שישי הקרוב. כאשר הקובץ בשרת מתעדכן ביום ראשון הקרוב – התוצאה: 5 ימים בהם הגולש צופה בנתונים לא עדכניים.

המצב המתואר לא יקרה ב-Varnish, משום שב-Varnish משתמשים ב-Age header (מיישם את אותו עיקרון $cache-time אך בצורה שונה).

ב-nginx אפשר להימנע מהמצב המתואר למעלה ע"י שימוש מותאם אישית (באמצעות location) ב-proxy_cache_valid המגדיר ל-nginx כמה זמן לשמור על הקובץ בקאש.

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

עד הפעם הבאה.
אבי.

פורסם בקטגוריה לינוקס | להגיב

ערים מנותקות מהאינטרנט – איך זה נראה בגרף?

עד לפני כשעה הייתה תקלה בבזק בינלאומי,

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

ככה זה נראה בגרף של IIX (צומת האינטרנט הישראלי):

פורסם בקטגוריה כללי | 3 תגובות

Cdn.co.il – "נחטף" בהצלחה

בהמשך לפוסט הקודם שלי על חטיפת דומיינים, רכש חדש מהלילה, Cdn.co.il,

אחת מראשי התיבות של Cdn היא Content Delivery Network, ויש מס' חברות בארץ שעוסקות בתחום הזה, כמו קוטנדו, מטריקס, Castup, GNS ועוד.

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

פורסם בקטגוריה כללי | להגיב

פלאפון – האינטרנט הכי מהיר גם בביטורנט

מצ"ב תמונת מסך, הורדה של קובץ של 109 מגה באמצעות ביטרונט, מהירות ההורדה עמדה על 550Kb~, באמצעות מודם סלולרי באיזור המרכז, שאפו.

פורסם בקטגוריה כללי | להגיב

איך ״לעבוד״ על אפליקציות

בתקופה האחרונה יש בהמון אפליקציות אפשרות לקנות פריטים בתשלום במקום להשקיע מאמץ במשחק.
בחלק מהאפליקציות יש אפשרות להמתין X שעות בתמורה לתוספת ניקוד/כוח וכו׳.

אני רוצה להביא דוגמא לאפליקצית BlackJack, לאחר שנגמרו הזיטונים תקבל 100 זיטונים על כל שעה שתחכה (עד 17 שעות).

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

2. נכנס להגדרות מערכת. ונשנה את התאריך לעתיד.
20120331-230634.jpg

3. נחזור לשחק עם 1700 זיטונים.

20120331-230806.jpg

4. כשסיימנו לשחק. נשנה את התאריך בחזרה.

קטע זה נכתב מהאייפד באמצעות אפליקצית wordpress.

פורסם בקטגוריה כללי | עם התגים , | להגיב

להימנע מ-304 Get request – איך להפחית עומס מהשרת

תשובה 304 לבקשת GET REQUEST, משמעותה שהאלמנט (CSS/JS וכו') לא השתנה ואין טעם להורידו שוב, אסביר איך זה עובד:

כאשר גולש נכנס לאתר אינטרנט, הדפדפן מוריד את כל האלמנטים המרכיבים אותו  ושומר אותם במחשב גם אם לא מופיע Cache-Control ב-Header. כאשר הגולש יכנס לאתר בפעם השנייה (או ימשיך לאחד העמודים בתוך האתר), הדפדפן יוריד ויטען את העמוד כאשר אלמנטים שהורדו בפעם הקודמת והכילו Cache-Control ב-Header ייטענו ישירות מהמחשב. אלמנטים שהורדו ללא Cache-Control (או שפג תוקפו של max-age) יידרשו מהדפדפן לפנות לשרת ולאמת (ע"י השוואת תאריך Last-Modified מול השרת) שהקובץ לא השתנה, במידה ולא, השרת יחזיר תשובה: (304 Not Modified).

כדי להציג מה ההשפעה של חוסר בהגדרת Cache-Control, הרצתי בדיקה ב-Webpagetest, על הפורום iatraf.co.il, בחרתי בכוונה בפורום מאחר ומס' הצפיות הממוצע של פורום עומד על 5 עמודים לגולש והגולשים חוזרים מספר פעמים ביום לאתר, לכן ול-Cache-Control יש השפעה חשובה על איכות הגלישה באתר. (למעלה מ-1.5 שניה פחות לעמוד)

לדף הבית יש 56 בקשות 304, מתוכם לפחות 30 בקשות גם בעמודי ההודעות בפורום (קבצי CSS, JS, PNG). את ההשפעה ב-Frontend אנחנו כבר יודעים, אבל מה ההשפעה ב-Backend? (אנו רואים שבאתר זה ה-TTFB לדף הבית עומד על 1.65)

כאשר הדפדפן מבקש מהשרת אלמנט שכבר קיים במחשב ללא Cache-Control הנה התהליכים שמתבצעים:

  • הדפדפן שולח GET REQUEST לשרת.
  • ברוב המקרים ה-GET REQUEST תכלול גם עוגייה, בזבוז מיותר של רוחב פס (בעלי אתרים בעלי עוגיות, תעבירו את כל התוכן הסטטי לסאב-דומיין).
  • השרת (Apache), מקצה מקום לדפדפן ומעבד את הבקשה.
  • בשלב הזה הוא פותח את קובץ ה-htaccess, מעבד את החוקים הכתובים בו, ומחפש את הקובץ. (בשלב הזה Apache מריץ לפחות 10 הוראות stat כדי לקבל את htaccess ואת מצב הקובץ).
  • Apache מחזיר 304 לדפדפן וממשיך לקובץ הבא (KeepAlive on) או סוגר את התקשורת (KeepAlive off).
הזמן הממוצע שכל התהליך הזה לוקח הוא בין 0.1-0.2 שניה בשרת שאינו עמוס, כל התהליך הזה מיותר לגמרי משום ש: 
  • הוא מאט את טעינת האתר. 
  • הוא מנפח את רוחב הפס – 0.2Kb בממוצע לכל בקשה.
  • הוא תופס מקום בשרת הווב (MaxClients). 
  • הוא מגדיל את העומס על ה-Hardisk. 

ערכתי בדיקה דומה על דף הבית בחמשת הפורמים הראשונים בגוגל (במילת החיפוש: "פורום"):

כל האתרים חוטאים בניהול שגוי של Cache-Control, ויכולים להאיץ את מהירות הגלישה של הגולשים תוך כדי חסכון בהוצאות התקשורת והשרתים.

עד הפעם הבאה, אבי.

לעוד חומרים בנושא האצת אתרים

פורסם בקטגוריה האצת אתרים | עם התגים , | 7 תגובות

מספר טיפים לבניית אתר מהיר

בשנים האחרונות האינטרנט התפתח ממש מהר, וכיום, גוגל פועלים להפיכת האינטרנט למהיר יותר ("Let's make the web faster"), הם גם הצהירו בעבר כי אתרים איטיים ידורגו מתחת לאתרים מהירים ובכלל, למי יש סבלנות לחכות יותר מ-2 שניות עד שעמוד נטען?

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

1. השתמשו ב-KeepAlive, פונקציה זו מאפשרת לקבל מס' בקשות רצופות בחיבור אחד מאשר יצירת חיבור חדש כל פעם:

נניח שאנחנו פותחים דף והוא מורכב מ:

  • קובץ css.
  • קובץ js.
  • 5 קבצי jpg.

הדפדפן מבצע בסה"כ 8 בקשות GET (דיי דומה ל: אהלן שרת X, שמפעיל את אתר Y, תן לי את קובץ Z). במידה ו-KeepAlive מכובה, הדפדפן יסגור את החיבור אחרי כל בקשה ויפתח חיבור חדש לבקשה הבאה.

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

2. Expires Header – השרת מודיע לדפדפן עד מתי לשמור את הקובץ: 

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

זה אופציה מעולה לבעלי אתרים שמקבלים טראפיק ממשתמשים חוזרים, היא ממש מאיצה את טעינת האתר מהפעם ה-2 והלאה ובנוסף ניתן לחסוך המון כסף בהוצאות על שרתים/תעבורה ע"י שימוש באופציה הזו.

3. CDN – Content Delivery Network – שימוש ברשת להפצת תוכן: 

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

הרעיון במקור נועד למנוע "פקקים" באינטרנט, בתקופה שהאינטרנט היה בחיתוליו והעברה של קובץ בין יבשות היה בעייתית. כיום רוב הבעיות האלה נפתרו (אם כי עדיין יש packet loss בין ישראל בארה"ב) והשימוש ב-CDN הפך מבלתי נמנע לאפשרי.

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

מתי כן להשתמש ב-CDN? אם יש לכם:

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

ניקח לדוגמא חברת קוסמטיקה ישראלית שפועלת בשוק הבינלאומי שמארחת את האתר שלה בישראל. אתר החברה (23 קבצים ששוקלים 450K) נטען תוך 4.5 שניות בישראל, 6.7 שניות ברוסיה (שוק חשוב לחברה) ו-7.1 שניות לארה"ב (שיקגו).

לאחר ביצוע אופטמציה לקוד האתר (Css sprites, JS/CSS compress & combine) זמן הגישה בישראל ירד ל-2.3 שניות בממוצע. גם ברוסיה ובארה"ב הורגשה טעינה מהירה יותר, אך עדיין יש מקום לשיפור המהירות בחו"ל, החברה העבירה את האתר ל-CDN של חברת AKAMAI וכיום זמן הטעינה הממוצע של האתר בארה"ב רוסיה וישראל עומד על 2.1 שניות בממוצע.

4. קאשינג לעמודים שמשתנים שמתעדכנים מדי 30 שניות ומעלה:

בעמודים עמוסי תוכן יש לפעמים שאילתות SQL מורכבות שמאטות את תהליך יצירת העמוד (וטעינת העמוד מתעכבת הרבה יותר).

מאחר והתוכן אינו מתעדכן באופן מיידי, ניתן ליצור משימה מתוזמנת שתיצור עמוד סטטי מדי X שניות (תלוי בתדירות של העמוד).

אני אתן דוגמא לשיפור ביצועים: לאחד הלקוחות שלי יש סקריפט שמפעיל מס' אתרי ווידאו, בעמוד הקטגוריות, ה-TTFB עמד על 3.5 שניות באופן קבוע, לאחר יצירת משימה מתוזמנת מדי 5 דקות ה-TTFB צנח ל-0.08 שניה.

לעוד חומרים בנושא האצת אתרים

פורסם בקטגוריה האצת אתרים, כללי | להגיב