सर्किट ब्रेकर और रिट्रीट
सर्किट ब्रेकर और रेट्राई
1) आपको इसकी आवश्यकता क्यों है
नेटवर्क अविश्वसनीय हैं: विलंबता स्पंदन, नोड्स गिरते हैं, सीमाएं पहुंचती हैं। रिट्रे को अल्पकालिक विफलताओं से बचाया जाता है, और सर्किट ब्रेकर सिस्टम को कैस्केडिंग विफलताओं और स्व-डीडीओएस से बचाता है। सही समय और सीमाओं के साथ संयोजन एसएलओ को संरक्षित करता है, पूंछ की देरी और "नाइन" की कीमत को स्थिर करता है।
2) बुनियादी सिद्धांत
पहले टाइमआउट, फिर पीछे हटता है, फिर सर्किट ब्रेकर।
रेट्रीम केवल पहचान वाले संचालन (GET, सुरक्षित POST/idempotent कुंजी के साथ PUT)।
एक रिट्रे बजट आवंटित करें: प्रति मार्ग मूल आरपीएस का ≤ 10-15%।
स्थानीयकरण विफलता: बल्कहेड (अलग पूल/कोटा) + दर-सीमा।
गिरावट के दौरान - तेजी से विफलता (असफल-तेज), सुंदर-गिरावट/स्टब।
3) रिट्रे शब्दार्थ
कब पीछे हटना है
क्षणिक त्रुटियां: टाइमआउट, 5xx, नेटवर्क अनुपलब्धता, 429 ('रेट्री-आफ्टर' के बाद)।
आप पीछे नहीं हट सकते: स्पष्ट व्यापार त्रुटियां (4xx ≠ 429), निष्क्रियता के बिना दुष्प्रभाव (एक कुंजी के बिना भुगतान)।
रणनीतियाँ
घातीय बैकऑफ + जिटर (पूर्ण या यहां तक कि): पीछे हटने के झुंड को चिकना करता है।
अधिकतम प्रयास: 1-2 (शायद ही कभी 3) - अधिक आमतौर पर हानिकारक होता है।
बजट: वैश्विक रिट्रे काउंटर/सेकंड प्रति सेवा और प्रति-अनुरोध "पुन: प्रयास टोकन।"
हेजिंग (दुर्लभ): टी-मात्रा (p95) के बाद अनुरोध का समानांतर दोहरा - केवल कड़ाई से पहचान के लिए पढ़ ता है।
स्यूडोकोड बैकऑफ + जिटर:python base = 100 # ms for attempt in range(1, max_attempts+1):
try:
return call()
except Transient as e:
if attempt == max_attempts: raise sleep_ms = min(cap_ms, base 2(attempt-1))
sleep(random(0, sleep_ms)) # full jitter
4) टाइमआउट और "त्वरित विफलता"
क्लाइंट टाइमआउट <अपस्ट्रीम टाइमआउट: ताकि "ज़ोंबी" अनुरोधों को जमा न किया जा सके।
Делите: टाइमआउट कनेक्ट करें, टाइमआउट पढ़ें, समग्र समय सीमा।
टेल-अवेयर टाइमआउट: p95/p99 + छोटे मार्जिन के लिए लक्ष्य।
एक सामान्य समय सीमा क्षेत्र (उदाहरण के लिए, gRPC 'समय सीमा') का उपयोग करें और इसे श्रृंखला के नीचे डालें।
5) सर्किट ब्रेकर: यह कैसे काम करता है
राज्य:- बंद: यातायात पास करता है, त्रुटियों/विलंबता की गिनती करता है।
- ओपन: तुरंत एक त्वरित इनकार (या अतिरिक्त उत्तर) देता है।
- हाफ-ओपन: परीक्षण प्रश्न; सफल होने पर, यह बंद हो जाता है।
- त्रुटियाँ/समय समाप्ति एक्स% प्रति विंडो एन निवेदन/सेकंड या सीमा से ऊपर p99 से अधिक है।
- रोलिंग आंकड़े और न्यूनतम मात्रा प्रासंगिक हैं (उदाहरण के लिए, ≥ 50 प्रश्न)।
6) बल्कहेड, कोटा और विभाजित और जीत
प्रति-अपस्ट्रीम और प्रति-सुविधा कनेक्शन के अलग पूल।
इन-फ्लाइट अनुरोधों के लिए कोटा; अत्यधिक - त्वरित इनकार।
फीचर फ्लैग की कमी के मामले में।
7) परिधि एकीकरण (दूत/इस्तियो/Nginx)
दूत (पुनः प्रयास + बाहरी + सीबी, विचार):yaml routes:
- match: { prefix: "/api" }
route:
cluster: upstream_api timeout: 2s retry_policy:
retry_on: "connect-failure,reset,retriable-4xx,5xx"
num_retries: 2 per_try_timeout: 600ms retry_back_off: { base_interval: 100ms, max_interval: 800ms }
hedge_policy:
hedge_on_per_try_timeout: true initial_requests: 1 additional_request_chance: { numerator: 5, denominator: HUNDRED } # 5%
clusters:
- name: upstream_api circuit_breakers:
thresholds:
- priority: DEFAULT max_connections: 500 max_requests: 1000 max_retries: 200 outlier_detection:
consecutive_5xx: 5 interval: 5s base_ejection_time: 30s max_ejection_percent: 50
Istio (VirtualService दोष/पुनरावृत्ति, संपीड़ित उदाहरण):
yaml apiVersion: networking. istio. io/v1beta1 kind: VirtualService spec:
hosts: ["payments"]
http:
- route: [{ destination: { host: payments } }]
timeout: 2s retries:
attempts: 2 perTryTimeout: 600ms retryOn: "5xx,connect-failure,refused-stream,reset"
Nginx Ingress (एनोटेशन):
yaml nginx. ingress. kubernetes. io/proxy-connect-timeout: "2"
nginx. ingress. kubernetes. io/proxy-read-timeout: "2"
nginx. ingress. kubernetes. io/proxy-next-upstream: "error timeout http_502 http_503 http_504"
nginx. ingress. kubernetes. io/proxy-next-upstream-tries: "2"
8) पुस्तकालय और कोड (स्टैक स्निपेट्स)
जावा (Resilience4j):java var cb = CircuitBreaker. ofDefaults("psp");
var retry = Retry. of("psp-retry",
RetryConfig. custom()
.maxAttempts(2)
.waitDuration(Duration. ofMillis(200))
.intervalFunction(IntervalFunction. ofExponentialRandomBackoff(100, 2. 0, 0. 5) )//jitter
.retryExceptions(SocketTimeoutException. class, IOException. class)
.build());
Supplier<Response> decorated =
CircuitBreaker. decorateSupplier(cb,
Retry. decorateSupplier(retry, () -> client. call()));
return Try. ofSupplier(decorated)
.recover(BusinessException. class, fallback())
.get();
गो (संदर्भ समय सीमा + बैकऑफ):
go ctx, cancel:= context. WithTimeout(context. Background(), 2time. Second)
defer cancel()
var lastErr error for i:= 0; i < 2; i++ {
reqCtx, stop:= context. WithTimeout(ctx, 600time. Millisecond)
lastErr = call(reqCtx)
stop()
if lastErr == nil { break }
sleep:= time. Duration(rand. Intn(1<<uint(7+i))) time. Millisecond // full jitter time. Sleep(min(sleep, 800time. Millisecond))
}
if lastErr!= nil { return fastFail() }
नोड। जेएस (मिला + पी-रीट्री):
js import pRetry from 'p-retry';
await pRetry(() => got(url, { timeout: { connect: 500, request: 2000 } }), {
retries: 2,
factor: 2,
randomize: true,
minTimeout: 100,
maxTimeout: 800,
onFailedAttempt: e => { if (isBusiness(e)) throw e; }
});
9) रिट्रे और एसएलओ बजट
टाइप रीट्री टोकन: प्रत्येक रिट्रे एक टोकन खर्च करता है; पूल सीमित है।
त्रुटि-बजट के साथ सहयोगी: यदि बर्न-रेट सीमा से ऊपर है, तो रिट्रे बंद करें, अधिक बार सीबी खोलें, गिरावट को चालू करें।
कैनरी रिलीज़: कैनरी पर, प्रयासों और टोकन को कम करें।
10) हेजिंग (सावधानी)
p95 की समय सीमा के बाद एक अतिरिक्त अनुरोध चलाएं, हारने वाले को रद्द करें।
केवल पढ़ ने और "सुरक्षित" पहचान संचालन के लिए; शेयर (≤ 1-5%) सीमित करें।
ऊपर की ओर लोड में वृद्धि के लिए देखें।
11) अवलोकन क्षमता
मार्गों के साथ RED मैट्रिक्स: दर, त्रुटि, अवधि (p50/p95/p99)।
सीबी मैट्रिक्स: स्थिति (ओपन/हाफ-ओपन), ओपनिंग रेट, मिस/इनकार किए गए अनुरोध।
रिट्रेस: प्रयास/अनुरोध, पुन: प्रयास-दर, जले हुए टोकन।
परिधि: बाहरी-अस्वीकृति, इजेक्शन-दर।
ट्रेसेस: 'retry _ try', 'cb _ state', 'hedged = true', 'trace _ id' को एनोटेट करें।
12) वास्तुकला एकीकरण
प्रत्येक महत्वपूर्ण अपस्ट्रीम के लिए बल्कहेड + सीबी।
कतारें/असिंक्रॉन: पागल समय के बजाय लंबे संचालन के लिए।
कैश/स्टब्स: फेल-ओपन होने पर गैर-महत्वपूर्ण सुविधाओं के लिए।
ऑटोस्केल: खराब रिट्रीट के लिए नहीं बनाता है - पहले तूफान को रोकें।
13) एंटी-पैटर्न
टाइमआउट के बिना रिट्रेज़ - जमे हुए कनेक्शन और पूल की कमी।
गैर-आइडेम्पोटेंट लेनदेन (डबल राइट-ऑफ) दोहराएं।
कैप और जिटर के बिना अनंत घातीय वृद्धि।
सभी अपस्ट्रीम के लिए एक एकल सीबी → पूरे उत्पाद में विफलता को खींचें और ड्रॉप करें।
429/' रीट्री-आफ्टर 'को नजरअंदाज कर रहा है।
क्लाइंट टाइमआउट अपस्ट्रीम (या बिल्कुल नहीं) की तुलना में लंबा है।
रेट्रास के साथ "व्यापार" त्रुटियों का इलाज करें।
14) कार्यान्वयन चेकलिस्ट (0-30 दिन)
0-7 दिन
मार्गों और उनकी पहचान की पहचान करें।
टाइमआउट सेट करें (कनेक्ट/रीड/ओवरऑल), न्यूनतम रिट्रे (× 1) और डिफ़ॉल्ट सीबी सक्षम करें।
मुख्य अपस्ट्रीम के लिए पूल/कोटा (बल्कहेड) को अलग करें।
8-20 दिन
जिटर और वैश्विक रिट्रे बजट, रीट्री-रेट अलर्ट शामिल करें।
परिधि पर बाहरी-इजेक्शन कॉन्फ़िगर करें, लो-प्रियो फीचर के लिए तेजी से विफलता।
RED + CB/Retry डैशबोर्ड, टैग किए गए ट्रेल्स।
21-30 दिन
कैनरी रिट्रे प्रोफाइल (कम प्रयास), गेम-डे "अपस्ट्रीम स्लो/फ्लैप्स"।
दस्तावेज़ नीति: कौन/क्या पीछे हटता है, सीमा, अपवाद।
आंकड़ों के अनुसार p95/p99 और टाइमआउट की समीक्षा करें, आंख से नहीं।
15) परिपक्वता मैट्रिक्स
100% मार्गों में टाइमआउट और प्रलेखित रिट्रे/एनई नीति है।
रेट्री-रेट बजट (≤ 10-15%) में फिट बैठता है, घटनाओं में कोई स्पाइक्स नहीं हैं।
पूरे पूल के गिरने से पहले सीबी आग; कोई कैस्केडिंग विफलताएं नहीं।
ट्रेल्स प्रयास/हेजिंग दिखाते हैं; p99 चोटियों पर स्थिर है।
कैनरी रिलीज़ एक "सावधान" रिट्रे प्रोफाइल का उपयोग करते हैं।
16) लघु विन्यास उदाहरण
Resilience4j YAML (स्प्रिंग बूट, идея):yaml resilience4j:
circuitbreaker:
instances:
psp:
slidingWindowType: COUNT_BASED slidingWindowSize: 100 minimumNumberOfCalls: 50 failureRateThreshold: 50 waitDurationInOpenState: 30s permittedNumberOfCallsInHalfOpenState: 5 retry:
instances:
psp:
maxAttempts: 2 waitDuration: 200ms enableExponentialBackoff: true exponentialBackoffMultiplier: 2. 0 retryExceptions:
- java. net. SocketTimeoutException
- java. io. IOException
दूत दर-सीमा (विचार टुकड़ा):
yaml rate_limits:
- actions:
- generic_key: { descriptor_value: "api. payments" }
17) निष्कर्ष
स्थिरता एक अनुशासन है: टाइमआउट → रिट्रीट (जिटर और बजट के साथ) → सर्किट ब्रेकर + बल्कहेड/कोटा और त्वरित अस्वीकृति। एक परिधि (बाहरी-इजेक्शन) सेट करें, RED/CB/Retry डैशबोर्ड लटकाएं, पहचान नीति को ठीक करें और व्यवसाय SLI के बारे में न भूलें। फिर संक्षिप्त विफलताएं अदृश्य रहेंगी, और वास्तविक घटनाएं कैस्केडिंग में नहीं बदल जाएंगी।