סדרת דרמה על האצת תמונות: איך תיקנו שני אתרים מ“אפשר לגשת” ל“באמת מהיר”
נתחיל עם השורה התחתונה:
d3vו-aiyaיכולים עכשיו לעבוד בצורה יציבה דרך שרשרת Cloudflare + R2.- גם תמונות ישנות וגם תמונות חדשות נפתחות.
- אפשר לגבות ואז לנקות העלאות היסטוריות מקומיות, ולא להיות כבולים יותר לדיסק.
ועכשיו התהליך:
מערכה ראשונה: חשבנו שזו בעיית רשת, ובסוף התברר שזה “עקיפה מערכתית”
בהתחלה כולם הסתכלו על ההשהיה:
- מסין לסינגפור,
pingנראה בערך 300ms. - SSH נתקע עד שכמעט מאבדים תקווה.
- אתר העסק, כי השתמש ב-CF reverse proxy ובדומיין מועדף, הרגיש עוד בסדר.
ואז מגיעה שאלת הנשמה:
“אפשר גם להאיץ SSH ככה?”
התשובה היא: אפשר להתעסק עם זה, אבל זו לא אותה השיטה שבה מאיצים אתר HTTP שאפשר פשוט להעתיק אחד-לאחד. בהמשך צמצמנו את הפוקוס קודם כול לשרשרת התמונות, כי זה החלק שהמשתמשים באמת מרגישים.
מערכה שנייה: 404 לא אומר שהאובייקט נעלם, אלא שהחזרה למקור חזרה לבית הלא נכון
הבור הכי קלאסי:
- הקישור
uploads.aiya.de5.net/...נפתח ומחזיר404. - אבל כשנכנסים ל-R2 ועושים
head_object, האובייקט בבירור שם.
מה זה אומר?
זה אומר ש“שכבת האחסון בסדר, שכבת התעבורה לא בסדר”.
בסוף איתרנו:
- ה-hostname המותאם אישית (SaaS custom hostname) של
uploads.aiyaהצביע לזמן מה על כניסה של bucket אחר. - התאמת Host/SNI בחזרה למקור וב-Nginx גם חוותה אי-התאמות.
- ובנוסף Cloudflare שמר במטמון את ה-
404הישן, כך שזה נראה כאילו “תיקנו אבל לא באמת תיקנו”.
סיכום במשפט אחד:
האובייקט בתוך ה-bucket לא מבטיח שהמשתמש יכול לקבל אותו.
מערכה שלישית: אתה חושב שזה DNS, אבל בפועל זו “תיאום של הגדרות רב-שכבתיות”
למעשה בשרשרת הזו יש ארבע שכבות:
- ניתוב לפי קווים ב-Huawei Cloud (ביתי/חוץ-ארץ)
- Cloudflare SaaS custom hostname
- תזמור חזרה למקור ב-Nginx
- דומיין public/managed/custom של ה-bucket ב-R2
כל שכבה שבה ההגדרה “נראית די דומה” יכולה לנתב את הבקשה ל-bucket הלא נכון או ל-Host הלא נכון.
לכן שיטת התיקון שלנו לא הייתה “לשנות משהו על סמך תחושת בטן”, אלא:
- קודם לבצע גיבוי.
- אחר כך לאמת שכבה-שכבה (DNS → SaaS → origin → bucket object).
- בכל שכבה להשתמש ב-
curl -Iוב-HEADשל האובייקט לאימות עובדתי.
מערכה רביעית: למה פוסטים ישנים תמיד “נראים כאילו לא השתנה כלום”
הרבה אנשים נשברים כאן:
“אבל כבר עברתי ל-S3/R2, למה פוסטים ישנים עדיין הם aiya.de5.net/uploads/...?”
כי ב-Discourse יש שני עולמות:
raw: הטקסט המקורי של הפוסט (נפוץupload://...)cooked: ה-HTML אחרי רינדור (img/src/srcsetנמצא כאן)
posts:rebake מחשב מחדש את cooked מתוך raw.
אז אם שינית רק את cooked, rebake עתידי יכול “להחזיר אותך לברירת המחדל”.
זה לא כשל של R2, זו התנהגות רגילה של מדיניות הרינדור.
מערכה חמישית: מה בעצם עשינו הפעם
בסוף מה שנחת בפועל:
- תיקון החזרה למקור של
uploads.aiyaאל ה-bucket הנכון. - ניקוי מטמון 404 ישן.
- סנכרון אובייקטים היסטוריים חסרים ל-R2.
- החלפה מרוכזת של
cookedבפוסטים ישנים ל-https://uploads.aiya.de5.net/...(כדי שגם התצוגה תהיה אחידה).
תוצאה:
- כל התמונות השבורות שהבאתם חזרו לעבוד.
- תמונות חדשות וישנות כולן פוגעות בשרשרת ההאצה.
“רשימת קיצורי דרך” למי שיבוא אחר כך
- אל תחשוד קודם שהאובייקט אבד—קודם תעשה
HEAD object. - עם
404קודם תבדוק מצב מטמון:cf-cache-status: HITיכול להיות פשוט מטמון ישן. - אחרי שינוי מקור ב-SaaS custom hostname, חובה לאמת התאמת Host בפועל.
- לשנות שכבה אחת בכל פעם, לאמת שכבה-שכבה—לא לשנות כמה דברים יחד ואז להתפלל.
- קודם לגבות ואז להגר, במיוחד את
/shared/uploads/*. - לכתוב את “מסלול הרולבאק” חשוב יותר מ“הפעם סוף סוף הצליח”.
ביצת פסחא: התחושה הכי אמיתית הפעם
זו לא בעיה של “רשומת DNS אחת שלא מולאה נכון”.
זו “ארכיטקטורה חצי-ארגונית שמורכבת מתוכנית חינמית”:
- אפשר לחסוך כסף, אפשר להאיץ, אפשר לגרום לזה לרוץ;
- אבל צריך להביא סבלנות של SRE, ולהסכים שהיא תחנך אותך בתנאי קצה.
גם אם זו התעסקות, בסוף זה היה שווה:
- העלות לא התפוצצה;
- המהירות עלתה;
- והארכיטקטורה סוף סוף עברה מ“עובד” ל“ניתן להסבר, ניתן לתחזוקה”.
מקווה שהמאמר הזה יעזור לבאים אחריכם לישון כמה לילות יותר.