# Retries, Idempotency और Retry Storms — API Gateway और Service Mesh

Source: https://www.geekswithgeeks.com/hi/api-gateway-service-mesh/z-retries

> सिर्फ़ सुरक्षित, अस्थायी विफलताओं को backoff और budgets के साथ retry करें और बोझ बढ़ने से बचें।

## मददगार या हानिकारक

Retry अस्थायी समस्याएँ (pod का restart होना, गिरा connection) ठीक करता है पर लापरवाही से करने पर outages बदतर कर देता है। नियम: सिर्फ़ **idempotent** अनुरोध retry करें (GET, PUT, DELETE, या idempotency key वाला POST) और सिर्फ़ **सुरक्षित विफलता प्रकारों** पर (connection errors, timeouts, `502/503/504`), `400/401/404` पर कभी नहीं। **Jitter के साथ exponential backoff** और छोटा **retry budget** उपयोग करें (जैसे retries अधिकतम 10% अतिरिक्त बोझ जोड़ें)। और **amplification** याद रखें: 3 परतों में से हर एक 2 अतिरिक्त बार retry करे तो एक user अनुरोध सबसे गहरी service तक 27 calls बन सकता है। हर परत पर नहीं, **एक परत** पर retry करें (अक्सर gateway या mesh)।

## 503 पर retry (config)

`resilient` एक टूटा upstream (`flaky`, हमेशा 503) और एक स्वस्थ upstream सूचीबद्ध करता है। `proxy_next_upstream` errors, timeouts और 503 पर अगला server आज़माता है। Gateway config का अंश।

```nginx
upstream resilient { server flaky:8080; server orders-v1:8080; }

location /resilient/ { proxy_next_upstream error timeout http_503; proxy_pass http://resilient/; }
```

## टूटे server के बावजूद हर अनुरोध सफल, चलाकर

मैंने यह Docker में असली nginx 1.27 gateway पर चलाया, upstreams के रूप में छोटी Node.js services के साथ (पूरा setup केस स्टडी में)। चारों calls `orders-v1` से `200` लौटाती हैं: जब भी nginx ने पहले टूटा `flaky` server चुना, उसे 503 मिला और उसने पारदर्शी रूप से स्वस्थ पर retry किया। Client ने विफलता कभी नहीं देखी।

```bash
# four calls to /resilient/x: status and the service that answered
```

Output:

```
200 orders-v1, 200 orders-v1, 200 orders-v1, 200 orders-v1
```

## Amplification और backoff, चलाकर

मैंने यह सादा-Python मॉडल चलाया। हर परत पर 2 retries के साथ, 1, 2, 3 और 4 परतों के retries 3, 9, 27 और 81 calls बनाते हैं। दूसरी पंक्ति retry-budget का विचार है: 10% अतिरिक्त पर सीमित retries का मतलब लगभग 1.1 गुना बोझ। Backoff सूची 0.1 s से 5 s की सीमा तक दोगुना होती प्रतीक्षा दिखाती है।

```python
import hashlib, bisect, math, random

def calls(layers, retries): return (1 + retries) ** layers
print([calls(l, 2) for l in (1, 2, 3, 4)])
def with_budget(rate, budget=0.1): return round(1 + budget, 2)
print(with_budget(100))

def backoff(attempt, base=0.1, cap=5.0): return min(cap, base * 2 ** attempt)
print([backoff(a) for a in range(8)])

```

Output:

```
[3, 9, 27, 81]
1.1
[0.1, 0.2, 0.4, 0.8, 1.6, 3.2, 5.0, 5.0]
```

**Quiz:** हर परत पर retry करना ख़तरनाक क्यों है?

- [ ] HTTP में retries की अनुमति नहीं
- [x] Retries गुणा होते हैं, एक अनुरोध को कई बनाकर विफल होती service पर बोझ डालते हैं
- [ ] Retries responses छोटे करते हैं
- [ ] यह सिर्फ़ logging को प्रभावित करता है

*Answer:* Retries गुणा होते हैं, एक अनुरोध को कई बनाकर विफल होती service पर बोझ डालते हैं. परतदार retries outage के दौरान बोझ को घातीय रूप से बढ़ाते हैं।
