Bu qatlamda nima bor
Core darslik asoslarni berdi. Bu Deep qatlam senior darajadagi chuqur mexanikani ochadi: OAuth2/OIDC/mTLS auth, rate limit algoritmlari va distributed limit, gateway HA va masshtab, plugin/filter arxitektura, gRPC va WebSocket gateway, canary va versiyalash, Kong/Envoy sozlash. Oxirida — kuzatuvchanlik, xavfsizlik va senior cheklist.
OAuth2, OIDC, JWKS va mTLS
oauth2 · oidc · jwks · mTLSCore’da JWT’ni gateway’da tekshirdik. Senior darajada bu butun OAuth2/OIDC oqimi va mTLS bilan to‘liq xavfsizlik enforcement nuqtasiga aylanadi.
OAuth2 — rollar va grant turlari
OAuth2’da 4 rol: resource owner (foydalanuvchi), client (ilova), authorization server (token beruvchi), resource server (API — gateway bu yerda himoyachi). Asosiy grant turlari:
- Authorization Code + PKCE — SPA va mobil uchun (eng xavfsiz foydalanuvchi oqimi).
- Client Credentials — xizmatlararo (foydalanuvchisiz, service-to-service).
OIDC — OAuth2 ustidagi identity qatlami
OAuth2 ruxsat (authorization) uchun; OIDC unga kimligi (authentication)ni qo‘shadi: ID token (foydalanuvchi kimligi) va access token (nima qila oladi). Gateway access token’ni tekshiradi:
// Gateway access token'ni JWKS (auth server public kalitlari) bilan tekshiradi
const jwks = jwksClient({ jwksUri: 'https://auth.sayt.uz/.well-known/jwks.json' });
async function verifyAtGateway(token: string) {
const { header } = decodeJwt(token); // kid (key id) ni ol
const key = await jwks.getSigningKey(header.kid); // mos public kalit
const claims = jwt.verify(token, key.getPublicKey(), {
issuer: 'https://auth.sayt.uz', // iss tekshiruvi
audience: 'api.sayt.uz', // aud tekshiruvi
});
assertScopes(claims.scope, 'orders:read'); // ruxsat (scope)
return claims; // downstream'ga uzatiladi: X-User-Id, X-Scopes (ishonchli zona)
}
Opaque token (JWT emas) bo‘lsa — gateway auth server’ning introspection endpointidan tekshiradi (RFC 7662). mTLS — yuqori xavfsizlik yoki xizmatlararo: klient ham sertifikat ko‘rsatadi, gateway ikki tomonlama tekshiradi. Muhim qoida: token bir marta gateway’da tekshiriladi, ichki xizmatlar uzatilgan claim’larga ishonadi (zona ichidagi ishonch).
Algoritmlar va distributed limit
token bucket · redis luaCore’da "rate limit" dedik. Senior darajada qaysi algoritm ekani muhim — har biri burst (to‘satdan portlash) va silliqlikni turlicha boshqaradi.
| Algoritm | Qanday | Kelishuv |
|---|---|---|
| Fixed window | Har N soniyada X so‘rov (oddiy hisoblagich) | Oson; lekin oyna chegarasida 2X burst mumkin |
| Sliding window | Suriluvchi oyna (silliqroq hisob) | Adolatli; biroz ko‘proq hisoblash/xotira |
| Token bucket | Token to‘ldiriladi; har so‘rov 1 token oladi | Burst’ga ruxsat (bucket hajmigacha) + o‘rtacha tezlik |
| Leaky bucket | Chiqish doimiy tezlikda "oqadi" | Chiqishni silliqlaydi; burst’ni navbatlaydi |
Eng keng tarqalgani — token bucket (burst’ni ham, o‘rtacha tezlikni ham boshqaradi). Lekin gateway ko‘p nusxada ishlaydi — demak hisoblagich umumiy (Redis) va atomik bo‘lishi shart:
-- TOKEN BUCKET (atomik, Redis Lua) — burst'ga ruxsat, sekin to'ldiriladi
local capacity = tonumber(ARGV[1]) -- max token (burst hajmi)
local rate = tonumber(ARGV[2]) -- sekundiga to'ldirish tezligi
local now = tonumber(ARGV[3])
local tokens = tonumber(redis.call('HGET', KEYS[1], 'tokens') or capacity)
local last = tonumber(redis.call('HGET', KEYS[1], 'ts') or now)
tokens = math.min(capacity, tokens + (now - last) * rate) -- o'tgan vaqtda to'ldir
if tokens < 1 then return 0 end -- token yo'q -> 429 RAD
redis.call('HSET', KEYS[1], 'tokens', tokens - 1, 'ts', now)
redis.call('EXPIRE', KEYS[1], 3600)
return 1 -- ruxsat
Gateway’ning 5 nusxasi har biri o‘z lokal hisoblagichini yuritsa — chegara 5 barobar oshib ketadi. Shuning uchun hisoblagich Redis’da markazlashtiriladi va Lua bilan atomik yangilanadi (yuqorida). Aks holda race condition limitni buzadi.
Limitlar bir nechta kalit bo‘yicha bo‘ladi: per-user, per-IP, per-API-key, per-endpoint. Va bosqichli: bepul tarif 100/min, premium 10000/min. Gateway buni token/key’dagi claim’ga qarab qo‘llaydi.
Gateway HA, masshtab, control plane
stateless · data/control planeGateway — butun trafikning bo‘g‘zi. Core’da "stateless + LB" dedik; senior darajada holat qayerda yashaydi va bo‘g‘oz bo‘lib qolmaslik muhim.
Holat qayerda
Gateway’ning o‘zi stateless bo‘lsa, gorizontal masshtablanadi (5-mavzu). Lekin ba’zi holatlar tashqarida saqlanadi:
- Rate-limit hisoblagichlari → Redis (umumiy, 2-bo‘lim).
- Konfiguratsiya (route, plugin) → control plane / DCS (har nusxa bir xil ko‘radi).
- Sessiya → yo‘q! Stateless token (JWT) — gateway hech narsa eslab qolmaydi.
Bo‘g‘oz bo‘lib qolmaslik
1. Async I/O va upstream’larga connection pooling (har so‘rovga yangi ulanish ochma). 2. Har upstream chaqiruviga timeout + circuit breaker (14-mavzu) — bitta sekin xizmat butun gateway’ni bloklamasin. 3. Og‘ir ish (transform, aggregation) hot path’da minimal bo‘lsin. 4. Konfiguratsiyani restart’siz (hot reload) yangilash — deploy uzilish bermasin.
Yetuk gateway’lar (Kong, Envoy) ikkiga bo‘linadi: data plane (haqiqiy trafikni tashiydi — tez, ko‘p nusxa) va control plane (konfiguratsiyani boshqaradi va data plane’ga tarqatadi). Bu masshtab va boshqaruvni ajratadi (7-mavzudagi Patroni/DCS g‘oyasiga o‘xshash).
Plugin/filter zanjiri
lifecycle · kong · envoy · wasmGateway’ning kuchi — kengaytiriluvchanlik: vazifalar alohida plugin/filterlar sifatida, so‘rov hayot siklida ketma-ket ishlaydi. Senior bu zanjir va uning tartibini biladi.
So‘rov hayot sikli (request lifecycle)
Har so‘rov plugin’lar zanjiridan o‘tadi. Tartib hal qiluvchi: auth rate-limit’dan oldin (avtorizatsiyasiz so‘rovni sanab o‘tirma), transform route’dan oldin, logging oxirida:
// Gateway so'rov hayot sikli — plugin'lar ZANJIRI (tartib MUHIM)
// kelgan so'rov
// -> [cors] CORS tekshiruvi
// -> [auth] JWT/OAuth2 (1-bo'lim)
// -> [rate-limit] token bucket (2-bo'lim)
// -> [transform] so'rovni moslash (header, versiya)
// -> [router] to'g'ri upstream'ga yo'naltirish
// => UPSTREAM xizmat
// <- [resp-transform] javobni moslash
// <- [logging] metrika, trace (12-mavzu)
// javob mijozga
Kong: plugin’lar Lua’da (OpenResty asosida), har fazaga ulanadi (access, header_filter, body_filter, log). Envoy: HTTP filter chain — har filter so‘rovni qayta ishlaydi; WASM bilan istalgan tilda custom filter yozish mumkin. NestJS’da bu rol — guard/interceptor/middleware zanjiri.
Plugin’lar hot pathda — har so‘rovda ishlaydi. Sekin yoki bloklovchi plugin butun gateway’ni sekinlashtiradi. Plugin’larni tez, async va minimal tut; og‘ir ishni (masalan, tashqi API chaqiruvi) plugin ichida sinxron qilma.
gRPC va WebSocket gateway
grpc-web · ws handshakeOddiy REST’dan tashqari, gateway gRPC va WebSocketni ham boshqarishi kerak — ularning har biri maxsus ishlov talab qiladi.
gRPC gateway
gRPC — HTTP/2 ustida ishlaydi, demak gateway h2ni qo‘llashi shart. Ikki muhim vazifa:
- gRPC-Web transcoding: brauzer xom gRPC qila olmaydi — gateway brauzerning HTTP/JSON so‘rovini gRPC’ga (va aksincha) tarjima qiladi (Envoy
grpc_web/grpc_json_transcoderfilteri). - Load balancing: gRPC uzoq HTTP/2 ulanishidan foydalanadi — L7 (har so‘rov) balansi kerak (5-mavzu Deep), aks holda yuk notekis.
WebSocket gateway
1. Upgrade: gateway HTTP→WS "upgrade"ni to‘g‘ri proksi qilishi kerak. 2. Auth: WebSocket’da har xabarga header yuborib bo‘lmaydi — token ulanish (handshake) paytida tekshiriladi (query param yoki subprotocol orqali). 3. Sticky + draining: ulanish uzoq yashaydi va bitta nusxaga bog‘lanadi — sticky kerak, deploy’da ehtiyotkor draining (5-mavzu Deep).
Server-Sent Events (SSE) va gRPC streaming uchun gateway buffer qilmasdan oqimni o‘tkazishi kerak (response buffering o‘chiriladi), aks holda real-time yo‘qoladi.
Canary va versiyalash
weighted routing · blue-greenGateway — trafikning markazi, demak u versiyalash va bosqichli chiqarish (canary) uchun ideal joy.
API versiyalash
Strategiyalar: URI (/v1/orders — eng aniq), header (Accept-Version), content negotiation (Accept). Gateway versiyaga qarab to‘g‘ri backend’ga yo‘naltiradi — eski va yangi versiya yonma-yon yashaydi.
Canary release — gateway trafikni bo‘ladi
Yangi versiyaga avval kichik % trafik yo‘naltiriladi, kuzatiladi (xato/kechikish), so‘ng asta oshiriladi. Gateway weighted routing bilan buni qiladi:
# Canary: trafikning 5% YANGI versiyaga (Envoy weighted clusters)
route_config:
virtual_hosts:
- name: api
routes:
- match: { prefix: "/v1/orders" }
route:
weighted_clusters:
clusters:
- { name: orders-v1, weight: 95 }
- { name: orders-v2, weight: 5 } # canary — kuzatib, asta oshiriladi
Blue-green: butun trafikni birdan yangi versiyaga (orqaga qaytarish oson). A/B test: header/foydalanuvchi bo‘yicha turli versiyaga (xususiyatni sinash). Deprecation: eski versiyaga Sunset header bilan ogohlantirish va versiya hayot siklini boshqarish.
Kong va Envoy sozlash
declarative · xDSSenior amalda gateway’ni odatda deklarativ konfiguratsiya bilan boshqaradi (kod emas) — bu GitOps va audit uchun qulay.
Kong — deklarativ, plugin asosida
# Kong — deklarativ konfiguratsiya (GitOps'ga mos, kod emas)
_format_version: "3.0"
services:
- name: orders
url: http://orders-svc:3000
routes:
- name: orders-route
paths: ["/v1/orders"]
plugins:
- name: jwt # auth (1-bo'lim)
- name: rate-limiting
config: { minute: 100, policy: redis } # distributed limit (2-bo'lim)
- name: prometheus # metrika (8-bo'lim)
Envoy — filter chain, dinamik (xDS)
# Envoy — gateway sifatida: listener -> filter chain -> route -> cluster
http_filters:
- name: envoy.filters.http.jwt_authn # 1) JWT tekshir
- name: envoy.filters.http.ratelimit # 2) rate limit
- name: envoy.filters.http.grpc_web # 3) gRPC-Web transcoding (5-bo'lim)
- name: envoy.filters.http.router # 4) route -> upstream cluster
| Kong | Envoy | Cloud (AWS API GW) | |
|---|---|---|---|
| Asos | Nginx/OpenResty + Lua | C++ proksi, xDS | Boshqariladigan |
| Kuchli tomon | Boy plugin ekotizimi | Tezlik, mesh bilan integratsiya | Operatsiya yo‘q, serverless |
| Qachon | Plugin/siyosat ko‘p | Yuqori masshtab, gRPC, mesh | AWS ichida, tez boshlash |
Oddiy ehtiyoj + NestJS qulay → kichik o‘z gateway’ing (Core). Boy plugin/siyosat → Kong. Yuqori masshtab, gRPC, service mesh bilan birga → Envoy. AWS ichida tez yechim → cloud API Gateway. Deklarativ config’ni Git’da saqlab, CI orqali qo‘lla.
Tracing, xavfsizlik, senior cheklist
Kuzatuvchanlik va xavfsizlik
| Soha | Nima |
|---|---|
| Tracing | Trace ID’ni generatsiya/uzatish (W3C traceparent) — butun yo‘l ko‘rinadi (12-mavzu) |
| Metrika | Per-route so‘rov soni, kechikish p99, xato darajasi, rate-limit rad soni |
| WAF / validatsiya | So‘rov sxemasini, hajmini, CORS’ni tekshirish (zararli kirishni to‘sish) |
| Audit log | Kim, nima, qachon — markazlashgan (gateway ideal joy) |
Senior tayyorlik cheklisti
| Savol / amaliyot | Bo‘lim |
|---|---|
| OAuth2 grant turlari, OIDC, JWKS bilan JWT tekshirish, mTLS’ni bilaman | 1 |
| Rate limit algoritmlarini (token bucket) va distributed (Redis Lua) limitni qo‘llayman | 2 |
| Gateway’ni stateless + LB qilaman; holatni Redis/control plane’ga chiqaraman | 3 |
| Plugin/filter zanjiri va tartibini to‘g‘ri quraman; hot path’ni yengil tutaman | 4 |
| gRPC-Web transcoding va WebSocket auth/draining’ni boshqaraman | 5 |
| Versiyalash va canary/blue-green’ni gateway’da weighted routing bilan qilaman | 6 |
| Kong/Envoy’ni deklarativ config bilan sozlayman; to‘g‘ri yechimni tanlayman | 7 |
| Trace/metrika/WAF/audit’ni gateway’da markazlashtaraman | 8 |
Bu 8-mavzuning Deep/Senior qatlami edi — Core bilan birga, API Gateway endi to‘liq.
Keyingi mavzu: “9-mavzu: CQRS” — o‘qish va yozishni alohida modellarga ajratish. Core’dan boshlaymiz.