למה REST API לנתוני קריפטו לא עומד בעומס השוק
שכבת הגישה לנתוני שוק מתוכננת ראשונה, והיא נשברת ראשונה. REST API לנתוני קריפטו עובד לפי סכמת "בקשה — תשובה": האפליקציה פונה למקור עבור כל מחיר וממתינה לתשובה. כל עוד השוק רגוע, הסכמה נראית עובדת — זמני ההשהיה צפויים, ומספר הפניות גדל באופן לינארי יחד עם מספר המשתמשים.
בתנודתיות שיא התמונה משתנה בקפיצה. מגבלות הבקשות למקור נצרכות תוך שניות, חלק מהפניות מקבל סירוב, ופסקי זמן תחת תנודתיות שיא הופכים לנורמה ולא לחריג נדיר. הלקוח עובר לניסיונות חוזרים, מוסיף עומס לשכבת הגישה וסוגר את המעגל: ככל שיש יותר חזרות, כך פחות תשובות מוצלחות מגיעות למוצר.
בהמשך מופיעים מחירים מיושנים בתשובה. אם שכבת הגישה מחזירה ערך מהמטמון בלי לסמן את גילו, האפליקציה מציגה מחיר שכבר אינו קיים בשוק — ועבור מסחר או חישובים זה גרוע יותר משגיאה כנה.
מתווסף גם חוסר סנכרון: חלק מהכלים מגיעים בערוץ אחד, חלק בערוץ אחר, הטריות שלהם שונה, ואיחוד הכול לתמונת שוק אחת הופך למשימה בפני עצמה.
בסופו של דבר העומס על שכבת הגישה גדל לא ממספר המשתמשים, אלא מהארכיטקטורה עצמה של הפנייה למקור: הוספת שרתים לא מסירה את הבעיה, כי הצוואר מבקבוק נמצא במגבלות החיצוניות של המקור. להלן נפרק כיצד זה נסגר.
מה משתנה אחרי בנייה מחדש של שכבת הגישה לנתוני בלוקצ'יין
מהירות התגובה ויציבות תחת עומס שיא
הבנייה מחדש של שכבת הגישה מתחילה בהפרדת הזרמים: נתוני שוק — מחירים, ספר פקודות, עסקאות — נקראים ממטמון מעל Redis עם זמן חיים קצר, ובקשות לרשת הבלוקצ'יין עוברות דרך תור עם הגבלה על פניות בו-זמניות לצומת.
מטמון של נתוני שוק מסיר את עיקר החזרות, ולכן זינוק בשעות תנודתיות גבוהה לא הופך לתור של לקוחות ממתינים. במדידות שלנו במערכות פעילות זמן התגובה לבקשות תדירות הצטמצם פי כמה, ושיעור השגיאות תחת עומס שיא נשאר בגבולות עשיריות האחוז.
בנפרד נסגר סוג הכשלים בגלל אי-זמינות של מקור חיצוני: בעת כשל של ספק הבקשה נענית מהחתך התקף האחרון, והמנויים מתחברים מחדש בעצמם. ההתאוששות אחרי כשל של מקור אורכת דקות במקום שעות של השבתה.
כמה עבודה ידנית יוצאת מהתהליכים
בעבר היציבות של שכבת הגישה נשענה על אדם: הוא עקב אחרי הפיגור של הצמתים, הפעיל מחדש זרמי נתונים, והצליב ידנית פערים בין המקור לבסיס הנתונים שלו. כעת הפעולות האלה מתוארות ככללים — בקרת פיגור, ניסיונות חוזרים עם השהיה גדלה, הצלבה אוטומטית של פערים והתראה רק בעת אנומליות.
הצמצום בפעולות ידניות ניכר בתורנויות: שעות של בדיקות שגרה בשבוע נעלמות. סכמת הגישה, כללי המטמון ונוהל ההתאוששות נשארים בתיעוד, ולכן התוצאה אינה תלויה במהנדס מסוים.
מצבי אספקת נתונים: סקר לפי דרישה, מנויי זרם, היברידי
פורמט האספקה נבחר לפי תדירות השינוי של הנתונים וכמה לקוחות קוראים אותם בו-זמנית. עבור היסטוריית עסקאות, אגרגטים לתקופה ודוחות, סקר לפי דרישה נותן עומס צפוי: הלקוח עצמו קובע את החלון והתדירות, וכשל של קריאה אחת לא משפיע על האחרות.
עבור מחירים, ספר פקודות וסטטוסי עסקאות נדרשים מנויי זרם — השרת מחזיר את השינוי מיד, בלי תקופת המתנה.
| אפשרות | מתי מתאים | מגבלות |
|---|---|---|
| סקר לפי דרישה | היסטוריה, דוחות, עדכונים נדירים | ההשהיה שווה לתקופת הסקר; בסקר תדיר גדל מספר הקריאות המיותרות |
| מנויי זרם | מחירים, ספר פקודות, סטטוסי עסקאות | הגבלה על מספר החיבורים; בעת ניתוק נדרשים מנוי מחדש והשלמת הנתונים שהוחמצו |
| סכמת אספקה היברידית | ממשק מסחר ואנליטיקה במוצר אחד | מורכבת יותר בהגדרה ובבדיקה, נדרש חוזה מפתחות אחיד בין הזרם לבקשה |
מתי סקר לפי דרישה זול יותר בתמיכה
סקר לפי דרישה מנצח במקומות שבהם הנתונים משתנים לאט יותר מפעם בכמה שניות: אין מצב חיבור ארוך-טווח, אין מנוי מחדש אחרי ניתוק, והדיבוג נעשה לפי לוגים רגילים של קריאות. התשובות נשמרות במטמון בצד השירות, ולכן שיא של בקשות מכמה לקוחות לא הופך לשיא של פניות למקור. ההשוואה בין מצבי קבלת הנתונים כאן חד-משמעית לטובת פשטות התחזוקה.
סכמה היברידית: נתונים חמים בזרם, היסטוריה לפי דרישה
סכמת אספקה היברידית מסירה את המגבלה העיקרית של המנויים: בזרם נשאר רק מה שמשתנה כרגע, והעומק וההיסטוריה עוברים לבקשות עם החזרה מדורגת לפי עמודים. הלקוח משלים את הקטע שהוחמץ אחרי חיבור מחדש בקריאה אחת, ולא קורא מחדש את כל הערוץ. כך הממשק נשאר מגיב, והעומס על האחסון — צפוי.
סדר העבודות: ביקורת בקשות, סכמה, הגדרה, בדיקה, מסירה
אנחנו מתקדמים בשלבים כך שכל צעד הבא נשען על נתונים מתועדים מהשלב הקודם, ולא על הנחות. תחילה אנחנו מפרקים את הפניות בפועל למקורות, אחר כך מתכננים את הסכמה, ורק לאחר מכן מגדירים מגבלות ותורים — אחרת הפרמטרים נבחרים באקראי ולא מחזיקים מעמד מול עומס השיא הראשון.
- ביקורת פניות: מתעדים לוג בקשות למקורות לתקופת עבודה — מי, מה ובאיזו תדירות מבקש, היכן יש כפילויות וקריאות סרק.
- סכמת אינטגרציה של מקורות: עבור כל סוג נתונים מגדירים מקור ראשי ומקור גיבוי, פורמט נרמול ועדיפות בעת פער בין ערכים.
- הגדרת מגבלות ותורים: מפזרים מכסות בין הצרכנים, קובעים חציצה לזינוקים וכלל התדרדרות כשהמקור עונה לאט או מחזיר שגיאות.
- בדיקת עומס: מריצים פרופיל הקרוב לשיא, מודדים את השהיית התגובה ואת שיעור הסירובים, ובודקים שהתורים מתרוקנים בלי גידול בהשהיה.
- מסירת המערכת: מוסרים קונפיגורציות, הרשאות, סכמה ונוהל תגובה לכשלים, ומפרקים יחד עם הצוות שלכם אירועים טיפוסיים.
מה בודקים בשלב הביקורת
כאן חשובות מדידות ולא מילים כלליות: מתעדים את התדירות והפרופיל של הבקשות לפי כל מקור, את המגבלות שלו ואת השהיית התגובה בפועל, ומסמנים נקודות כשל — מקור בלי גיבוי, מגבלה קשיחה בלי מרווח, היעדר ניסיונות חוזרים בעת ניתוק תקשורת. לפי הנתונים האלה מחשבים את המרווח במכסות ומחליטים היכן נדרשת חציצה והיכן מספיק מטמון מקומי.
מה נשאר אצל צוות הלקוח: קונפיגורציות, סכמות, נהלים
לידיים נמסר לא סט של הרשאות והסכמות בעל-פה, אלא מארז של ארטיפקטים שלפיו הצוות שלכם יכול בעצמו להעלות את השירות, לחבר מקור חדש ולפרק פער בנתונים בלי העזרה שלנו.
הרכב התיעוד הנמסר
- קונפיגורציות של שירותים: פרמטרים של סביבות, מגבלות בקשות, כללי חיבור מחדש של מנויים ופסקי זמן.
- סכמות של זרמי נתונים: המסלול מהמקור דרך הנרמול והמטמון ועד לנקודת המסירה, עם ציון מקומות אפשריים של אובדן וכפילויות.
- מטריצת הרשאות: אילו שירותים ותפקידים רשאים לגשת לאילו מתודות, מפתחות וזרמים, עם הפרדה בין קריאה לניהול.
- תיעוד ממשקים: תיאור מתודות REST וערוצי WebSocket, פורמטי שגיאות, מגבלות, דוגמאות לבקשות ולתשובות.
- מודל נתונים: פורמט אחיד לכלי, לזוג, לעסקה ולנר, וכללי איחוד נתונים מכמה מקורות.
- תיאור סביבת הבדיקה: כיצד להעלות סטנד ולשחזר אירוע על נתונים היסטוריים.
נהלים ותחומי אחריות
בנפרד נמסר נוהל עדכון מקורות: סדר הוספת מקור חדש, בדיקת תאימות הפורמט בסביבת הבדיקה ותנאי ההכללה בסביבת הייצור. שם גם מתעדים את גבול האחריות: מה מנטרת משמרת התורנות שלנו בתקופת הליווי, ומה עובר אליכם, כיצד מנוסחים שינויים בסכמת התשובה ולאן להסתכל בעת פער בין מחירים ממקורות שונים.
דוגמה ליישום: אגרגטור בורסאי — גידול בפניות בלי כשלים
הלקוח — אגרגטור בורסאי שמאחד מחירים וספר פקודות מעשרות פלטפורמות ומחזיר אותם לאפליקציות חיצוניות דרך REST API ציבורי וזרם WebSocket. המערכת לא הייתה מוכנה לגידול בקהל: ניסו להרחיב אותה בעת כתיבת מתודות API חדשות מעל המונוליט המשותף, וזה רק החריף את הבעיה.
מה היה לפני הבנייה מחדש
שירות אחד שילב איסוף נתוני שוק, חישובים והחזרה ללקוחות, ולכן תעבורת שיא פגעה בכל הצמתים בבת אחת. שיעור הכשלים עמד על 9-14% בשעות פעילות גבוהה, זמן התגובה על שליפות כבדות הגיע לכמה שניות, ואת המגבלות והמטמון המתפעלים תיקנו ידנית — עד עשרים התערבויות בשבוע. פירוק אירוע ארך שעות: לא היה נראה באיזה מקטע הנתונים אבדו.
התוצאה בנתונים מדידים
האיסוף והחישובים הועברו למערכת נפרדת, וההחזרה ללקוחות — למערכת משל עצמה, עם סקיילינג בלתי תלוי ומטמון של מנויים חמים. שיעור הכשלים בשיא — 0,2–0,4%, זמן התגובה תחת עומס — עשיריות השנייה בזמן שעומס השיא גדל פי שלושה, ותיקונים ידניים — לא יותר מאחד-שניים בחודש. המדדים נלקחו מלוחות תפעול ב-Grafana, והם נשארו אצל המזמין יחד עם הגדרות ההתראות.
בעת התדרדרות של פלטפורמה בודדת המנוי לא נקרע: הלקוח מקבל נתונים מהערוץ החלופי, והאירוע נכתב ללוג לצורך פירוק. מרווח החוסן הזה הוא שאיפשר להגדיל את הקהל בלי לשנות את הארכיטקטורה.
מה לעשות אם צומת עצמאי ו-API כבר פרוסים
צומת עצמאי פרוס ו-API עובד אינם סיבה לכתוב את המערכת מחדש בשלמותה. תחילה מבצעים ספירת מלאי: אילו מתודות מחזירות תעבורה, אילו צרכנים תלויים בהן, היכן בקשות הולכות ישירות לצומת ועל איזה נפח הוא מתחיל לפגר אחרי הרשת. זה נותן מפת החלטות — מה נשאר כפי שהוא ומה עובר תחת שכבה חדשה.
השינוי המרכזי — מטמון ותור בין הצרכנים לצומת. נתונים חמים כמו יתרות ובלוקים אחרונים מוחזרים ממטמון עם זמן חיים מוגדר, ושליפות היסטוריות כבדות עוברות לתור ונספרות ברקע.
מנויים לאירועים מטופלים בערוץ נפרד, ולכן זינוק בפעילות לא מפיל את הבקשות הראשיות, והצומת לא משכפל את אותה עבודה מאות פעמים.
הגירה בלי השבתה נשענת על העברה הדרגתית. השכבה החדשה מועלית לצד הישנה, חלק מהתעבורה מועבר אליה, והתשובות מוצלבות עם הקודמות על בקשות חיות. חופפות — החלק גדל; חורגות — ההחלפה מתבטלת בפקודה אחת, והצרכנים לא מבחינים בהבדל.
האינטגרציות הקיימות נשמרות: כתובות המתודות ופורמט התשובות נשארים כשהיו, ורק הפנים הפנימי משתנה. ההפעלה ההדרגתית נעשית מתודה אחת בכל פעם, כך שהמוצר לא נשאר בלי נתונים אף לא לדקה, וכל חלק שהוחלף נראה מיד במדדים.
ספקות טכניים: עומס, כשלי מקור, תמיכה
לפני ההתחלה מהנדסי המזמין שואלים את אותה קבוצת שאלות: איך המערכת מתנהלת בנפילה של מקור, איך לוודא שהנתונים לא אבדו בדרך, כמה זמן לוקח החיבור ומה יקרה אחרי ההשקה.
להלן התשובות כפי שאנחנו נותנים אותן במפגשים טכניים, בהסתמך על תפעול של מערכות דומות: השירות לא נותן אמון במקור ובודק את עצמו.
מה יקרה אם המקור יפסיק להחזיר נתונים?
כשל של מקור לא מפיל את המערכת: הבקשות עוברות לתור עם ניסיונות חוזרים והשהיה גדלה, והצרכנים מקבלים את הערכים התקפים האחרונים עם חותמת זמן. אחרי חידוש הקשר, הפערים מחושבים מחדש לפי הלוג, ולא נמחקים בזרם חדש.
איך בודקים שלמות נתונים?
רציפות רצף האירועים, הצלבה של אגרגטים מול מקור בלתי תלוי (לדוגמה, CoinGecko) ושיעור המרווחים החסרים. אם הפער גבוה מהסף, החלון מסומן כלא-תקף ולא נמסר לצרכן בשקט.
כמה זמן לוקח להעלות את המערכת לפעולה ומה עם התמיכה?
מערכת ראשונה על מקור אחד — ימים: מתאם, סכמת נתונים, בדיקות, הרצה על תעבורה מוקלטת. בהמשך — תורנות לפי מדדי השהיה ושיעור שגיאות, עדכון מתאמים בעת שינוי פורמט התשובות, ובדיקות מתוכננות של התאוששות מהלוג.
איך מוסיפים או מחליפים מקור בהמשך?
המתאם מופרד מהליבה: ספק חדש מתחבר עם עדיפות משלו וכללי הצלבה משלו. ההחלפה נעשית בקנרית — חלק מהתעבורה על המקור החדש, השוואת מדדים, ואחר כך החלפת הראשי.
תחילת העבודות: מה נדרש מצדכם ואיך נחזור עם הערכה
כדי לחזור עם הערכה ותוכנית עבודה, ולא עם הנחות כלליות, אנחנו צריכים מינימום של נתוני פתיחה. חלק מהם על הנתונים עצמם, וחלק — על הרשאות ומגבלות בצד שלכם.
- רשימת מקורות: בורסות, מערכות ברוקראז' או שירותים משלכם, מהם אנחנו לוקחים מחירים, ספר פקודות, עסקאות והיסטוריה.
- היכן מספיקות בקשות תקופתיות והיכן נדרש זרם WebSocket קבוע עם חיבור מחדש והשלמת מה שהוחמץ.
- מפתחות למקורות במצב קריאה בלבד, בלי הרשאות לפעולות מסחר.
- גישה לסביבת הפריסה או לריפוזיטורי והבנה לאן לכתוב לוגים ומדדים.
- מגבלות של ספק הנתונים: תדירות הפניות, עומק ההיסטוריה, ההתנהגות בעת חריגה.
- דרישות להפרדת הרשאות ולתיעוד פניות.
- איש קשר מצדכם, שיאשר במהירות את פורמט השדות ויענה על הבהרות.
סדר הפתיחה הוא כזה: דנים במשימה, מתעדים את היקף המקורות ותרחישי הצריכה, ואחר כך חוזרים עם הערכה ותוכנית עבודה — שלבים, לוחות זמנים ונקודות קבלה.
שלב העבודה הראשון מסיר את הסיכון המרכזי ובדרך כלל מתקדם מהר יותר מהאחרים: מתארים את נקודות הקצה ואת פורמט הזרם, מעלים שלד של REST API לנתוני קריפטו על מקור אחד, ובודקים את ההתנהגות בעת ניתוק תקשורת, בקשה חוזרת ופער בנתונים בין מקורות. בהמשך מחברים את שאר המקורות לפי הסכמה שכבר עובדת.
תארו את המשימה — אילו נתונים נדרשים ומי יצרוך אותם; את השאר נבהיר בשיחה.







