ЁЯЫЯ рдзрдбрд╛ 13 тАФ Design рдордзреВрдирдЪ resilience: рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдгрд╛рд╕рд╛рдареА рдПрдХ рдпреЛрдЬрдирд╛
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 18 рдкреИрдХреА рдзрдбрд╛ 13 ┬╖ рдкреБрдвреАрд▓: lesson-14-security
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ12, рдЖрдгрд┐ рдХрд╛рд░реНрдпрд╛рд▓рдп рдЖрдХреГрддреАрд╡рд░реАрд▓ рдкреНрд░рддреНрдпреЗрдХ box рд▓рд╛ рд╡рд┐рдЪрд╛рд░рддреЗ рддреЛ рдкрд╣рд┐рд▓рд╛ рдкреНрд░рд╢реНрди: рддреЛ рдЕрдкрдпрд╢реА рдЭрд╛рд▓рд╛ рддрд░ рдХрд╛рдп рд╣реЛрддреЗ? рддреБрдореНрд╣реА рд╢рд┐рдХрддрд╛ timeout budgets, backoff рдЖрдгрд┐ jitter рд╕рд╣ retries, circuit breaker, bulkheads, graceful degradation, рдЖрдгрд┐ multi-AZ рдЪреЗ рдЧрдгрд┐рдд. рд╣рд╛ рдзрдбрд╛ рдирд┐рдпреЛрдЬрдирд╛рдЪреНрдпрд╛ рдирдЬрд░реЗрддреВрди рдЖрд╣реЗ. Scaling рд╢рд╛рд│рд╛, рдзрдбрд╛ 13 рдкреНрд░рддреНрдпреЗрдХ рд╕рд╛рдзрди simulations рд╕рд╣ рдЦреЛрд▓рд╛рдд рдмрд╛рдВрдзрддреЛ.
- design/designs.py тАФ
call_chain(hops, ms_each, availability_each) - design/demo.py тАФ
python3 design/demo.py resilience - design/test_design.py тАФ check L13
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рджреАрдкрд┐рдХрд╛ рд╕реВрдЪрдирд╛-рдлрд▓рдХ app рдЪреА рдЖрдХреГрддреА рднрд┐рдВрддреАрд╡рд░ рд▓рд╛рд╡рддреЗ. рддреНрдпрд╛рдд boxes рдЖрдгрд┐ рдмрд╛рдг рдЖрд╣реЗрдд. рддреА рдХрддрд░рд┐рдирд╛рд▓рд╛ рдПрдХ рд▓рд╛рд▓ рдкреЗрди рджреЗрддреЗ. "рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдгрд╛рд╕рд╛рдареА рдЪрд╛рд░ рдЧреЛрд╖реНрдЯреА рд▓рд┐рд╣реА."
- тП▒я╕П рдЖрдкрдг рдХрд┐рддреА рд╡реЗрд│ рдерд╛рдВрдмрд╛рдпрдЪреЗ? рдкреВрд░реНрдг page 800 ms рдордзреНрдпреЗ рддрдпрд╛рд░ рд╡реНрд╣рд╛рдпрд▓рд╛ рд╣рд╡реЗ. рдореНрд╣рдгреВрди login рддрдкрд╛рд╕рдгреАрдХрдбрдЪреНрдпрд╛ рдмрд╛рдгрд╛рд▓рд╛ 50 ms, рд╕реВрдЪрдирд╛-рдиреЛрдВрджрд╡рд╣реАрдХрдбрдЪреНрдпрд╛ рдмрд╛рдгрд╛рд▓рд╛ 150 ms, photo service рдХрдбрдЪреНрдпрд╛ рдмрд╛рдгрд╛рд▓рд╛ 300 ms рдорд┐рд│рддрд╛рдд. рдпрд╛ рд╕рдЧрд│реНрдпрд╛ рдкреНрд░рддреАрдХреНрд╖рд╛ 800 рдЪреНрдпрд╛ рдЖрдд рдмрд╕рд╛рдпрд▓рд╛ рд╣рд╡реНрдпрд╛рдд.
- ЁЯЩП рдЖрдкрдг рдкреБрдиреНрд╣рд╛ рд╡рд┐рдЪрд╛рд░рд╛рдпрдЪреЗ рдХрд╛? рдПрдХ-рджреЛрдирджрд╛, рд╡рд╛рдврддреНрдпрд╛ рд╡рд┐рд░рд╛рдорд╛рдиреЗ рдЖрдгрд┐ рдереЛрдбреНрдпрд╛ random рдЬрд╛рджрд╛ рд╡реЗрд│рд╛рдиреЗ, рдореНрд╣рдгрдЬреЗ рд╕рдЧрд│реЗ callers рдПрдХрд╛рдЪ рдХреНрд╖рдгреА рдкреБрдиреНрд╣рд╛ рд╡рд┐рдЪрд╛рд░рдд рдирд╛рд╣реАрдд.
- ЁЯФМ рд╡рд┐рдЪрд╛рд░рдгреЗ рдХрдзреА рдерд╛рдВрдмрд╡рд╛рдпрдЪреЗ? рд╕рд▓рдЧ рдЕрдиреЗрдХ рдЕрдкрдпрд╢рд╛рдВрдирдВрддрд░ рдПрдХ switch рдЙрдШрдбрддреЛ: "10 seconds photo service рд▓рд╛ call рдХрд░реВ рдирдХрд╛." рдордЧ рдПрдХ рдЪрд╛рдЪрдгреА call.
- ЁЯкз рддреНрдпрд╛рдРрд╡рдЬреА рдХрд╛рдп рджрд╛рдЦрд╡рд╛рдпрдЪреЗ? Photo service рдмрдВрдж рдЖрд╣реЗ? рд╕реВрдЪрдирд╛ photos рд╢рд┐рд╡рд╛рдп рджрд╛рдЦрд╡рд╛. Page рддрд░реАрд╣реА рдЙрдШрдбрддреЗ.
рдРрд╢реНрд╡рд░реНрдпрд╛ рдкрд╛рдЪрд╡реА рдХрд▓реНрдкрдирд╛ рдЬреЛрдбрддреЗ: рд╡реЗрдЧрд│реНрдпрд╛ рдЦреЛрд▓реНрдпрд╛. Photo рдорджрддрдиреАрд╕ рддреНрдпрд╛рдВрдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдЦреЛрд▓реАрдд рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдЦреБрд░реНрдЪреНрдпрд╛рдВрд╡рд░ рдХрд╛рдо рдХрд░рддрд╛рдд. рддреЗ рд╕рдЧрд│реЗ рдЕрдбрдХрд▓реЗ рддрд░реА рд╕реВрдЪрдирд╛-рдорджрддрдиреАрд╕рд╛рдВрдЪреНрдпрд╛ рдЦреБрд░реНрдЪреНрдпрд╛ рддреНрдпрд╛рдВрдЪреНрдпрд╛рдХрдбреЗрдЪ рд░рд╛рд╣рддрд╛рдд. рд╣реЗрдЪ bulkhead, рдЬрд╣рд╛рдЬрд╛рдЪреНрдпрд╛ рдЖрддрд▓реНрдпрд╛ рднрд┐рдВрддреАрдВрд╕рд╛рд░рдЦреЗ.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
u["ЁЯСк parent<br/>page budget 800 ms"] --> api["ЁЯзй notice API"]
api -->|"тП▒я╕П 50 ms"| auth["ЁЯФС auth"]
api -->|"тП▒я╕П 150 ms"| db["ЁЯЧДя╕П notices DB"]
api -->|"тП▒я╕П 300 ms ┬╖ ЁЯФМ breaker"| ph["ЁЯЦ╝я╕П photo service"]
ph -.->|"down"| fb["ЁЯкз degrade:<br/>notices without photos"]
subgraph bh["ЁЯЪк bulkheads"]
p1["pool for DB calls"]
p2["pool for photo calls"]
end
az["ЁЯПвЁЯПвЁЯПв 3 AZs<br/>99.5% each тЖТ 99.99999%"]
ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрд╡реГрддреНрддреА + рдПрдХ lab: https://school-edh.pages.dev/system-design/lesson-diagrams.html#l13
тЭУ рдХрд╛рдп
- Timeout budget тАФ user рдЪреНрдпрд╛ рдорд░реНрдпрд╛рджреЗрдкрд╛рд╕реВрди рд╕реБрд░реБрд╡рд╛рдд рдХрд░рд╛ (page: 800 ms) рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ dependency рд▓рд╛ рддреНрдпрд╛рддрд▓рд╛ рдПрдХ рддреБрдХрдбрд╛ рджреНрдпрд╛. рд╣реЗ рддреБрдХрдбреЗ, рдЕрдзрд┐рдХ рддреБрдордЪреЗ рд╕реНрд╡рддрдГрдЪреЗ рдХрд╛рдо, рдЖрдд рдмрд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ. рдЙрд░рд▓реЗрд▓рд╛ рд╡реЗрд│ request рд╕реЛрдмрдд рдЦрд╛рд▓реА рдкрд╛рдард╡рд╛ (deadline header, рдХрд┐рдВрд╡рд╛ gRPC deadline) рдореНрд╣рдгрдЬреЗ caller рдиреЗ рд╕реЛрдбреВрди рджрд┐рд▓реНрдпрд╛рдирдВрддрд░ рдЦреЛрд▓рд╡рд░рдЪреА service рдХрд╛рдо рдХрд░рдд рд░рд╛рд╣рдд рдирд╛рд╣реА.
- Retry + backoff + jitter тАФ рдлрдХреНрдд рд╕реБрд░рдХреНрд╖рд┐рдд calls retry рдХрд░рд╛ (reads, рдХрд┐рдВрд╡рд╛ idempotency key рдЕрд╕рд▓реЗрд▓реЗ writes тАФ рдзрдбрд╛ 11). рдкреНрд░рддреНрдпреЗрдХ рд╡реЗрд│реА рдЬрд╛рд╕реНрдд рдерд╛рдВрдмрд╛ (100, 200, 400 ms тАж, рдПрдХрд╛ рдорд░реНрдпрд╛рджреЗрдкрд░реНрдпрдВрдд), рдЖрдгрд┐ рдПрдХ random рднрд╛рдЧ (jitter) рдЬреЛрдбрд╛ рдореНрд╣рдгрдЬреЗ рдПрдХрддреНрд░ рдЕрдкрдпрд╢реА рдЭрд╛рд▓реЗрд▓реЗ clients рдПрдХрддреНрд░ retry рдХрд░рдд рдирд╛рд╣реАрдд. рдПрдХрд╛рдЪ рдерд░рд╛рд╡рд░ retry рдХрд░рд╛: рдкреНрд░рддреНрдпреЗрдХреА 3 рд╡реЗрд│рд╛ рдкреНрд░рдпрддреНрди рдХрд░рдгрд╛рд░реЗ рддреАрди рдерд░ 27 calls рдХрд░рддрд╛рдд.
- Circuit breaker тАФ closed (calls рдЬрд╛рддрд╛рдд, рдЕрдкрдпрд╢ рдореЛрдЬрд▓реЗ рдЬрд╛рддреЗ) тЖТ N рдЕрдкрдпрд╢рд╛рдВрдирдВрддрд░ open (рдкрдЯрдХрди fail, рдерд╛рдВрдмрдгреЗ рдирд╛рд╣реА) тЖТ рдПрдХрд╛ рд╡рд┐рд░рд╛рдорд╛рдирдВрддрд░ half-open (рдПрдХ рдЪрд╛рдЪрдгреА call). рд╣рд╛ рддреБрдордЪреЗ threads рд╡рд╛рдЪрд╡рддреЛ рдЖрдгрд┐ рдЖрдЬрд╛рд░реА service рд▓рд╛ рд╕рд╛рд╡рд░рд╛рдпрд▓рд╛ рдЬрд╛рдЧрд╛ рджреЗрддреЛ.
- Bulkhead тАФ рдкреНрд░рддреНрдпреЗрдХ dependency рдХрд┐рдВрд╡рд╛ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░рдЪреНрдпрд╛ customer рд╕рд╛рдареА рд╡реЗрдЧрд│реЗ pools (threads, connections, queues, рдЕрдЧрджреА servers). рдЕрдбрдХрд▓реЗрд▓реА dependency рдлрдХреНрдд рддрд┐рдЪрд╛рдЪ pool рд╕рдВрдкрд╡реВ рд╢рдХрддреЗ.
- Graceful degradation тАФ launch рдЖрдзреА рдард░рд╡рд╛ рдХреА рдХрд╛рдп рдЕрддреНрдпрд╛рд╡рд╢реНрдпрдХ рдЖрд╣реЗ (рд╕реВрдЪрдиреЗрдЪрд╛ рдордЬрдХреВрд░) рдЖрдгрд┐ рдХрд╛рдп рдмрдВрдж рд╣реЛрдК рд╢рдХрддреЗ (photos, "312 рдЬрдгрд╛рдВрдиреА рд╡рд╛рдЪрд▓реА", рд╢рд┐рдлрд╛рд░рд╕реА). Error рдРрд╡рдЬреА рдЫреЛрдЯреЗ рдЙрддреНрддрд░ рджреНрдпрд╛. "5 рдорд┐рдирд┐рдЯреЗ рдЬреБрдиреА" рдЕрд╢реА рдЦреВрдг рдЕрд╕рд▓реЗрд▓реА cached рдкреНрд░рдд рдЕрдиреЗрдХрджрд╛ рдЪрд╛рд▓рддреЗ.
- Multi-AZ рдЪреЗ рдЧрдгрд┐рдд тАФ n Availability Zones рдкреИрдХреА рдкреНрд░рддреНрдпреЗрдХрд╛рдд рдПрдХ рдкреНрд░рдд рдЕрд╕реЗрд▓, рддрд░ рддреА рд╕рдЧрд│реНрдпрд╛ рдмрдВрдж рдЕрд╕рддреАрд▓ рддреЗрд╡реНрд╣рд╛рдЪ рдмрдВрдж рдкрдбрддреЗ: 1 тИТ (1 тИТ a)тБ┐, рдЬрд░ zones рд╕реНрд╡рддрдВрддреНрд░рдкрдгреЗ рдЕрдкрдпрд╢реА рд╣реЛрдд рдЕрд╕рддреАрд▓ рддрд░. рд╕рд╛рдорд╛рдИрдХ bug рдХрд┐рдВрд╡рд╛ рд╡рд╛рдИрдЯ deploy рд╕реНрд╡рддрдВрддреНрд░ рдирд╕рддреЛ.
- рд╕рд╛рдЦрд│реНрдпрд╛ availability рдХрдореА рдХрд░рддрд╛рдд тАФ рдУрд│реАрддреАрд▓ hard dependencies рдЪрд╛ рдЧреБрдгрд╛рдХрд╛рд░ рд╣реЛрддреЛ: a ├Ч a ├Ч a. рдкреНрд░рддреНрдпреЗрдХ рдЬрд╛рд╕реНрддреАрдЪреА hard dependency рдПрдХреВрдг availability рдХрдореА рдХрд░рддреЗ (рдзрдбрд╛ 09). рдкреНрд░рддреА рдЖрдгрд┐ fallbacks рддреА рд╡рд╛рдврд╡рддрд╛рдд.
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдгрд╛рд▓рд╛ рдЕрдкрдпрд╢рд╛рдЪреА рдпреЛрдЬрдирд╛ рдорд┐рд│реЗрдкрд░реНрдпрдВрдд рдЖрдХреГрддреА рдЕрд░реНрдзреАрдЪ рдЕрд╕рддреЗ. Timeout рдирд╕реЗрд▓ рддрд░ рдПрдХ рдЕрдбрдХрд▓реЗрд▓реА service рдкреНрд░рддреНрдпреЗрдХ thread рдзрд░реВрди рдареЗрд╡рддреЗ. Jitter рд╢рд┐рд╡рд╛рдпрдЪреЗ retries рдЫреЛрдЯреНрдпрд╛ рдЕрдбрдерд│реНрдпрд╛рдЪреЗ рд╡рд╛рджрд│ рдХрд░рддрд╛рдд. Fallback рдирд╕рд▓реЗрд▓реЗ design "photos рдирд╛рд╣реАрдд" рдЪреЗ "app рдирд╛рд╣реА" рдХрд░рддреЗ. рд╣реЗ design рдЪреЗ рдирд┐рд░реНрдгрдп рдЖрд╣реЗрдд тАФ outage рдЪреНрдпрд╛ рд╡реЗрд│реА рдЬреЛрдбрдгреНрдпрд╛рдкреЗрдХреНрд╖рд╛ рддреЗ рдпреЛрдЬрдиреЗрд╡рд░ рд▓рд┐рд╣рд┐рдгреЗ рдЦреВрдк рд╕реНрд╡рд╕реНрдд рдЕрд╕рддреЗ.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
design/designs.py рдордзреАрд▓ call_chain(hops, ms_each, availability_each)
calls рдЪреНрдпрд╛ рдПрдХрд╛ рдУрд│реАрдЪреА latency (hops ├Ч ms_each) рдЖрдгрд┐ availability (availability_each ** hops)
рдкрд░рдд рдХрд░рддреЛ. design/demo.py рдордзреАрд▓ resilience() рдПрдХрд╛ page рдЪреЗ
timeout budget рдЖрдгрд┐ multi-AZ рдмреЗрд░реАрдЬ 1 тИТ (1 тИТ 0.995)┬│ рдЫрд╛рдкрддреЛ. Snippet budget рдЪреА рдмреЗрд░реАрдЬ
рдХрд░рддреЛ, рд╕рд╛рдЦрд│реА рд╡рд╛рдврд╡рддреЛ, рдЖрдгрд┐ рдерд░рд╛рдВрдордзреАрд▓ retries рдореЛрдЬрддреЛ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 design/demo.py resilience
python3 - <<'EOF'
import sys; sys.path.insert(0, "design"); from designs import call_chain
budget, deps = 800, {"auth": 50, "notices DB": 150, "photo service": 300}
print("timeouts add up to", sum(deps.values()), "ms of an", budget, "ms budget тЖТ left for our own work:", budget - sum(deps.values()), "ms")
for hops in (1, 3, 5):
c = call_chain(hops, 20, 0.999); print(f"{hops} hard dependencies in a line тЖТ {c['latency_ms']:>3} ms, {c['availability']:.3%}")
for a in (0.99, 0.995):
print(f"one AZ {a:.1%} тЖТ", " ┬╖ ".join(f"{n} AZs {1 - (1 - a) ** n:.6%}" for n in (1, 2, 3)))
for tries in (1, 2, 3):
print(f"3 layers each trying {tries}x тЖТ up to {tries ** 3} calls reach the sick service for one click")
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
resilience рд╣реЗ рдЫрд╛рдкрддреЛ:
тФАтФА the budget for one page is 800 ms; each dependency gets a timeout inside it
auth timeout 50 ms
notices DB timeout 150 ms
photo service timeout 300 ms
photo service down тЖТ show notices without photos (degrade), breaker open, retries with jitter
one AZ 99.5% тЖТ three AZs 99.99999% ┬╖ deeper dive: the Scaling school, lesson 13
рддреБрдордЪрд╛ snippet рд╣реЗ рдЫрд╛рдкрддреЛ:
timeouts add up to 500 ms of an 800 ms budget тЖТ left for our own work: 300 ms
1 hard dependencies in a line тЖТ 20 ms, 99.900%
3 hard dependencies in a line тЖТ 60 ms, 99.700%
5 hard dependencies in a line тЖТ 100 ms, 99.501%
one AZ 99.0% тЖТ 1 AZs 99.000000% ┬╖ 2 AZs 99.990000% ┬╖ 3 AZs 99.999900%
one AZ 99.5% тЖТ 1 AZs 99.500000% ┬╖ 2 AZs 99.997500% ┬╖ 3 AZs 99.999988%
3 layers each trying 1x тЖТ up to 1 calls reach the sick service for one click
3 layers each trying 2x тЖТ up to 8 calls reach the sick service for one click
3 layers each trying 3x тЖТ up to 27 calls reach the sick service for one click
Tests рдордзреНрдпреЗ тЬЕ L13 three copies beat one рдЕрд╕рддреЗ.
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рддреАрди timeouts 800 ms рдЪреНрдпрд╛ page рдкреИрдХреА 500 ms рд╡рд╛рдкрд░рддрд╛рдд, API рдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдХрд╛рдорд╛рд╕рд╛рдареА 300 ms рдЙрд░рддрд╛рдд тАФ рдЖрдгрд┐ photo call рдЪреНрдпрд╛ retry рд╕рд╛рдареА рдЬрд╛рдЧрд╛рдЪ рдЙрд░рдд рдирд╛рд╣реА (рдЖрдгрдЦреА 300 ms), рдореНрд╣рдгреВрди рддреНрдпрд╛ call рд▓рд╛ рдХреЛрдгрддрд╛рд╣реА retry рдорд┐рд│рдд рдирд╛рд╣реА. 99.9% рдЪреНрдпрд╛ рдкрд╛рдЪ hard dependencies 99.501% рдкрд░реНрдпрдВрдд рдШрд╕рд░рддрд╛рдд. 99.5% рдЪрд╛ рдПрдХ zone рджреЛрди zones рд╕рд╣ 99.9975% рдЖрдгрд┐ рддреАрди рд╕рд╣ 99.999988% рд╣реЛрддреЛ (demo рддреЗ рдЧреЛрд▓ рдХрд░реВрди 99.99999% рдЫрд╛рдкрддреЛ) тАФ рдлрдХреНрдд zones рд╕реНрд╡рддрдВрддреНрд░рдкрдгреЗ рдЕрдкрдпрд╢реА рд╣реЛрдд рдЕрд╕реЗрдкрд░реНрдпрдВрдд. рдЖрдгрд┐ рддреАрди рдерд░рд╛рдВрд╡рд░ "рдлрдХреНрдд 3 retries" рдореНрд╣рдгрдЬреЗ рдЖрдзреАрдЪ рдЖрдЬрд╛рд░реА рдЕрд╕рд▓реЗрд▓реНрдпрд╛ service рдХрдбреЗ 27 рдкрд░реНрдпрдВрдд calls.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- user рдЪреНрдпрд╛ budget рд╡рд░реВрди рдард░рд╡рдгреНрдпрд╛рдРрд╡рдЬреА рдПрдХ-рдПрдХ рдХрд░реВрди рдирд┐рд╡рдбрд▓реЗрд▓реЗ timeouts ("30 s рд╕реБрд░рдХреНрд╖рд┐рдд рдЖрд╣реЗ")
- callee рдЪрд╛ timeout рддреНрдпрд╛рдЪреНрдпрд╛ caller рдкреЗрдХреНрд╖рд╛ рдореЛрдард╛ тАФ caller рд╕реЛрдбреВрди рджреЗрддреЛ, рдХрд╛рдо рдХреЛрдгрд╛рд╕рд╛рдареАрдЪ рдирд╕рддрд╛рдирд╛ рдЪрд╛рд▓реВ рд░рд╛рд╣рддреЗ
- рдкреНрд░рддреНрдпреЗрдХ рдерд░рд╛рд╡рд░ retries, рдЖрдгрд┐ non-idempotent writes рдЪреЗ retries
- fallback рдирд╕рд▓реЗрд▓рд╛ breaker тАФ рдкрдЯрдХрди fail рдЭрд╛рд▓реЗ рддрд░реА рдкрд╛рд▓рдХрд╛рд▓рд╛ рдХрд╛рд╣реАрддрд░реА рдЙрддреНрддрд░ рд╣рд╡реЗрдЪ
- рдкреНрд░рддреНрдпреЗрдХ dependency рд╕рд╛рдареА рдПрдХрдЪ рд╕рд╛рдорд╛рдИрдХ connection pool тАФ рд╣рд│реВ dependency рд╕рдЧрд│реА connections рдШреЗрддреЗ
- рдПрдХрдЪ NAT gateway, рдПрдХрдЪ cache node рдХрд┐рдВрд╡рд╛ single-AZ database рдЕрд╕рд▓реЗрд▓реЗ "multi-AZ"
- рдХрдзреАрдЪ рддрдкрд╛рд╕рд▓реА рди рдЧреЗрд▓реЗрд▓реА рдЕрдкрдпрд╢рд╛рдЪреА рдпреЛрдЬрдирд╛ тАФ staging рдордзреНрдпреЗ рдореБрджреНрджрд╛рдо рдПрдХ dependency рдореЛрдбрд╛
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
рдЦрд▒реНрдпрд╛ account рд╡рд░ тАФ рдкреНрд░рддреНрдпреЗрдХ call рд╕реЛрдмрдд deadline рдЦрд╛рд▓реА рдкрд╛рдард╡рд╛, рдЖрдгрд┐ рдЦреВрдк рдХрдореА рд╡реЗрд│ рдЙрд░рд▓рд╛ рдЕрд╕реЗрд▓ рддрд░ рд▓рд╡рдХрд░ рдерд╛рдВрдмрд╛:
import time, requests
def call(url, deadline):
left = deadline - time.monotonic()
if left < 0.05: # under 50 ms left: do not start
raise TimeoutError("budget spent")
return requests.get(url, timeout=(0.1, min(left, 0.3)), # connect, read (s)
headers={"X-Request-Deadline": str(round(left * 1000))})
deadline = time.monotonic() + 0.8 # the page budget: 800 ms
Code рдордзрд▓рд╛ bulkhead тАФ рдПрдХрд╛ рд╡реЗрд│реА рдЬрд╛рд╕реНрддреАрдд рдЬрд╛рд╕реНрдд 20 photo calls, рдореНрд╣рдгрдЬреЗ photo service рдХрдзреАрдЪ рд╕рдЧрд│реЗ workers рдШреЗрдК рд╢рдХрдд рдирд╛рд╣реА:
import threading
photo_slots = threading.BoundedSemaphore(20)
def photos_for(notice_id, deadline):
if not photo_slots.acquire(timeout=0.01):
return [] # bulkhead full тЖТ degrade: no photos
try:
return call(f"https://photos.internal/notices/{notice_id}", deadline).json()
except Exception:
return [] # photo service slow or down тЖТ degrade
finally:
photo_slots.release()
Backoff рдЖрдгрд┐ jitter рд╕рд╣ AWS SDK retries, рдЖрдгрд┐ Multi-AZ database:
export AWS_RETRY_MODE=standard AWS_MAX_ATTEMPTS=3
aws rds modify-db-instance --db-instance-identifier notices-db --multi-az --apply-immediately
Service mesh рдордзреАрд▓ circuit breakers, outlier detection, DLQs, health checks рдЖрдгрд┐ AWS FIS рд╕рд╣ chaos tests рд╕рд╛рдареА, рдкрд╛рд╣рд╛ Scaling рд╢рд╛рд│рд╛, рдзрдбрд╛ 13.
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: рдкреНрд░рддреНрдпреЗрдХ design рдордзреНрдпреЗ рдПрдХ "failure" table рдЬреЛрдбрд╛: рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдгрд╛рд╕рд╛рдареА рдПрдХ row, рддреНрдпрд╛рдЪрд╛ timeout, retry рдирд┐рдпрдо, breaker, bulkhead рдЖрдгрд┐ fallback рд╕рд╣. рд░рд┐рдХрд╛рдорд╛ рдХрдкреНрдкрд╛ рдореНрд╣рдгрдЬреЗ рднрд╡рд┐рд╖реНрдпрд╛рддрд▓рд╛ outage.
тПня╕П рдкреБрдвреЗ
рднрд╛рдЧ рдЕрдкрдШрд╛рддрд╛рдиреЗ рдЕрдкрдпрд╢реА рд╣реЛрддрд╛рдд. рдХрд╛рд╣реА рд▓реЛрдХ рддреЗ рдореБрджреНрджрд╛рдо рдореЛрдбрдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░рддрд╛рдд. Design рдордзреВрдирдЪ security.
git checkout lesson-14-security