פסק זמן בקרת מעגל
1) למה אתה צריך את זה
המערכות לא נופלות מכשל ”קטלני” אחד, אלא מהצטברות של עיכובים ו ”גל” חוזר. פסקי זמן מגבילים את זמן ההמתנה ומשחררים את המשאבים, ובקרת המעגל (מפסק + שפיכה + תחרות אדפטטיבית) מונעת מהתפשטות לאורך שרשרת התלויות. המטרה היא לשמור על p95/p99 בתוך גבולות המטרה ולשמור על זמינות עבור כשלים חלקיים.
2) הגדרות בסיסיות
2. 1 סוגי פסקי זמן (L7/L4)
חיבור פסק זמן - צור חיבור TCP/TLS.
זמן לחיצת יד - לחיצות ידיים TLS/HTTP2 הקדמה.
כתוב פסק זמן - שלח בקשה (כולל גוף).
קרא פסק זמן - המתן לביט הראשון של התגובה ו/או כל הגוף.
זמן ללא הפסקה - חיבור לא פעיל.
תאריך יעד כולל - מועד אחרון ”קשה” לכל הבקשה (מקצה לקצה).
2. 2 תקציב מועד אחרון
בחר את היעד "דדליין _ סה" כ "וחלק בשלבים:- 'ingress (שער) + authZ + app + DB/cache + outbound PSP'.
- שער: 30 ms,
- יישום: 120 ms,
- ד: 120 ms,
- PSP: 100 ms,
- מרווח: 30 ms.
2. 3 התפשטות וביטול
'Deadline '/' time out' most להיות מועבר במורד השרשרת (הקשר, כותרות, GRPC Deadline). על תפוגה - לבטל פעולות רקע (ביטול/ביטול ctx), מנעולים/סמאפורות נקיים.
3) אסטרטגיות הגדרת זמן
1. מלמעלה למטה: בהתבסס על SLO ו-p95 - נקבע מועד סופי, ואז להתפצל לתתי-זמנים.
2. זהה מסלולים ”יקרים” (הורדות קבצים, דוחות, PSPS חיצוני) - פרטים ארוכים יותר, אך מוגבלים.
- אידמפוטנט (GET/סטטוס חוזר) - קצר יותר, אגרסיבי יותר;
- כתיבה/כסף - קצת יותר זמן, אבל עם חזרה אחת ואידמפוטנטיות.
4. סיום על ידי תוכניות/דיירים (יוזמה יכולה להיות זמן ארוך יותר, אבל פחות מקבילית).
4) מפסק מעגל: מודלים ופרמטרים
4. 1 מדיניות מפעילה
שיעור שגיאה - X% על חלון שאילתה/זמן N.
כשלים משמעותיים, כשלים רצופים.
קצב קריאה איטי - פרופורציה של שיחות ארוכות יותר מהסף T.
שיעורי שגיאה: פסקי זמן/5xx/חיבור-אתחול = ”קטלני”, 4xx - אל תיקחו בחשבון.
4. 2 תנאים
סגור - מדלג על הכל, מצטבר סטטיסטיקה.
כישלון מיידי (חוסך משאבים, אינו מוחץ את התלות).
חצי פתוח - ”דגימות” קטנות (N) עבור ”בדיקת מים”.
4. 3 תוספות שימושיות
מחיצה: מאגר של אשכולות/חיבורים לכל תלות כדי שלא ”למצוץ” הכל.
Adaptive concurrency: automatic concurrency restruction (אלגוריתמים דמויי AIMD/וגאס) על ידי latency נצפה.
Load Shedding: כישלון מוקדם/הידרדרות במקרה של מחסור במשאב מקומי (תורים, מעבד, GC pauses).
5) אינטראקציה: פסקי זמן, נסיגות, גבולות
דד-ליין ראשון, ואז מגש מחדש: כל חזרה צריכה להתאים לדד-ליין משותף.
Backoff + jiter להילוך חוזר; לכבד את ”Retry-After” ולנסות מחדש-תקציב.
קצב מגביל: עם מפסק פתוח - גבולות נמוכים יותר כדי לא להגביר את הסערה.
Idempotency: חובה על פעולות כתיבה (כדי להימנע מלקחת עם פסקי זמן ”מטומטמים”).
היכן לחזור: רצוי בקצה (לקוח/שער) ולא עמוק בפנים.
6) ערכי מטרה מעשיים (סימני ספסל)
קריאה ציבורית API: מקצה לקצה '200-500 ms', לקרוא פסק זמן '100-300 ms'.
כתב קריטי (תשלומים): '300-800 ms' e2e; בדיקת PSP חיצונית '250-400 ms'.
חיבור/TLS: ”50-150 ms” (יותר - בעיית רשת/הלחמה).
סרק: 30-90's '(לקוחות ניידים - קצר כדי לחסוך סוללה).
התאם את הערכים עבור p95/p99 ואזורים.
7) תצורות ודוגמאות
7. שליח 1 (מסלול אשכול +, פסאודו)
yaml clusters:
- name: payments_psp connect_timeout: 100ms type: STRICT_DNS lb_policy: ROUND_ROBIN circuit_breakers:
thresholds:
- priority: DEFAULT max_connections: 2000 max_requests: 2000 max_retries: 50 outlier_detection:
consecutive_5xx: 5 interval: 5s base_ejection_time: 30s max_ejection_percent: 50
routes:
- match: { prefix: "/api/v1/payments" }
route:
cluster: payments_psp timeout: 350ms # per-request deadline idle_timeout: 30s retry_policy:
retry_on: "reset,connect-failure,refused-stream,5xx,gateways"
num_retries: 1 per_try_timeout: 200ms
7. 2 NGINX (היקף)
nginx proxy_connect_timeout 100ms;
proxy_send_timeout 200ms; # write proxy_read_timeout 300ms; # read (первый байт/все тело)
keepalive_timeout 30s;
send_timeout 15s;
Быстрый отказ при перегрузке limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn addr 50;
7. 3 GRPC (לקוח, Go-פסאודו)
go ctx, cancel:= context.WithTimeout(context.Background(), 350time.Millisecond)
defer cancel()
resp, err:= client.Pay(ctx, req) // Deadline передается вниз
7. לקוח 4 HTTP (ללכת)
go client:= &http.Client{
Timeout: 350 time.Millisecond, // общий дедлайн на запрос
Transport: &http.Transport{
TLSHandshakeTimeout: 100 time.Millisecond,
ResponseHeaderTimeout: 250 time.Millisecond,
IdleConnTimeout: 30 time.Second,
MaxIdleConnsPerHost: 100,
},
}
7. 5 Resilience4j (ג 'אווה, פסאודו)
yaml resilience4j.circuitbreaker.instances.psp:
slidingWindowType: TIME_BASED slidingWindowSize: 60 failureRateThreshold: 50 slowCallDurationThreshold: 200ms slowCallRateThreshold: 30 permittedNumberOfCallsInHalfOpenState: 5 waitDurationInOpenState: 30s
resilience4j.timelimiter.instances.psp:
timeoutDuration: 350ms
8) יכולת התבוננות והתראה
8. 1 מדדים
'http _ client _ בקשות' endpoint, status ',' לקוח _ latency _ buckett&pos
8. 2 שבילים
ספאנס: לחדור למפעיל = DB/Redis # חיצוני.
תכונות: "timeout _ ms _ target", "circuit _ state", "תור _ time _ ms'.
לדוגמה: עניבת פסגות p99 לאיתור זיהוי ספציפי.
8. 3 התראות
'p99 _ latency [קריטי]'> מטרות X דקות ברציפות.
פסק זמן _ קצב [תלות] קפץ> Y%.
מעברים תכופים לשובר 'פתוח '/' מנופף'.
גידול של 'shed _ בקשות _ total' with high CPU/GC.
9) התאמה קונקורנסי וטעינה Shedding
9. רעיון 1
אוטומציה מפחיתה מקביליות ככל שזנבות האחיזה גדלים:- עלייה איטית, ירידה חדה.
- כמו וגאס: לעמוד בתור.
- מבוסס טוקן: כל בקשה ”שורף” האסימון; אסימונים מונפקים על סמך המהירות הנמדדת.
9. 2 מימוש
סמאפורות מקומיות לכל מסלול; המטרה היא לשמור על ”תור _ זמן” מתחת לסף.
פתיל גלובלי (RPS/תחרותי) על השער.
אם קיים מחסור בקשרי CPU/After, כשל מוקדם לפני הביצוע הלוגי (429/503 עם Retry-After).
10) בדיקות ותרחישי כאוס
הזרקת Latency: באופן מלאכותי להוסיף 50-300 ms לכל תלות.
Packet loss/dup/drop (tc/tbf, Toxiproxy).
סיבוב ידית: להפחית בריכות חיבור, להגדיל עומס לרוויה.
Kill/Degrade אזור אחד/רסיס (לא זמין חלקית).
צ 'קים: לא ”נכשל” סערת המגש מחדש; שובר נפתח באופן צפוי; אם התור גדל.
11) תרופות אנטי ־ פטריות
אחד גלובלי ”לקרוא פסק זמן” ללא פרטים להתחבר/TLS/לכל שלב.
היעדר דד-ליין משותף * מגשים מחדש מעבר ל-SLO.
רטריי בלי ג 'יטר ובלי תקציב מחדש.
קשרים ”נצחיים” ללא פסקי זמן בטלים = תיאורי דליפה.
ברייקר נחשב 4xx כטעויות קטלניות.
אין ביטול/ביטול = = עבודת הרקע ממשיכה לאחר פסק זמן ללקוח.
פסקי זמן ארוכים מדי לרשתות ניידות/לא יציבות.
12) פרטים של iGaming/Finance
כתיבה ביקורתית (משקעים/יציאות): חזרה קצרה אחת עם מפתח אידמפוטנטי, ואז '202 מקובלים' + סקרים במקום ציפיות אינסופיות.
PSP/בנקאות: מדיניות נפרדת על ידי ספק/אזור (חלק איטי יותר).
תשלומים וגבולות אחראיים: עבור מנעולים/ביקורות - מהיר '423/409', לא למתוח ”תלייה” עסקאות.
דיווח/צבירה - הפעל באופן אסינכרוני (אצווה + משאב סטטוס).
13) רשימת מוכנות תומכת
[ הגדרת המסלול הקריטי ] (GET/POST).
[ ] מתוקצב על ידי במה; התפשטות המועד האחרון מתאפשרת.
[ ] חיבור/TLS/read/write/idle configs על שער ולקוחות.
[ מפסק מעגל ] עם קצב כישלון וסף קריאה איטי; נכון היגיון חצי פתוח.
[ ] מחיצות על תלויות; לכל מסלול גבולות מקבילים.
[ ] הטעינה לפני ההיגיון העסקי מבוצעת במהלך עומס יתר.
[ אינטגרציה ] עם נסיגות: Backoff + jitter, retry-תקציב, כבוד ”Retry-After”.
[ ] Idempotency לכתוב, ”Idempotency-Key” ויוצא לאירועים.
[ ] Metrics: פסק זמן/שיחה איטית/מפסק/תור זמן/תחרותי.
[ ] כאוס: הזרקת עיכובים/הפסדים/כשלים, הידרדרות האזורים.
[ תיעוד לקוח ]: תיזמון לדוגמה, קודי תגובה, טיפים לשידור חוזר.
14) TL; DR
תן לכל בקשה תאריך יעד קשה, תארגן אותה בשלבים ותפזר אותה במורד השרשרת. ניהול מגרעות באמצעות מפסק + מחיצות + הסתגלות לקונקורנסי + הטעינה. הילוכים חוזרים - רק בתוך המועד האחרון, עם ג 'יטר ותקציב; לכתוב - אידמפוטנט בלבד. מדידת זמן/קריאה איטית, מצב שובר ו ”תור _ זמן”, באופן קבוע לנהוג בדיקות כאוס.