Onlarca mikroserviste tekrar eden token doğrulama, yetkilendirme, kota, loglama ve dönüşüm işlerini tek bir politika noktasında toplayan; bunu yaparken o noktayı sistemin en kırılgan yeri hâline getirmeyen mimari.
Bu sunum bir seviye seçtirmez; sizi seviyeler boyunca yürütür. Her aşama bir öncekinin üstüne biner: önce ortak dili kurarız, sonra tasarım kararlarını veririz, ardından üretim gerçekleriyle yüzleşiriz ve en sonunda kendi gateway'imizi yazmayı tartışırız. Solda gördüğünüz renkli şerit ve üstteki etiket, her an hangi aşamada olduğunuzu söyler.
Aşama 1 tek başına konunun omurgasını verir. Animasyonlu anlatımları izleyin, kod bloklarını atlayın — aşama 2'nin sonunda zaten hazır olacaksınız.
Asıl kazanç aşama 2 ve 3'te: karar tabloları, yapılandırma örnekleri ve "hangi politika hangi rotaya" eşlemeleri. Aşama 1'i hızlı geçin.
Aşama 3 ve 4 doğrudan size: uyarlanabilir eşzamanlılık, hücresel dağıtım, eklenti mimarileri, custom gateway iç tasarımı ve ürünlerde bulunmayan farklılaştırıcılar.
Vaka metnindeki tablo tanıdık: mikroservislere doğrudan erişilebiliyor ve her servis token doğrulama, yetkilendirme, rate limit, loglama, correlation ID, istek/yanıt dönüşümü, servis adresi çözümleme ve versiyon kontrolünü ayrı ayrı yapıyor. Sorun bu işlerin yapılması değil — her yerde tekrar edilmesi.
JWT doğrulamayı kırk yerde yazarsanız kırk farklı doğru olur: biri aud bakmaz, biri alg allowlist'i koymaz, biri anahtar rotasyonunu kaçırır.
"Bugünden itibaren tüm B2B trafiğinde mTLS zorunlu" cümlesi kırk takvim, kırk sprint demektir. Politika hızınız en yavaş takımın hızına eşitlenir.
Correlation ID her serviste farklı isimle üretiliyorsa uçtan uca akış birleştirilemez. Olay müdahalesinde kaybedilen dakikalar buradan çıkar.
İstemci doğrudan on servise konuşuyorsa servis bölünmesi istemci sürümü gerektirir. Mobilde bu, aylarca eski sürüm desteklemek demektir.
Bu aşamayı bitiren biri, bir mimari toplantısında geçen her cümleyi anlar. Ürün seçmez, yapılandırma yazmaz — ne olduğunu ve neyin neye benzemediğini bilir.
Sunumun geri kalanında sürekli geçecek terimlerin tamamı burada. Her kavram, şemada tam olarak nereye ait olduğuyla birlikte gösterilir — çünkü bu terimlerin çoğu yanlış yerde kullanıldığı için tartışmalar tıkanır.
API Gateway, istemciler ile arka uç servisleri arasında konumlanan, her isteği anlayan (yalnızca taşımayan) ve üzerinde politika uygulayan bir ters vekildir. Sorumlulukları dört gruba ayrılır; diyagramda her grup ayrı bir katman olarak gösterilmiştir.
Bu listedeki her madde gateway'i yeniden bir monolite dönüştürür.
Her isteği karşılar, politikayı uygular, upstream'e taşır. İstek yolundadır, trafikle ölçeklenir. Düşerse trafik durur — tam karartma. Örnek: Envoy, Kong node, SCG uygulaması.
Yapılandırmayı üretir, doğrular ve veri düzlemine dağıtır. İstek yolunun dışındadır. Düşerse trafik akmaya devam etmeli — fail static. Örnek: Istiod, Kong CP, Gateway API controller.
Aradaki fark yeteneklerde değil, niyette ve istek hakkında sahip olunan bilgi derinliğindedir. 2026 itibarıyla sınırlar bulanıklaşmış durumda — Envoy dördünü de yapabilir — ancak mimari diyagramda bu ayrımı korumak, doğru düşünmenin göstergesidir.
| Boyut | Load Balancer | Reverse Proxy | API Gateway | Service Mesh |
|---|---|---|---|---|
| Birincil niyet | Kapasite ve erişilebilirlik | Güvenlik ve performans | Politika ve API yönetimi | Servisler arası güvenlik |
| Katman | L4 (bazen L7) | L7 | L7 + API semantiği | L4+L7, her pod |
| Ne bilir | Bağlantı, port, sağlık | Yol, header, TLS | API, tüketici, kota, sürüm, şema | Servis kimliği, çağrı grafiği |
| Trafik yönü | Kuzey-güney | Kuzey-güney | Kuzey-güney | Doğu-batı |
| Kimlik kavramı | Yok | Zayıf | Tüketici / kullanıcı / kurum | Servis (SPIFFE, mTLS) |
| Tipik ürün | NLB · HAProxy L4 · IPVS | NGINX · HAProxy · Caddy | Kong · APISIX · SCG · Apigee | Istio · Linkerd · Cilium |
| Yapılandırma sahibi | Ağ ekibi | Platform ekibi | API ekibi + ürün ekipleri | Platform ekibi |
Işıkları açık tutar. Hacme odaklıdır: paketleri A'dan B'ye verimli taşır.
Kötüleri dışarıda, veriyi hızlı tutar. TLS, önbellek, temel filtreleme.
Trafiğin iş kurallarını yönetir. İçeriğe bakar: gövde, header, token, kota, sürüm.
Servisler arasını yönetir. mTLS, retry, gözlemlenebilirlik — uygulama kodu değişmeden.
İstek zincirin içinden ileri doğru (pre) geçer, upstream'e gider, yanıt aynı zincirden geri doğru (post) döner. Aşağıdaki sahnede gerçek istekler zincirden geçiyor; bazıları kimlik veya kota bandında kesiliyor ve arka uca hiç ulaşmıyor.
Gövde boyutu, header sayısı ve rota eşleşmesi gibi maliyetsiz kontroller; JWT imzası veya Redis çağrısı gibi pahalı işlemlerden önce gelmeli. Aksi hâlde geçersiz istekler size CPU'ya mal olur — doğrudan DoS yüzeyi oluşturur.
Rate limit anahtarı kullanıcı/kurum ise kimlik çözülmeden kota uygulanamaz. Ama anonim trafiğe karşı IP bazlı kaba bir limit kimlikten önce durmalı; aksi hâlde kimlik doğrulama ucu maliyetsiz bir DoS hedefine dönüşür.
İstemciden gelen X-User-Id, X-Internal-*, X-Forwarded-For zincirin en başında silinmeli. Bu tek satır, kimlik sahteciliğinin en yaygın yolunu kapatır.
En yüksek öncelikli filtre pre'de ilk, post'ta son çalışır. Bu yüzden korelasyon ve metrik filtreleri en dışta olmalı ki her şeyi — hataları dâhil — ölçebilsinler.
Kurallar tek tek doğru görünür; asıl değer birlikte uygulandıklarında ortaya çıkar. Aşağıdaki zincir bu dört kuralın sonucudur: ucuz kontroller solda, kimlik ortada, pahalı işler kimlikten sonra, ölçüm en dışta. Paket soldan sağa ilerlerken her durakta neden orada olduğu gösterilir.
Bu 16 durak, sunumun geri kalanının haritasıdır — sonraki her bölüm bunlardan birini derinleştirir. Aşağıdaki hat, bir metro hattı gibi okunur: soldan sağa duraklar, üstte pre aşaması, sağ uçta arka uca çıkış, altta post dönüşü. Bir durağa tıklayın veya hattı baştan sona oynatın.
Terimler diyagramın yönünden gelir: istemciler yukarıda (kuzey), veri aşağıda (güney). Gateway kuzey-güney trafiğin sahibidir; servislerin birbirine yaptığı yatay çağrılar doğu-batı trafiğidir ve mesh'in alanıdır. BFF ile GraphQL router gateway'in arkasında, ayrı bir katman olarak yaşar — yerine değil.
Bütün istemciler aynı şeyi istiyorsa doğru seçim. Mobil küçük payload, web tam detay isteyince gateway'de uzlaşma başlar ve endpoint şişer.
İstemci deneyimi başına ayrı, o ekibin sahip olduğu ince bir servis. Gateway'in arkasında durur. Uber'in "Presentation Layer"ı tam olarak budur.
Veri modeli yoğun biçimde bağlıysa ve ön uca özerklik vermek istiyorsanız. Router yine gateway'in arkasındadır; kimlik, kota ve TLS hâlâ gateway'in işidir.
Artık "nedir" değil "nasıl kurulur" sorusundayız. Bu aşamayı bitiren biri gerçek bir gateway'i yapılandırabilir: rotayı yazar, kimliği bağlar, kotayı kurar, izlenebilirliği açar.
Ne zaman eşleşir (predicate) · ne yapılır (filter) · nereye gider (uri). İsimler ürüne göre değişir, kavram değişmez.
| Kavram | Spring Cloud GW | Envoy | K8s Gateway API |
|---|---|---|---|
| Koşul | Predicate | Route match | rules.matches |
| Davranış | GatewayFilter | HTTP filter | filters |
| Hedef | uri: lb:// | Cluster | backendRefs |
| Ağırlık | Weight=g,n | weighted_clusters | weight |
| Predicate | Örnek | Kullanım |
|---|---|---|
| Path | /api/v1/siparis/** | Ana yönlendirme ekseni |
| Method | GET,POST | Okuma/yazma ayrı politika |
| Header | X-Api-Version, v2 | Header tabanlı sürüm |
| Host | **.partner.kurum.com | Çok kiracılı ayrım |
| Cookie | deney, v2 | Yapışkan canary |
| Weight | katalog, 95 | Ağırlıklı yönlendirme |
| Between | 2026-08-01T… | Kampanya / planlı sunset |
spring.cloud.gateway.server.webflux: # Tüm rotalara uygulanan varsayılanlar default-filters: - DedupeResponseHeader=Access-Control-Allow-Origin, RETAIN_FIRST - RemoveResponseHeader=Server - RemoveRequestHeader=X-Internal-Auth # taklidi kes - SecureHeaders routes: # ── Dış rota: sıkı kota, devre kesici, küçük gövde ── - id: siparis-public-v1 uri: lb://siparis-servisi # servis keşfi predicates: - Path=/api/v1/siparis/** - Method=GET,POST,PUT filters: - StripPrefix=2 # /api/v1/x → /x - name: RequestSize args: { maxSize: 1MB } - name: RequestRateLimiter args: key-resolver: "#{@kurumKeyResolver}" redis-rate-limiter.replenishRate: 200 redis-rate-limiter.burstCapacity: 400 - name: CircuitBreaker args: { name: siparisCB, fallbackUri: forward:/fallback/siparis } - name: Retry args: { retries: 2, methods: GET, series: SERVER_ERROR } # yalnız idempotent # ── Canary: trafiğin %5'i v2'ye ── - id: katalog-v1 uri: lb://katalog-servisi predicates: [ Path=/api/v1/katalog/**, Weight=katalog, 95 ] - id: katalog-v2-canary uri: lb://katalog-servisi-v2 predicates: [ Path=/api/v1/katalog/**, Weight=katalog, 5 ]
Rota lb://siparis-servisi diyor. O listeyi kim güncelliyor, bir örnek çöktüğünde gateway bunu ne kadar sürede öğreniyor? Gözlemlenen "kararsızlığın" büyük kısmı bu üç sorunun cevabında saklıdır.
| Yaklaşım | Kayıt kaynağı | Güncelleme gecikmesi | Güçlü yanı | Zayıf yanı |
|---|---|---|---|---|
| Statik URI | Config dosyası | Deploy süresi | Basit, öngörülebilir | Ölçeklenmez |
| DNS | A / SRV kaydı | TTL kadar | Dilden bağımsız | TTL cache tuzağı, ağırlık taşımaz |
| Eureka | Servis kendini kaydeder | ~30 sn | Spring ile sorunsuz | Spring dışında zayıf |
| Consul | Agent + sağlık kontrolü | Saniyeler | Çoklu DC, VM+K8s karışık | İşletme yükü |
| Kubernetes DNS | API server / EndpointSlice | Saniyeler | Aynı RBAC, ek bileşen yok | Küme dışına çıkmaz |
| etcd + watch | Kontrol düzlemi | Milisaniyeler | Anlık yayılım, DB yok | etcd operasyonu |
| xDS (Envoy) | gRPC akışı | Milisaniyeler | Endüstri standardı | Kontrol düzlemi gerekir |
İstekleri sırayla dağıtır. İstek maliyetleri birbirine yakınsa yeterlidir; aksi hâlde yavaş örneği de hızlı örnek kadar besler ve kuyruk orada birikir.
En az aktif isteği olan örneği seçer. Envoy'un "iki rastgele aday arasından azını seç" varyantı, tam sıralama maliyeti olmadan aynı sonucu üretir — üretim varsayılanı budur.
Aynı anahtar her zaman aynı örneğe yönlendirilir. Önbellek isabetini artırır ve yapışkan canary sağlar; örnek eklendiğinde yeniden dağıtım en aza iner.
Aynı erişilebilirlik bölgesindeki örnekleri tercih eder; bölgeler arası veri transferi ücretini ve gecikmeyi düşürür, bölge zayıfladığında otomatik olarak taşar.
Vaka kapsamının en çok atlanan maddesi. Dış trafiğin tehdit modeli, SLA'sı, değişim hızı ve ölçek profili iç trafikten tamamen farklıdır.
| Boyut | Dış (public) | Partner (B2B) | İç (internal) |
|---|---|---|---|
| Tüketici | Mobil, web, anonim | Kurumsal müşteri, entegratör | Diğer ekipler, batch, admin |
| Kimlik | OAuth2/OIDC kullanıcı token'ı | mTLS + client credentials + IP allowlist | Servis kimliği (SPIFFE), iç JWT |
| Tehdit modeli | Yüksek: bot, DDoS, kimlik doldurma | Orta: sözleşme ihlali, kota aşımı | Düşük ama yıkıcı: yanlış yapılandırma |
| Kota | Sıkı, kullanıcı/IP bazlı | Sözleşmeye bağlı + faturalandırma | Gevşek, koruma amaçlı |
| Gövde limiti | 1–5 MB | 10–50 MB | Yüksek / akış |
| Değişim hızı | Yavaş, sürüm sözleşmeli | Sunset takvimli | Hızlı, kırıcı değişime toleranslı |
| Ağ konumu | DMZ / kenar, WAF arkasında | DMZ, ayrı dinleyici + sertifika | Küme içi, internete kapalı |
Yalnızca kimlik, kota, izleme, protokol dönüşümü. İş mantığı yasak. Golang, self-servis yapılandırma arayüzü.
İstemciye özel görünüm üretimi ve veri birleştirme — yani BFF. Ürün ekiplerinin sahip olduğu servisler.
Yeniden kullanılabilir, özelliğe özgü API'ler. Birden çok deneyim tarafından tüketilir.
Tek bir işi yapan yaprak mikroservisler. Grafiğin ucu.
Gateway'in kimlik işi tek cümleyle: doğrulanmamış hiçbir istek iç ağa girmesin, ve doğrulanmış her isteğin kimliği downstream'e güvenilir biçimde taşınsın.
| Yöntem | Nerede | Gateway'in işi | Dikkat |
|---|---|---|---|
| JWT (Bearer) | Kullanıcı oturumları | İmza + claim doğrulama, JWKS önbelleği | İptal edilemez — kısa ömür + refresh |
| Opaque token | Yüksek güvenlikli oturum | Introspection + sonucu önbellekleme | Her istekte IdP'ye gitmek gecikme ekler |
| mTLS | Partner, iç servisler | Sertifika zinciri + CN/SAN eşleme | Kullanıcıyı değil servisi tanır |
| API key | Basit B2B, dahili araç | Hash'lenmiş anahtar araması, kota bağlama | Tek başına kimlik doğrulama değildir |
| HMAC imza | Bankacılık, ödeme, webhook | Gövde + zaman damgası imzası | Replay için nonce + zaman penceresi gerekir |
Kurumsal ortamların fiilî standardı: hem güvenlik hem performans problemini aynı anda çözer. Akış aşağıda adım adım oynuyor.
JWT'nin gövdesi Base64'tür, şifreli değildir. Tarayıcıda duran bir JWT e-posta, rol ve kurum bilgisini açığa çıkarır. Opaque token hiçbir şey söylemez ve anında iptal edilebilir.
Her mikroservisin her istekte IdP'ye gitmesi hem gecikme hem tek hata noktası demektir. JWT'yi yerel doğrulamak mikrosaniyeler alır.
Gateway'de introspection sonucunu önbelleklemek zorunludur (token'ın kalan ömrüyle sınırlı TTL). Aksi hâlde her istek IdP'ye bir çağrı ekler.
Vaka kapsamındaki "authentication ve authorization kontrollerinin gateway üzerindeki konumu" maddesinin cevabı ve kısa kuralı: bu ikisi yer değiştiremez.
| Kontrol | Örnek soru | Nerede | Gerekçe |
|---|---|---|---|
| Kimlik doğrulama | Token geçerli mi? | Gateway (zorunlu) | Tekdüze olmalı, veri gerektirmez |
| Kapsam / scope | Token siparis:yaz içeriyor mu? | Gateway | Token'ın içinde |
| Rol / fonksiyon yetkisi | Admin ucuna girebilir mi? | Gateway (kaba) + servis (kesin) | Rota bazlı filtre ucuz ve etkili |
| Kurum izolasyonu | Bu token X kurumuna mı ait? | Gateway (yönlendirme) + servis (doğrulama) | Gateway kiracıyı bilir, kaydın kiracısını bilmez |
| Nesne düzeyi yetki (BOLA) | 42 numaralı sipariş bu kullanıcının mı? | Yalnızca servis | Gateway iş verisine erişemez, erişmemeli |
| Alan düzeyi yetki | TCKN alanını görebilir mi? | Servis (veya gateway'de maskeleme) | Veri modeline bağımlı |
| İş akışı yetkisi | Limit üstü transfer ikinci onay ister mi? | Yalnızca servis | Saf iş mantığı |
Genel amaçlı politika motoru; Envoy'un ext_authz API'siyle yerel entegrasyonu var. Harici veriyi kendi biçiminde işler. Öğrenme eğrisi dik, ifade gücü yüksek.
Daha dar kapsamlı ve okunabilir; politika analizi (çakışma/erişilebilirlik kanıtı) yapılabilir. İzin modeli net olan uygulamalarda Rego'dan pratiktir.
Yetki isteği/cevabının nasıl taşınacağını standartlaştıran açık spesifikasyon. Uygulama PEP, motor PDP olur; motoru değiştirmek entegrasyonu kırmaz.
"Dakikada 60 istek" cümlesi, seçilen algoritmaya göre tamamen farklı sistemler üretir. Aşağıda dört algoritma aynı istek akışını alır ve her biri kendi iç durumunu canlı gösterir. Ani yük düğmesi davranış farkını görünür kılar; bir algoritma satırına tıklandığında o algoritmanın nasıl çalıştığı adım adım açılır.
| Algoritma | Bellek | Doğruluk | Ani yük | Zayıf noktası | Ne zaman |
|---|---|---|---|---|---|
| Sabit pencere | 1 sayaç | Düşük | Kontrolsüz | Pencere sınırında 2× limit geçebilir | İç servisler, kaba koruma |
| Kayan pencere (log) | N zaman damgası | Tam | Yok | Bellek ve temizlik maliyeti yüksek | Düşük hacim, kritik doğruluk |
| Kayan pencere (sayaç) | 2 sayaç | Yüksek | Yok | Ağırlıklı tahmin, küçük sapma | Genel amaçlı varsayılan |
| Jeton kovası | 2 alan | Yüksek | Kontrollü (kapasite kadar) | Boş kovadan sonra ani yük geçmez | Genel API'ler için en iyi varsayılan |
| Sızdıran kova | Kuyruk | Yüksek | Emilir, çıkış düzleşir | Kuyrukta bekleme = gecikme | Arka uç sabit hız istiyorsa |
| GCRA | 1 zaman damgası | Yüksek | Kontrollü | Kavraması daha zor | Dağıtık ortamda en zarif |
Ve tek bir limit hiçbir zaman yeterli değildir: gerçek sistemlerde limitler katmanlıdır ve her katman farklı bir tehdide karşı durur.
Her örnek limitin 1/N'ini uygular. Ağ maliyeti sıfır; ama yük dengesiz dağılınca yanlış reddetme üretir ve otomatik ölçekleme limiti sessizce değiştirir.
Tek doğruluk kaynağı. Atomiklik için tek Lua betiği — oku/hesapla/yaz yarışını engellemenin tek güvenli yolu. Maliyet: ~0.3–1 ms Redis gidiş-dönüşü.
Yerel sayaç hızlı karar verir, arka planda merkezle uzlaşır. Ultra yüksek hacimde tek yol; karşılığında kısa süreli aşımları kabul edersiniz.
| Boyut | Anahtar | Neye karşı korur | Tuzağı |
|---|---|---|---|
| IP | ip:203.0.113.9 | Anonim kötüye kullanım | NAT — binlerce kullanıcı tek IP |
| Kullanıcı | u:8f21… | Hesap kötüye kullanımı, kazıma | Kimlik doğrulanmadan bilinemez |
| Kurum | k:ACME | Gürültülü komşu, sözleşme aşımı | Kurum içi tek kullanıcı tüm kotayı yiyebilir |
| API anahtarı | a:pk_live_… | Sızmış anahtar, entegrasyon hatası | Paylaşılırsa kimlik anlamını kaybeder |
| Rota | r:odeme-olustur | Pahalı endpoint sömürüsü | Ağırlık yoksa ucuz/pahalı eşit sayılır |
| Global | * | Toplam kapasite koruması | Tek başına adaletsiz — en üst emniyet supabı |
-- KEYS[1] = kova anahtarı (rl:kurum:ACME:route:siparis) -- ARGV = kapasite, hız(jeton/sn), şimdi(ms), istenen local durum = redis.call('HMGET', KEYS[1], 'jeton', 'ts') local kapasite = tonumber(ARGV[1]) local hiz = tonumber(ARGV[2]) local simdi = tonumber(ARGV[3]) local istenen = tonumber(ARGV[4]) local jeton = tonumber(durum[1]) or kapasite local ts = tonumber(durum[2]) or simdi -- geçen süre kadar doldur, tavan: kapasite local gecen = math.max(0, simdi - ts) / 1000 jeton = math.min(kapasite, jeton + gecen * hiz) local izin, bekle = 0, 0 if jeton >= istenen then jeton = jeton - istenen izin = 1 else bekle = math.ceil((istenen - jeton) / hiz) -- Retry-After end redis.call('HSET', KEYS[1], 'jeton', jeton, 'ts', simdi) redis.call('PEXPIRE', KEYS[1], math.ceil(kapasite/hiz*2000)) return { izin, math.floor(jeton), bekle }
Gateway'in en çekici ve en tehlikeli yeteneği. Ayrımı bilmek, gateway'i dağıtık monolitten ayıran çizgidir.
| Header | Risk | Gateway davranışı |
|---|---|---|
| X-Forwarded-For | Sahte IP ile IP kısıtı ve rate limit atlatma | Güvenilir proxy sayısına göre kes ve yeniden yaz |
| X-Forwarded-Proto / -Host | Yanlış şema/host → yönlendirme ve önbellek zehirlenmesi | Kenar gateway'de zorla sabitle |
| X-User-Id, X-Roles, X-Kurum | Doğrudan kimlik taklidi | Gelen değeri koşulsuz sil, token'dan yeniden üret |
| Authorization | İç servise sızan dış token | Gerekiyorsa exchange et, gerekmiyorsa iletme |
| Connection, TE, Upgrade | İstek kaçakçılığı (smuggling) | İletme; belirsiz Content-Length/Transfer-Encoding ikilisini reddet |
…o tek isteğin geçtiği yedi servisi tek bir kimlikle birleştirebiliyor musunuz? Gateway bu zincirin başladığı yerdir. Aşağıda traceparent header'ı parça parça açılıyor.
Geçerli bir traceparent/correlation yoksa oluştur.
Formatı geçersizse yeni üret — sahte/bozuk değeri ağaca sokma.
Upstream'e mutlaka geçir. Header allowlist'i bunu sessizce düşürebilir.
Yanıt header'ında istemciye dön — destek kaydında tek referans olur.
| Kavram | Ne işaret eder | Kim üretir | Ömrü |
|---|---|---|---|
| Correlation ID | Bir iş akışının tamamı (kullanıcı eylemi) | İstemci veya gateway | Asenkron adımlar dâhil, saatler |
| Trace ID | Bir isteğin dağıtık çağrı ağacı | İlk enstrümante bileşen (gateway) | İstek süresi |
| Span ID | Ağaçtaki tek bir iş birimi | Her servis kendi span'ını üretir | Metot/çağrı süresi |
| Request ID | Tek bir HTTP isteği (retry'lar farklı) | Gateway | Tek atlama |
Sunset tarihi olmayan bir sürüm sonsuza kadar yaşar. Versiyonlama kararının gerçek bedeli buradadır.
| Yöntem | Örnek | Artı | Eksi | Gateway'de |
|---|---|---|---|---|
| URI yolu | /api/v2/siparis | Görünür, önbelleklenebilir, her araçla uyumlu | URL'ler kalıcıdır; eski yolu silmek acı verir | Path predicate |
| Header | X-Api-Version: 2 | URL temiz, kaynak kimliği bozulmaz | Gizli — tarayıcıdan denenemez | Header predicate |
| Media type | …vnd.kurum.v2+json | Mimari olarak en temizi | Geliştiricilere en yabancı olanı | Header + Vary |
| Query param | ?version=2 | Denemesi kolay | Önbellek anahtarını kirletir | Query predicate |
# Sunset edilmiş sürüm — hâlâ ayakta, ama uyarıyor - id: siparis-v0-deprecated uri: lb://siparis-legacy predicates: [ Path=/api/v0/siparis/** ] filters: # RFC 9745 — bu kaynak kullanımdan kaldırıldı - AddResponseHeader=Deprecation, @1767225600 # RFC 8594 — şu tarihte yanıt vermeyi bırakacak - AddResponseHeader=Sunset, Sat, 31 Jan 2027 23:59:59 GMT # Yerine ne kullanılacak - AddResponseHeader=Link, <https://api.kurum.com/docs/v1>; rel="successor-version"
Duyuru + iki hatırlatma + karartma tatbikatı (planlı kısa kesintiler) dizisi, gerçek kapanış gününde sürpriz yaşamamanın tek yoludur.
Buraya kadar her şey her şey yolundayken nasıl çalıştığıydı. Bu aşama, işler ters gittiğinde ne olduğuyla ilgili: arka uç yavaşladığında, kapasite aşıldığında, bir bölge düştüğünde. Kesinti günlerinde sistemin kaderini burada verilen kararlar belirler.
Üç farklı zaman aşımı vardır ve karıştırılmaları en yaygın hatadır.
TCP + TLS kurulumu. Aynı bölgede 100–500 ms fazlasıyla yeterli. Uzun tutmak, çökmüş bir örneğe saniyelerce bağlanmaya çalışmak demektir.
Yanıt beklemesi. Servisin p99 gecikmesinin 2–3 katı. Bu ölçüyü tahminle değil, gerçek metrikle koyun.
Retry'lar dâhil toplam. İstemcinin bekleyeceği mutlak üst sınır. Retry sayısı × response timeout bu değeri aşamaz.
Arka uç yavaşlar → gateway retry yapar → yük 3× olur → arka uç daha da yavaşlar → daha çok retry. Bu, üretim kesintilerinin en yaygın büyütücü mekanizmasıdır. Kesintiyi retry başlatmaz ama küçük bir olayı tam karartmaya o çevirir.
Dört farklı devre kesici stratejisi aynı arıza akışını alıyor ve bağımsız karar veriyor. Kaydırıcılarla arka ucun hata ve yavaşlık oranını değiştirin; alttaki karşılaştırma tablosunda hangi stratejinin ne kadar boşa çağrıyı engellediğini ve kaç yanlış kesme yaptığını yan yana görün.
resilience4j.circuitbreaker.instances.siparisCB: slidingWindowType: COUNT_BASED slidingWindowSize: 20 minimumNumberOfCalls: 10 # gürültüye tepki verme failureRateThreshold: 50 # %50 hata → OPEN slowCallRateThreshold: 60 # %60 yavaşsa da OPEN slowCallDurationThreshold: 1s waitDurationInOpenState: 10s permittedNumberOfCallsInHalfOpenState: 5 ignoreExceptions: # 4xx devreyi AÇMAMALI - com.kurum.IsKuraliHatasi resilience4j.timelimiter.instances.siparisCB: timeoutDuration: 2s # breaker'ın GÖZÜ cancelRunningFuture: true
| Rota | Nitelik | Timeout | Retry | Circuit breaker | Fallback |
|---|---|---|---|---|---|
| /odeme/tahsilat | Kritik, yazma, idempotent değil | 5 s | Yok | Hassas: %30 eşik | Yok — net hata döndür |
| /siparis | Kritik, yazma | 3 s | 1 (yalnız GET) | %50 / 10 sn | Kuyruğa al + 202 |
| /katalog | Okuma, önbelleklenebilir | 1 s | 2 | %50 / 5 sn | Bayat önbellek servis et |
| /arama | Okuma, pahalı | 800 ms | 1 | %40 / 15 sn | Basit liste + uyarı |
| /oneri | İsteğe bağlı süsleme | 300 ms | Yok | %30 / 30 sn | Boş liste — sayfa yine yüklenir |
| /rapor | Uzun süren, toplu | 60 s | Yok | Kapalı | Asenkron iş kimliği |
Devre kesici eşiklerinin doğru değeri, ilk yazıldığı gün bilinemez; trafiğin şekli, arka ucun kapasitesi ve iş önceliği değiştikçe değişir. Bu bölüm iki soruyu cevaplar: parametreler nasıl seçilir ve yeniden deploy etmeden nasıl değiştirilir?
Resilience4j desenleri iç içe geçmiş dekoratörler olarak uygular: en dıştaki modül, içindeki her şeyi tek bir çağrı gibi görür. Sıra keyfi değildir — kim kimi sarıyorsa onun kararını da sayar. Modülleri kapatıp açın, isteğin hangi katmanda durduğunu izleyin.
// En içten dışa doğru: Bulkhead → TimeLimiter → // RateLimiter → CircuitBreaker → Retry var tedarikci = Decorators.ofSupplier(() -> istemci.cagir()) .withBulkhead(bulkhead) // 1 · eşzamanlılık .withTimeLimiter(zaman, sched) // 2 · süre bütçesi .withRateLimiter(hizSiniri) // 3 · hız .withCircuitBreaker(devre) // 4 · sağlık .withRetry(retry) // 5 · en dışta .withFallback(List.of(Exception.class), e -> bayatVeri()) .decorate();
# 1) Anlık durum: hangi devre açık, pencere ne durumda? curl -s localhost:9000/actuator/circuitbreakers | jq '.circuitBreakers' { "siparisCB": { "state": "OPEN", "failureRate": "72.0%" }, "katalogCB": { "state": "CLOSED" , "failureRate": "3.5%" } } # 2) Olay akışı: geçişleri canlı izle (SSE) curl -N localhost:9000/actuator/circuitbreakerevents/siparisCB/stream STATE_TRANSITION CLOSED -> OPEN failureRate=72% # 3) Operatör müdahalesi: devreyi elle zorla (olay anında) curl -XPOST localhost:9000/actuator/circuitbreakers/siparisCB \ -d '{"updateState":"FORCE_OPEN"}' # arka ucu koru curl -XPOST localhost:9000/actuator/circuitbreakers/siparisCB \ -d '{"updateState":"DISABLE"}' # yanlış açılmayı geç # 4) Eşiği canlı değiştir: config sunucusundan yenile curl -XPOST localhost:9000/actuator/refresh ["resilience4j.circuitbreaker.instances.siparisCB.failureRateThreshold"]
Actuator uçları operatör içindir. Politikayı program aracılığıyla değiştirmek gerektiğinde (örneğin kampanya saatinde eşiği gevşetmek) registry doğrudan kullanılabilir:
// Çalışan bir devre kesicinin eşiğini değiştirmek // yeni bir CircuitBreaker örneği üretmeyi gerektirir; // mevcut örneğin config'i değişmez (tasarım gereği). var yeni = CircuitBreakerConfig.from(mevcut.getCircuitBreakerConfig()) .failureRateThreshold(30) .waitDurationInOpenState(Duration.ofSeconds(30)) .build(); registry.remove("siparisCB"); // eski örneği düşür registry.circuitBreaker("siparisCB", yeni); // yenisini kaydet // UYARI: mevcut pencere sıfırlanır. Yoğun trafikte // bu işlem kısa süreli "kör nokta" yaratır — değişikliği // düşük trafikte veya kademeli yapın.
Devre kesici anlatımlarının çoğu üç durumda durur. Resilience4j'de üç tane daha vardır ve olay anında asıl işe yarayanlar bunlardır: metrik toplayan ama hiç kesmeyen, hiç ölçmeyen ve elle kilitlenmiş durumlar. Aşağıdaki grafikte bir duruma tıklayın — nasıl girilir, nasıl çıkılır ve ne zaman kullanılır.
Tek bir default devre kesici tüm arka uçları birleştirir ve bir servisin sorunu diğerlerini keser. Kural: her upstream için ayrı örnek, adı rota kimliğiyle aynı olsun — böylece metrik, alarm ve config aynı anahtarla eşleşir.
Rota başına elle ayar sürdürülemez. kritik / standart / opsiyonel adında üç baseConfig tanımlayıp rotaları bunlara bağlayın; yalnızca istisnalar için özelleştirme yapın.
Düşük trafikli rotalarda COUNT_BASED pencere saatlerce dolmayabilir; devre kesici fiilen devre dışı kalır. Trafiği düzensiz rotalarda zaman tabanlı pencere daha öngörülebilir davranır.
slowCallRateThreshold çoğu kurulumda unutulur. Oysa üretimde arka uç genelde hata vermez, yavaşlar. Yavaş çağrı eşiği olmadan devre kesici bu duruma kördür.
Devre kesici açıldıktan sonra korur; bulkhead açılmadan önce korur. Eşzamanlılık sınırı olmadan tek bir yavaş arka uç, gateway'in bütün iş parçacıklarını tüketebilir ve devre kesici devreye girecek kadar bile zaman bulamaz.
Yapılandırılmış ama hiç açılmamış bir devre kesici, test edilmemiş bir yedek gibidir. Ayda bir, kontrollü biçimde bir arka ucu bozup devrenin açıldığını, fallback'in çalıştığını ve alarmın düştüğünü doğrulayın.
"Devre açık" durumu bir alarm değil bir sonuçtur. Alarm CLOSED → OPEN geçişine ve açık kalma süresine kurulmalıdır; saniyeler içinde kapanan bir devre gürültü, on dakikadır açık olan devre olaydır.
Her eşik bir iş kararıdır: "ödeme rotasında %30 seçildi çünkü yanlış tahsilat, kısa kesintiden pahalıdır." Bu gerekçe yazılmazsa altı ay sonra kimse değeri değiştirmeye cesaret edemez — ve parametre fiilen dondurulur.
Kapasitenin üstünde yük geldiğinde iki seçenek vardır: herkese kötü hizmet (her istek yavaşlar, hepsi zaman aşımına uğrar, sistem çöker) veya bir kısmını hemen reddetmek (kalan normal hızda hizmet alır). İkincisi her zaman doğru cevaptır.
Gelen hız çıkan hızı aşıyorsa kuyruk sonsuza kadar büyür. Kuyrukta 8 saniye bekleyip işlenen bir istek, istemci 3 saniyede vazgeçtiği için boşa harcanmış iştir. Sistem %100 meşgul, faydalı iş sıfır. Bu duruma congestion collapse denir.
Çözüm: kuyruğa girerken de bütçe koymak — kuyrukta çok bekleyen isteği işlemeye başlamadan atmak.
"Aynı anda en fazla 200 istek" gibi elle konmuş limitler donanım değişince, kod hızlanınca veya arka uç yavaşlayınca yanlışa döner. Uyarlanabilir yaklaşım Little Yasası'yla gözlenen gecikmeden anlık kapasiteyi türetir: gecikme artmaya başlayınca eşzamanlılık limitini otomatik düşürür — TCP tıkanıklık kontrolüne benzer bir gradyan algoritması.
Kullanıcının doğrudan beklediği istek — oynatma başlatma. En son atılır.
Bozulmuş ama kabul edilebilir deneyim üretecek istekler.
Ön yükleme (prefetch), öneri zenginleştirme. Baskı altında ilk gidenler.
Telemetri, toplu iş, arka plan senkronizasyonu.
Gateway'in en sık ihmal edilen boyutu. Aşağıdaki sahne, aynı 500 MB'lık dosyanın iki farklı desenle nasıl taşındığını yan yana gösterir: gateway üzerinden ve ön imzalı URL ile doğrudan depoya. Gateway'in bellek ve bağlantı tüketimindeki fark, tasarım kararının tamamını açıklar.
| Limit | Neden | Öneri |
|---|---|---|
| İstek gövdesi | Bellek tüketimi, ayrıştırıcı DoS | JSON 256 KB–1 MB, yükleme ayrı rota |
| Yanıt gövdesi | Kontrolsüz veri sızıntısı, bant genişliği | Sayfalama zorunlu — sınırsız liste ucu yasak |
| Header toplamı | Bellek ve HPACK saldırıları | 8–16 KB |
| URL uzunluğu | Log ve ara katman uyumsuzlukları | 2–8 KB |
| Multipart parça sayısı | Ayrıştırıcı tüketimi | Açık üst sınır |
| Sıkıştırma oranı | Zip bomb | Açılmış boyut tavanı + oran kontrolü |
| JSON derinliği | Yığın taşması / özyineleme | 32–64 seviye |
500 MB'lık dosya gateway üzerinden. Gateway bağlantıyı dakikalarca tutar, belleği doldurur, bir yeniden başlatma tüm yüklemeleri iptal eder ve bu tek endpoint diğer bütün trafiğin gecikmesini bozar. Yönetilen ürünlerin sabit limitleri de vardır: AWS API Gateway'de yük sınırı 10 MB ve değiştirilemez.
Gateway sabit bellekle çalışır, boyut sınırı depoya taşınır, ağır işlem senkron istek yolundan tamamen çıkar.
Ara katmanların varsayılanları uzun ömürlü bağlantıları sessizce keser: NGINX proxy_read_timeout 60 sn, AWS ALB boşta kalma 60 sn. Uygulama düzeyinde heartbeat göndermeden bunları aşamazsınız.
SSE kullanıyorsanız yanıt tamponlaması kapalı olmalı, aksi hâlde olaylar ancak tampon dolunca ulaşır ve "gerçek zamanlı" özellik gerçek zamanlı olmaz. Gövde dönüşümü filtreleri de bu rotalarda kullanılamaz.
10.000 açık WebSocket'i olan gateway yeniden başlatıldığında hepsi aynı anda bağlanmaya çalışır. Zorunlu önlem: kademeli devre dışı bırakma, istemcide jitter'lı yeniden bağlanma, bağlantıların dengeli dağıtımı.
Gateway trafiği yönlendiren yer olduğu için, dağıtım stratejisinin doğal uygulama noktasıdır. Kaydırıcı ile ağırlık değiştirildiğinde trafiğin nasıl bölündüğü ve etkinin nasıl değiştiği izlenebilir.
| Strateji | Nasıl | Eksi | Ne zaman |
|---|---|---|---|
| Blue-green | İki tam ortam; trafik tek seferde geçer | Çift kapasite; hata anında herkes etkilenir | Hızlı geri alınabilir sürümler |
| Canary | Küçük yüzde yeniye; metrikle artırılır | Sürümler bir süre birlikte yaşar → geriye uyumlu şema | Varsayılan tercih |
| Shadow / mirror | İstek kopyalanır, yanıtı atılır | Yan etki riski: çift yazma, çift e-posta | Okuma ağırlıklı, yan etkisiz rotalar |
| Yapışkan canary | Kullanıcı hash'ine göre sabit atama | Dağılım tam yüzde vermez | Arayüzü etkileyen değişiklikler |
| Hedefli canary | Header/cookie ile yalnızca iç kullanıcılar | Gerçek trafik çeşitliliğini temsil etmez | Her canary'nin ilk adımı |
Yukarıdaki tablo stratejileri sözle anlatır; aşağıda her birini çalışırken görebilirsiniz. İstekler soldan gelir, gateway karar verir, sürümlere dağılır. "v2'yi boz" düğmesine basıp yeni sürümü kasıtlı olarak arızalandırın — stratejiler arasındaki etki alanı farkı ancak o zaman görünür hâle gelir.
Gateway her API çağrısının yolundadır. Düştüğünde kademeli bozulma olmaz — tam karartma olur. Bu bölüm o riski nasıl parçalayacağınızı anlatır.
| # | Katman | Neye karşı | Devreye girme |
|---|---|---|---|
| 1 | DNS / GSLB — sağlık kontrollü, düşük TTL | Bölge kaybı | TTL + istemci önbelleği |
| 2 | Anycast — aynı IP, çok konum | PoP kaybı, ağ yolu sorunu | Saniyeler |
| 3 | L4 load balancer — çoklu AZ | Sunucu / AZ kaybı | Saniyeler |
| 4 | Çoklu gateway örneği — stateless, N+2 | Örnek kaybı, deploy | Anında |
| 5 | Hücresel dağıtım — bağımsız yığınlar | Yazılım hatası, zehirli istek, gürültülü komşu | Hücre başına izole |
| Bağımlılık | Kaybedilirse | Doğru davranış | Uygulama |
|---|---|---|---|
| Kontrol düzlemi / config store | Yeni rota eklenemez | Fail static — son bilinen config | Diskte kalıcı önbellek |
| Servis keşfi | Yeni örnekler görünmez | Son bilinen endpoint listesi | Boş listede eskiyi koru |
| JWKS / IdP | Yeni anahtar öğrenilemez | Önbellekle doğrulamaya devam | Uzun TTL + arka planda yenileme |
| Redis (rate limit) | Kota sayılamaz | Rota bazlı: fail-open / fail-closed | Yerel yedek limiter |
| Politika motoru (OPA) | Yetki kararı alınamaz | Fail-closed (reddet) | Sidecar — ağ bağımlılığını kaldır |
| Log/metrik toplayıcı | Görünürlük kaybı | Asla isteği engelleme | Asenkron, sınırlı tampon, taşarsa düşür |
Bir veritabanı yetki değişikliği sorgunun yinelenen satır döndürmesine ve bot yönetimi özellik dosyasının ikiye katlanmasına yol açtı. Dosya tüm ağa yayıldı; boyut sınırını aşınca proxy süreçleri 5xx üretmeye başladı.
Workers KV kesintisi ona bağlı çok sayıda ürünü birlikte düşürdü; KV isteklerinin %91'i başarısız oldu, kesinti 2 sa 28 dk sürdü.
Dashboard'daki bir React useEffect hatası tek render'da hook'u tekrar tekrar çalıştırdı; Tenant Service API'si gereksiz çağrılarla boğuldu ve ona bağlı API'ler de düştü.
Bunu bozan her özellik (yerel oturum, yerel sayaç, yerel önbellek tutarlılığı) ölçeklenmeyi bir dağıtık sistem problemine dönüştürür. Durumsuzluk sağlandıktan sonraki soru kaç kopya değil, nasıl bölündüğüdür. Aşağıdaki sahnede dört topoloji aynı üç olaya maruz kalıyor — bozuk sürüm yayımı, bir erişilebilirlik bölgesinin kaybı ve zehirli bir kiracı. Her senaryoda kazanan topoloji değişir; sütunların altındaki "etkilenen trafik" ve "ayakta kapasite" değerlerini karşılaştırın.
Gateway'ler tipik olarak CPU-bağımlıdır: TLS el sıkışması, JSON/JWT ayrıştırma, şifreleme. Ancak uzun ömürlü bağlantı varsa sinyal aktif bağlantı sayısı olmalıdır — CPU boştayken bellek ve dosya tanıtıcıları tükenir.
Kritik optimizasyon: upstream'e keep-alive bağlantı havuzu. Her istekte yeni TCP+TLS kurmak, gateway ek yükünü tek başına 10 kat artırabilir.
| Topoloji | Artı | Eksi | Ölçek |
|---|---|---|---|
| Tek paylaşılan filo | Basit, tek politika noktası | En büyük blast radius | < 20 servis |
| Maruziyete göre ayrık | Tehdit ve SLA izolasyonu | 3× operasyon | Kurumsal varsayılan |
| Alana göre ayrık | Ekip özerkliği, bağımsız ölçekleme | Politika tutarlılığı zorlaşır | Büyük organizasyon |
| Hücresel (cell-based) | En küçük blast radius | En yüksek karmaşıklık | Çok kiracılı SaaS |
spec: replicas: 6 # N+2: AZ kaybı + deploy dalgası template.spec: topologySpreadConstraints: # AZ'lere eşit dağıt - maxSkew: 1 topologyKey: topology.kubernetes.io/zone terminationGracePeriodSeconds: 75 containers: - lifecycle.preStop.exec.command: # 1) sağlığı kapat 2) LB fark etsin 3) açık istekleri bitir # Bu olmadan HER deploy 502 üretir — en sık "deploy hatası" ["/bin/sh","-c", "curl -XPOST localhost:9000/drain && sleep 45"] readinessProbe.periodSeconds: 2 livenessProbe.failureThreshold: 6 # agresif = restart fırtınası resources: requests: { cpu: "1", memory: 1Gi } limits: { memory: 2Gi } # CPU limit KOYMAYIN --- kind: PodDisruptionBudget # bakım hepsini birden almasın spec: { minAvailable: "70%" }
Tanım basit; zor olan bu farkı dürüstçe ölçmek. Aşağıdaki etiketler açılıp kapatıldığında bütçenin nasıl değiştiği görülebilir.
| Ürün / sınıf | Teknoloji | Bildirilen ek yük |
|---|---|---|
| NGINX / APISIX | C + LuaJIT | Milisaniye altı |
| Envoy | C++ | Milisaniye altı |
| KrakenD | Go, durumsuz | Çok düşük |
| Kong | NGINX + Lua | 1–3 ms (eklenti yüküne göre) |
| Tyk | Go | 1–3 ms |
| Spring Cloud Gateway | JVM + Netty | Birkaç ms (JIT sonrası) |
(2)−(1) = proxy maliyeti · (3)−(2) = politika maliyeti. Bu ikisini ayırmazsanız "gateway yavaş" diye yanlış sonuca varırsınız; oysa yavaş olan genelde tek bir filtredir.
Kapalı model yük üreticileri (her sanal kullanıcı yanıtı bekleyip sonra yeni istek gönderir) sistem yavaşladığında istek göndermeyi de yavaşlatır. Böylece en kötü gecikmeler hiç ölçülmez ve p99 yapay olarak düşük çıkar. Yeşil görünen yük testlerinden sonra gelen üretim kesintilerinin klasik sebebi budur.
Çözüm: açık model — sabit varış hızı, yanıt gelsin gelmesin. k6'da constant-arrival-rate, Gatling'de constantUsersPerSec.
Bütün trafiği görür, her isteğin sonucunu bilir ve kullanıcı deneyimine en yakın ölçümü üretir. Bu avantajı doğru kullanmak, onlarca servise ayrı ayrı enstrümantasyon eklemekten hızlı sonuç verir.
Rate (istek/sn) · Errors (hata oranı) · Duration (gecikme dağılımı). Gateway metriklerinin doğal biçimi; her rota için ayrı toplanmalı.
Utilization · Saturation · Errors. Gateway'in kendi sağlığı: CPU, bağlantı havuzu doluluğu, event loop gecikmesi, dosya tanıtıcıları.
Latency, Traffic, Errors, Saturation. RED ile örtüşür; farkı doygunluğu öne çıkarmasıdır — kesintiden önceki tek erken uyarı çoğu zaman odur.
| Metrik | Neden | Alarm sinyali |
|---|---|---|
| Rota bazlı istek / hata / gecikme | Sorunun hangi API'de olduğunu tek bakışta gösterir | Rota SLO'su ihlali |
| Upstream gecikmesi vs toplam | Gateway mi arka uç mu yavaş — en sık sorulan soru | Fark aniden büyürse gateway'de sorun var |
| 429 oranı | Saldırı mı, hatalı entegrasyon mı, limit mi dar | Ani sıçrama veya sürekli yükseliş |
| 401 / 403 oranı | Token ve yetki yanlış yapılandırmaları | Yeni sürüm sonrası artış = kırık entegrasyon |
| Devre kesici durumu | Hangi arka uç kesildi | OPEN'a geçişte anında bildirim |
| Retry oranı | Retry fırtınasının erken göstergesi | Toplam isteğin %10'unu aşması |
| Bağlantı havuzu doygunluğu | Görünmeyen darboğazların en yaygını | %80 üzerinde sürekli seyir |
| TLS el sıkışma hatası | Sertifika süresi, mTLS sorunları | Sıfırdan farklı her değer incelenmeli |
| Sertifika kalan ömrü | 47 günlük sertifika çağında hayati | < 20 gün uyarı, < 7 gün sayfa |
| Sürüm bazlı kullanım | Sunset kararlarını veriyle almak | Eski sürümde beklenmeyen artış |
OWASP API Security Top 10 (2023) üzerinden değerlendirme: gateway bu risklerin ne kadarını çözer, ne kadarı uygulama ekibinin sorumluluğunda kalır? Satırlara tıklandığında her risk için gateway'in somut katkısı ve sınırı görüntülenir.
| # | Risk | Gateway katkısı | Nasıl |
|---|---|---|---|
| API1 | Broken Object Level Authorization | Düşük | Yalnızca anomali tespiti; asıl kontrol serviste |
| API2 | Broken Authentication | Yüksek | Tekdüze token doğrulama, brute-force limiti, JWKS yönetimi |
| API3 | Broken Object Property Level Auth. | Kısmi | Yanıt alan filtreleme/maskeleme, şema ile fazla alan engelleme |
| API4 | Unrestricted Resource Consumption | Yüksek | Rate limit, kota, gövde limitleri, timeout, yük atma |
| API5 | Broken Function Level Authorization | Yüksek (kaba) | Rota bazlı rol/scope kontrolü, admin yollarını kapatma |
| API6 | Unrestricted Access to Sensitive Business Flows | Kısmi | Bot tespiti, davranış hızı limitleri, cihaz parmak izi |
| API7 | Server Side Request Forgery | Yüksek | Egress allowlist, iç ağ hedeflerini reddetme |
| API8 | Security Misconfiguration | Yüksek | Merkezî TLS, CORS, güvenlik header'ları, hata normalizasyonu |
| API9 | Improper Inventory Management | Yüksek | Tek envanter, sürüm/sunset takibi, gölge API tespiti |
| API10 | Unsafe Consumption of APIs | Kısmi | Giden (egress) gateway ile üçüncü taraf yanıtlarını sınırlama |
Azami geçerlilik 15 Mart 2026'da 200 güne düşüyor, 2029'a kadar 47 güne inecek. ACME otomasyonu artık bir "iyi olur" değil çalışma şartı.
Gateway'iniz sertifikayı yeniden başlatmadan yükleyebiliyor mu? Hayırsa her 47 günde bir planlı kesinti yaşarsınız.
Son aşama iki soruyu cevaplar: hangi ürünü seçmeliyiz ve hazır ürünlerin yapamadığını nasıl yaparız? Burası, vaka çalışmasının en çok fark yaratan kısmı — çünkü rakiplerinizden ayrıldığınız yer, gateway'inizin sizin alanınızı bilmesi olacak.
Gateway ürünlerini tek listede karşılaştırmak yanıltıcıdır, çünkü aynı işi yapmıyorlar. Aşağıdaki harita on iki ürünü iki belirleyici eksende konumlandırır: yatayda üstlenilen operasyon yükü, dikeyde özelleştirme derinliği. Balon büyüklüğü ekosistem olgunluğunu gösterir.
| Ürün | Temel | Eklenti dili | Config kaynağı | Güçlü yanı | Zayıf yanı | İdeal senaryo |
|---|---|---|---|---|---|---|
| Spring Cloud Gateway | JVM · Netty / Servlet | Java / Kotlin | YAML, Java DSL, dinamik | Spring ile tam bütünleşme; sınırsız özelleştirme; ekibin bildiği dil | JVM bellek/ısınma; hazır eklenti pazarı yok | JVM kurumları, iş kuralına yakın özel gateway |
| Ocelot / YARP | .NET | C# | JSON / kod | .NET ekipleri için doğal; YARP hızlı ve MS destekli | Ekosistem küçük | .NET ağırlıklı kurumlar |
| Envoy | C++ | C++ / WASM / ext_proc | xDS (gRPC, dinamik) | Endüstri standardı veri düzlemi; olağanüstü trafik yönetimi | Tek başına gateway değil — kontrol düzlemi şart | K8s-native platformlar, çok dilli ortam |
| Apache APISIX | NGINX + LuaJIT | Lua, Java, Go, Python, WASM | etcd (watch, ms) | 100+ hazır eklenti; DB yok; sıcak yeniden yükleme | etcd operasyonu; Lua bilen ekip bulmak zor | Yüksek performans + zengin özellik |
| Kong | NGINX + LuaJIT | Lua, Go PDK | PostgreSQL / DB-less | En olgun ekosistem; geniş eklenti pazarı | Config yayılımı saniyeler sürebilir; kurumsal maliyet | Kurumsal API programı |
| Traefik | Go | Go middleware | Otomatik keşif (K8s, Docker) | Sıfır yapılandırmaya en yakın; otomatik TLS | Genişletilebilirlik sınırlı | Küçük–orta K8s kümeleri |
| KrakenD | Go, durumsuz | Go eklentileri | Statik JSON (DB yok) | Yanıt birleştirme odaklı; çok düşük gecikme | Dinamik yapılandırma zayıf | Mobil/BFF için çok kaynaklı birleştirme |
| Tyk | Go | Go, gRPC, JS | Redis + Mongo/Postgres | Açık kaynak çekirdek güçlü; hava boşluklu kurulum | Yönetim özellikleri ücretli panelde; Go eklenti sürüm uyumu | Şirket içi, regülasyonlu ortamlar |
| NGINX | C | Lua (OpenResty), njs | Dosya + reload | Efsanevi kararlılık; her yerde bilinir | API yönetimi katmanı yok | Basit ters vekil + TLS |
| AWS API Gateway | Yönetilen | Lambda authorizer, VTL | Konsol / IaC | Sıfır operasyon; IAM ve Lambda ile derin bütünleşme | 10 MB yük sınırı; ölçekte pahalı; satıcı bağımlılığı | AWS serverless, düşük–orta hacim |
| Azure API Management | Yönetilen | XML policy | Portal / IaC | Kurumsal özellikler hazır; Azure AD bütünleşmesi | XML policy hantal; WebSocket/SSE/gRPC akış desteği sınırlı | Microsoft ekosistemi |
| Apigee | Yönetilen | JS, Java callout | Apigee konsolu | En olgun API yönetimi; güçlü analitik ve monetizasyon | Kurulum karmaşık; öğrenme eğrisi dik; pahalı | Büyük API programları, dış ekosistem |
| WSO2 API Manager | Java | Java, mediation | Kendi kontrol düzlemi | Açık kaynak tam API yönetimi; olgun AI gateway | Ağır; kaynak tüketimi yüksek | Şirket içi kurumsal API yönetimi |
| Gravitee | Java | Java eklenti | Kendi kontrol düzlemi | Olay güdümlü/asenkron API'lerde (Kafka, MQTT) farklılaşır | Topluluk küçük | REST + event-driven birlikte |
Ürün karşılaştırmalarının çoğu tek boyutta (genelde performans) yapılır ve yanıltıcıdır. Aşağıdaki eksenler, bir gateway kararında gerçekten belirleyici olan boyutlardır. Soldan bir ürün seçildiğinde radar grafiği, güçlü/zayıf yanları ve "nerede kullanılmalı" değerlendirmesi birlikte güncellenir.
Geniş alan "daha iyi ürün" demek değildir. Her ürün belirli eksenlerde bilinçli olarak ödün verir: KrakenD durumsuzluğu seçerek esneklikten, Traefik basitliği seçerek genişletilebilirlikten feragat eder. Aranması gereken şey en geniş alan değil, sizin öncelik eksenlerinizde en dolu profildir.
Bu puanlar, yayımlanmış kıyaslamalar ve ürün yeteneklerinden derlenmiş göreli değerlendirmelerdir; laboratuvar ölçümü değildir. Amaçları sıralama üretmek değil, ödünleşimi görünür kılmaktır. Nihai karar kendi ortamınızdaki PoC ölçümüyle verilmelidir.
Radarda gösterilemeyen ama pratikte en ağır basan boyut: ekibinizin o ürünü işletebilme becerisi. Lua bilmeyen bir ekipte APISIX'in eklenti esnekliği kâğıt üstünde kalır. Bu eksen kuruma özgü olduğu için değerlendirmeyi okuyanın eklemesi gerekir.
Bir gateway, ömrünün neredeyse tamamını arka ucu beklerken geçirir. Klasik "istek başına bir iş parçacığı" modelinde 5.000 eşzamanlı istek 5.000 iş parçacığı anlamına gelir. Spring Cloud Gateway, WebFlux ve Netty üzerinde az sayıda olay döngüsü iş parçacığıyla çalışır; bekleme sırasında iş parçacığı serbest kalır.
Ekibiniz reaktif değilse ve trafiğiniz aşırı uçta değilse MVC varyantı artık savunulabilir bir tercihtir.
25 Kasım 2025'te yayımlandı; Spring Framework 7 ve Spring Boot 4 tabanlı, projeler 5.0.0 sürümünde.
| Global filtre | Görevi |
|---|---|
| RouteToRequestUrlFilter | Eşleşen rotanın URI'sinden hedef adresi üretir |
| ReactiveLoadBalancerClientFilter | lb:// şemasını çözer; örnek yoksa varsayılan 503 |
| NettyRoutingFilter | İsteği Netty HttpClient ile arka uca taşır |
| NettyWriteResponseFilter | Yanıtı istemciye yazar |
| ForwardRoutingFilter | forward:// — fallback uçları böyle çalışır |
| WebsocketRoutingFilter | ws/wss yükseltmelerini yönetir |
| GatewayMetricsFilter | spring.cloud.gateway.requests zamanlayıcısı (routeId, outcome, status…) |
| LocalResponseCache | Caffeine tabanlı yerel GET önbelleği (varsayılan TTL 5 dk) |
Çünkü mutlaka eklenecektir. Eklenti mimarisi, ürünle birlikte satın alınan en kalıcı teknik borçtur: performans, izolasyon ve geliştirici deneyimi arasındaki ödünleşim beş yıl boyunca sizinle kalır.
| Model | Ürün | Performans | İzolasyon | Sıcak yükleme | Geliştirici deneyimi |
|---|---|---|---|---|---|
| Lua / LuaJIT | Kong, APISIX | Neredeyse yerel (JIT, aynı süreç) | Yok — hata proxy'yi düşürebilir | APISIX evet · Kong reload | Niş dil, küçük işe alım havuzu |
| Go (yerel) | Tyk, Traefik | Çok yüksek (süreç içi) | Yok | Genelde yeniden başlatma | Yaygın dil; sürüm uyumu en sık şikâyet |
| gRPC / harici süreç | Tyk, Envoy ext_proc | Düşük (her çağrıda ağ) | Tam (ayrı süreç) | Evet | Her dil kullanılabilir |
| WASM (proxy-wasm) | Envoy, Istio, APISIX | İyi ama yerelden düşük — veri VM'e kopyalanır | Gerçek sanal alan: çöken eklenti proxy'yi düşürmez | Evet — çalışma anında | Hata ayıklama belirgin zor; TinyGo standart Go değil |
| Java | Spring Cloud GW, WSO2 | İyi (JIT sonrası) | Yok | Genelde yeniden başlatma | En geniş kurumsal işe alım havuzu |
| JS / TypeScript | Zuplo, Tyk (JS) | Orta | İzolat düzeyi | Evet | En büyük geliştirici havuzu |
| Ürün | Model | Referans fiyat | Ölçekte |
|---|---|---|---|
| AWS API Gateway | Saf çağrı başına | HTTP $1,00/M · REST $3,50/M | 100M REST ≈ $350 + ek servisler |
| Azure APIM | Katman + birim | Basic v2 ~$145/ay · Premium v2 ~$2.800/ay/birim | Çok bölgeli Premium > $10.000/ay |
| Apigee | Çağrı + ortam | $20/M · ortam tabanı $365–$3.431/ay | Kurumlar $8.000–$25.000/ay |
| Kong Konnect | Servis + çağrı aşımı | ~$105/ay/servis · +$200/ek milyon | 50M çağrı ≈ yalnız aşım ~$10.000/ay |
| MuleSoft | vCore aboneliği | ~$1.250/ay/vCore | 4 vCore ≈ $210.000/yıl |
| Kendi barındırma | Altyapı + insan | Tipik $50.000+/yıl | Asıl kalem sunucu değil, mühendis zamanı |
Bu bir kesin hüküm değil, tartışmayı doğru yerden başlatan bir çerçevedir. Her katmanda bir seçim yapıldığında akış aşağı doğru açılır; önceki seçimler görünür kalır ve istendiğinde değiştirilebilir. Sağdaki puan çubukları, seçimlerin ürünleri nasıl ayrıştırdığını gerçek zamanlı gösterir.
| Kriter | Hazır ürün | Kendi yaz |
|---|---|---|
| Zaman baskısı | Haftalar içinde üretim | Aylar |
| Standart ihtiyaçlar | %90'ı hazır | Hepsini yazarsınız |
| Alana özgü mantık | Eklenti sınırlarına takılırsınız | Sınırsız |
| Ekip kapasitesi | Küçük ekip yeter | Kalıcı 1–2 FTE |
| Güvenlik yaması / CVE | Satıcı sorumluluğu | Sizin sorumluluğunuz |
| Uzun vade (yüksek hacim) | Çağrı başına ücret birikir | Sabit altyapı maliyeti |
| İşe alım / bilgi aktarımı | Piyasada bilen var | Yalnızca sizde bilen var |
Zorluk kavramda değil, ayrıntıda ve dayanıklılıktadır.
| # | Katman | Zorluk kaynağı |
|---|---|---|
| 1 | Taşıma — soket, TLS, HTTP/1.1·2·3 ayrıştırma | Protokol kenar durumları: chunked, trailer, 100-continue, HPACK, smuggling |
| 2 | Rota motoru — eşleme, öncelik, parametre | Binlerce rotada hızlı eşleme → radix/trie gerekir |
| 3 | Filtre boru hattı — pre/post, sıralama, kısa devre | Post filtrelerin hata durumunda da çalışması |
| 4 | Upstream istemcisi — havuz, retry, breaker, akış | Gövdeyi belleğe almadan akıtmak (zero-copy) |
| 5 | Yapılandırma — doğrulama, atomik sıcak yükleme | Yarım uygulanmış config kesintiden kötüdür |
| 6 | Telemetri — metrik, log, trace, sağlık | Sıcak yolda alokasyon yapmadan ölçmek |
| 7 | Yönetim yüzeyi — admin API, drain, debug | Yönetim portunun asla dışarı açılmaması |
| Aşama | Kapsam | Gerçekçi süre | Ekip |
|---|---|---|---|
| Çalışan prototip | Yönlendirme, JWT, basit kota, log | 1–2 hafta | 1 kişi |
| PoC / iç kullanım | + breaker, metrik, trace, sıcak config | 6–10 hafta | 1–2 kişi |
| Üretime hazır | + HA, akış, zarif kapanma, admin API, sertleştirme | 6–12 ay | 2–3 kişi |
| Sürdürme | CVE, yeni protokoller, nöbet | Süresiz | 1–2 FTE kalıcı |
// Filtre = klasik middleware. Zincir dıştan içe kurulur. type Filtre func(http.Handler) http.Handler func Zincir(h http.Handler, f ...Filtre) http.Handler { for i := len(f) - 1; i >= 0; i-- { h = f[i](h) } return h } func main() { hedef, _ := url.Parse("http://siparis-servisi:8080") proxy := httputil.NewSingleHostReverseProxy(hedef) // KRİTİK: bağlantı havuzu. Varsayılan Transport her istekte // yeni TCP+TLS kurabilir; keep-alive ek yükü kat kat düşürür. proxy.Transport = &http.Transport{ MaxIdleConns: 1024, MaxIdleConnsPerHost: 256, // varsayılan 2 — en sık atlanan IdleConnTimeout: 90 * time.Second, ForceAttemptHTTP2: true, } // İç hatayı asla sızdırma; normalize edilmiş gövde döndür. proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) { metrik.UpstreamHata.WithLabelValues(rotaId(r)).Inc() w.WriteHeader(http.StatusBadGateway) w.Write([]byte(`{"hata":"upstream_erisilemiyor"}`)) } h := Zincir(proxy, Korelasyon, // en dış: her şeyi görür ve ölçer Metrik, HeaderTemizle, // ucuz, erken GovdeLimiti(1<<20), // pahalı işlerden ÖNCE Kimlik, // JWT doğrulama HizSiniri, // kota (kimlikten sonra) DevreKesici, Zamanasimi(2*time.Second), ) srv := &http.Server{ Addr: ":8443", Handler: h, ReadHeaderTimeout: 3 * time.Second, // slowloris MaxHeaderBytes: 16 << 10, } log.Fatal(srv.ListenAndServeTLS("cert.pem", "key.pem")) }
Kurumsal kütüphaneler hazır (HSM, imza, LDAP); ekip zaten biliyor; SCG'yi temel alıp üstüne yazabilirsiniz. Eksi: bellek tabanı, JIT ısınması, reaktif hata ayıklama.
Standart kütüphanede hazır ters vekil; tek ikili dosya; öngörülebilir bellek. Sıfırdan başlıyorsanız en iyi verim/çaba oranı.
En akıllı hibrit yol. Veri düzlemini yazmazsınız — protokol işini kanıtlanmış C++ yapar; siz yalnızca xDS konuşan bir servis yazarsınız.
Custom gateway'i başarısız kılan tek özellik genellikle şudur: her rota değişikliği bir yeniden derleme ve deploy gerektirir. Bu durumda gateway, ürün ekiplerinin darboğazına dönüşür ve insanlar onu baypas etmenin yollarını arar. Dinamiklik bir "güzel olur" özelliği değil, custom gateway'in varlık şartıdır.
// Yapılandırmayı DEĞİŞMEZ (immutable) bir anlık görüntü olarak tut. // İstek yolunda asla kilit alma: atomic.Value okuma maliyeti ~0'dır. type Snapshot struct { Surum int Rotalar *radix.Tree // önceden derlenmiş eşleştirici Politika map[string]Politika } var aktif atomic.Value // *Snapshot tutar // İSTEK YOLU — kilitsiz, her istekte çağrılır func rotaBul(yol string) *Rota { return aktif.Load().(*Snapshot).Rotalar.Lookup(yol) } // KONTROL YOLU — yalnızca config değişince çağrılır func uygula(ham []byte) error { yeni, err := ayristir(ham) if err != nil { return err } // 1) ŞEMA doğrula if err := yeni.Dogrula(); err != nil { return err } // 2) ANLAM doğrula if yeni.RotaSayisi() < mevcut().RotaSayisi()/2 { // 3) AKIL SAĞLIĞI return errors.New("rota sayısı yarıya düştü — reddedildi") } snap := derle(yeni) // 4) önceden derle aktif.Store(snap) // 5) TEK ATOMİK ADIM gecmisEkle(snap) // 6) geri alınabilirlik return nil }
Rotaları tek tek güncelleyen bir uygulama, güncelleme sırasında hiçbir sürüme ait olmayan karma bir durumdan geçer: bazı istekler eski politikayla, bazıları yenisiyle değerlendirilir. Bu durum sessizdir, hata üretmez ve yeniden üretilemez. Tek çare, yapılandırmayı bölünemez bir anlık görüntü olarak değiştirmektir.
| Öğe | Dinamik? | Gerekçe | Yayılma hedefi |
|---|---|---|---|
| Rota tanımı, upstream, ağırlık | Evet — zorunlu | Günlük iş; canary ve acil yönlendirme buna bağlı | < 5 sn |
| Kota limitleri ve anahtarları | Evet | Kampanya, olay müdahalesi, sözleşme değişikliği | < 5 sn |
| Devre kesici / timeout eşikleri | Evet | Kapasite ve trafik şekli değiştikçe ayarlanır | < 30 sn |
| Yetki kuralları (scope, rol) | Evet | Güvenlik olayında saniyeler önemlidir | < 5 sn |
| API anahtarı / token iptali | Evet — kritik | Sızıntı anında yayılım süresi = risk süresidir | < 1 sn |
| Özellik bayrakları, bakım modu | Evet | Olay müdahalesinin ilk aracı | < 5 sn |
| Filtre zincirinin sırası | Dikkatli | Güvenlik kararıdır; yanlış sıra sessizce açık üretir → ayrı onay | Kontrollü |
| Yeni filtre kodu | Hayır (WASM hariç) | Kod yayımlamak deploy'dur; sanal alan yoksa çöken eklenti proxy'yi düşürür | Deploy |
| TLS dinleyici, port, protokol | Hayır | Bağlantı kabul katmanı; değişimi zarif yeniden başlatma ister | Deploy |
Her yapılandırma sürümü numaralanmalı, saklanmalı ve tek komutla geri alınabilir olmalıdır. Pratik hedef: bozuk config fark edildikten sonra 60 saniye içinde önceki sürüme dönebilmek. Bu yetenek yoksa dinamiklik bir güvenlik açığına dönüşür.
Yeni yapılandırma önce tek bir düğüme uygulanır; o düğümün hata oranı ve gecikmesi bir süre izlenir; ancak sonra filoya yayılır. Kod için doğal karşılanan bu disiplin, yapılandırma için neredeyse hiç uygulanmaz — ve büyük kesintilerin kaynağı budur.
Dinamik yapılandırma denetlenebilir olmalıdır: her değişiklik yazarı, gerekçesi ve önceki değeriyle birlikte kaydedilmelidir. Aksi hâlde "üretimde bu limit neden 40?" sorusunun cevabı kaybolur ve kimse dokunmaya cesaret edemez.
Hazır ürünler genel problemleri çözmek zorundadır; bu yüzden sizin alanınıza özgü olanı çözemezler. Aşağıdaki on dört başlık, piyasa ürünlerinde ya hiç bulunmayan ya da yalnızca ilkel biçimde bulunan yeteneklerdir.
Kurum hiyerarşisine göre yetki (ana şirket alt şirketin verisini görebilir), çalışma saati/resmî tatil kısıtı, kanal bazlı limit (şube ≠ mobil ≠ ATM), risk skoruna göre uyarlanan kontrol.
Neden üründe yok: bu kurallar iş modelinizin parçası; hiçbir satıcı "resmî tatilde EFT limitini düşür" kuralını genel eklenti olarak yazamaz.
Idempotency-Key'i gateway seviyesinde yönetmek: aynı anahtarla gelen ikinci istek birincinin sonucunu döndürür; eş zamanlı gelen ikinci istek birincinin bitmesini bekler (in-flight coalescing), yeni çağrı üretmez.
Değeri: çift ödeme, çift sipariş, çift SMS problemini tek noktada çözer. Açık Bankacılık düzenlemeleri zaten bu header'ı şart koşar.
Gateway PUT /musteri/42 isteğini gördüğünde GET /musteri/42 ve /musteri/42/adresler önbelleklerini otomatik geçersiz kılar.
Neden üründe yok: hiçbir genel ürün bu ilişkiyi bilemez; sundukları tek şey TTL'dir — yani ya bayat veri ya düşük isabet.
Her isteğe maliyet birimi atamak; kiracı/ekip/ürün kırılımında "bu API bize ayda ne kadara mal oluyor, kim tüketiyor" raporu üretmek.
Değeri: ürünlerin analitik modülü istek sayısı verir, maliyet vermez. Gateway bu hesabı yapabilecek tek yerdir.
KVKK/GDPR kapsamında TCKN, IBAN, telefon maskeleme; veri yerleşimi kuralına göre bölge yönlendirme; değiştirilemez (WORM) denetim kaydı; imzalı denetim izi.
Ürünlerde kısmen var ama regex tabanlı geneldir. Gerçek ihtiyaç alan bazlıdır: "yanıttaki musteri.tckn, rol OPERATOR ise maskelensin".
SOAP ↔ REST, ISO 8583 (kart işlemleri), sabit uzunluklu kayıt, EBCDIC/AS-400 ana bilgisayar, XML dijital imza doğrulama, HSM ile imzalama.
Neden üründe yok: hazır ürünler modern protokolleri hedefler; kurumsal dünyada ayakta olan sistemlerin çoğu bunları konuşur ve her kurumun lehçesi farklıdır.
VIP müşteriyi ayrılmış havuza; kiracıyı kendi hücresine/shard'ına; pahalı dış sağlayıcı yerine ucuzu seçip yalnızca hatada pahalıya düşme; veri yerleşimine göre bölge seçme.
Neden üründe yok: ürünler ağırlık ve sağlık bilir; müşteri değeri ve maliyet bilmez.
Servis henüz yazılmadıysa sözleşmeye uygun sahte yanıt; gerçek trafiği kaydedip test ortamında oynatma; belirli header'la yapay gecikme/hata (chaos); yanıtın OpenAPI'den sapmasını yakalama (contract drift).
Değeri: ön uç arka ucu beklemez; dayanıklılık kodunuz gerçekten test edilir; dokümantasyon-gerçeklik kayması üretimde yakalanır.
Kapasite daraldığında rapor ve öneri isteklerini atıp ödeme ve girişi korumak; ödeme yapan müşteriye deneme kullanıcısından öncelik vermek.
Neden üründe yok: hangi işin kritik olduğu tamamen size özgü. Netflix bunu kendi gateway'ine gömdü ve gerçek kesintide kullanıcı isteklerinde >%99,4 erişilebilirlik korurken ön yüklemeyi %20'ye düşürdü.
Token'dan çözülen kimliği kurum kodu, yetki seti, abonelik katmanı, dil, para birimiyle zenginleştirip downstream'e tek ve standart bağlam header'ı olarak vermek.
Dikkat: bu header imzalanmalı veya yalnızca mTLS'li iç ağdan kabul edilmelidir; aksi hâlde kimlik taklidi için mükemmel bir araç olur.
İç servis kataloğuyla entegre sahiplik; rota başına SLO ve nöbetçi ekip; deprecated endpoint'i çağıran ekibe otomatik bildirim; gerçek kullanımdan otomatik SDK üretimi.
Değeri: ürünlerin portalları dış geliştiriciler içindir; asıl acınız genelde iç ekipler arası koordinasyondur.
İstek yerine token bazlı kota; prompt injection ve veri sızıntısı filtreleri; anlamsal önbellek (benzer soruya modeli tekrar çağırmadan cevap); model yönlendirme ve yedekleme; MCP sunucularına erişimi yöneten ajan gateway'i; araç çağrılarının onay ve denetim kaydı.
2026 gerçeği: alanın en hızlı büyüyen kısmı ve klasik ürünlerin eklentilerle yetiştirmeye çalıştığı yer.
Her tüketici için normal davranış profili çıkarmak ve sapmayı yakalamak. En kıymetlisi: tek bir token'ın kısa sürede çok sayıda farklı nesne kimliğine erişmesi — OWASP API1 sömürüsünün klasik imzası.
Neden üründe yok: genel WAF'lar imza tabanlıdır, iş akışı anomalisini bilmezler. Gateway tüm trafiği tek yerden gören tek bileşendir.
Yanıttan role göre alan çıkarmak (aynı endpoint, farklı görünürlük); eski istemcilere yeni alanları gizlemek veya eski alan adlarını yeni modele eşlemek.
Uyarı: bu gövde dönüşümüdür ve tüm uyarıları geçerlidir. Kısa vadeli geçiş aracı olarak kullanın, kalıcı mimari olarak değil.
İş mantığı yavaş yavaş sızar. Her ürün değişikliği gateway deploy'u gerektirir, sahiplik belirsizleşir, test imkânsızlaşır. Uber'de bu, mühendisliğin %40'ının aynı repoya kod yazdığı 1 milyon satırlık bir uygulamaya dönüştü.
Tüm trafik, tüm ekipler, tek küme. Bir ekibin hatası herkesi düşürür; deploy takvimi kilitlenir; kimse değişiklik yapmaya cesaret edemez.
Gateway'in iş verisine erişmesi gerekir → veritabanına bağlanır → artık bir servistir. OWASP API1 zaten gateway'de çözülemez.
"Gateway zaten doğruluyor" varsayımı. Tek bir yanlış ağ kuralı veya SSRF açığı, tüm sisteme tam yetkili erişim demektir.
Rota eklemek uygulama deploy'u gerektiriyorsa gateway ürün ekiplerinin darboğazına dönüşür ve insanlar onu baypas etmenin yollarını arar.
Küçük bir yavaşlamayı tam kesintiye çeviren en hızlı yol. Retry bütçesi ve daralan timeout zinciri tanımlanmadan retry etkinleştirilmemelidir.
Metrik etiketine ham yol, kullanıcı kimliği veya korelasyon kimliği koymak. Gözlemlenebilirlik maliyetiniz gateway'in kendisini geçer.
0,3 ms fark, ekibin ürünü işletebilme becerisinin yanında önemsizdir. Seçimi işletilebilirlik, işe alım ve ekosistem belirlemelidir.
Her küçük değişiklikte yeni sürüm. Üç yıl sonra kimsenin silemediği kırk rota, kırk farklı davranış ve devasa bir test yüzeyi kalır.
Seçilen ürün bizim yükümüzde, bizim politikalarımızla, bizim ekibimizle işliyor mu?
| Hafta | Konu | Yapılacaklar | Çıktı |
|---|---|---|---|
| 1 | İskelet | Gateway + 5 servis, statik rotalar, sağlık uçları | Çalışan uçtan uca akış |
| 2 | Keşif & rota | Servis keşfi, predicate seti, iç/dış ayrım, rewrite | Route ve Trafik Yönetim Tasarımı |
| 3 | Kimlik | OIDC, JWT, JWKS önbelleği, scope, header temizleme | Authentication / Authorization Akışları |
| 4 | Kota | Redis limiter, KeyResolver'lar, 429 sözleşmesi, fail politikaları | Rate Limit Entegrasyon Tasarımı |
| 5 | Gözlemlenebilirlik | Correlation ID, W3C trace, RED metrikleri, dashboard | Monitoring ve Alarm Yaklaşımı |
| 6 | Dayanıklılık | Rota bazlı timeout/retry/CB matrisi, fallback, hata enjeksiyonu | Route Bazlı Dayanıklılık Politikaları |
| 7 | Güvenlik | CORS, güvenlik header'ları, TLS/mTLS, gövde limitleri, şema doğrulama | Güvenlik Kontrol Listesi |
| 8 | Sürüm geçişi | Ağırlıklı yönlendirme, hedefli canary, sunset, geri alma tatbikatı | Canary senaryo kayıtları |
| 9 | Performans | Üç aşamalı yük testi, p50–p99 ek yük, kapasite eğrisi | Performans ve Gecikme Test Sonuçları |
| 10 | Erişilebilirlik | Örnek/Redis/IdP/config store kesme, bölge kaybı tatbikatları | Yüksek Erişilebilirlik Tasarımı |
| 11 | Karar | Alternatif ürünle karşılaştırma, TCO, ekip geri bildirimi | Sonuç ve Mimari Öneri |
Her biri yapay gecikme ve hata enjekte edebilen uçlara sahip olmalı — dayanıklılık testleri buna dayanır.
| Başarı kriteri | Hedef |
|---|---|
| Gateway ek yükü (p50) | < 2 ms |
| Gateway ek yükü (p99) | < 10 ms |
| Kota doğruluğu (3 örnek) | sapma < %2 |
| Devre kesici tepki süresi | < 5 sn |
| Canary geri alma süresi | < 60 sn |
| Deploy sırasında istek kaybı | 0 |
| Yeni rota ekleme (deploy'suz) | < 10 dk |
Başladığınızda "gateway nedir" sorusu vardı. Şimdi elinizde bir ürün seçim çerçevesi, bir dayanıklılık matrisi, bir güvenlik kontrol listesi ve kendi gateway'inizi yazma kararı için gereken her şey var.
Araştırmanın tamamından çıkan on iki madde. Bunlar tercih değil, tekrar tekrar doğrulanmış pratiklerdir.
Merkezileştirmenin faydası tartışmasız; riski tektir ve bilinir: iş mantığının sızması. "Gateway'e ne girmez" listesi yazılı hâle getirilmelidir.
Dış, partner ve iç trafiği ayrı filolarda çalıştırın. Aynı teknoloji, ayrı dağıtım. En düşük maliyetli blast-radius azaltma yöntemi.
Kimlik doğrulama tekdüze biçimde gateway'de. Kaba yetki gateway'de, nesne yetkisi serviste. Servisler gateway'e körü körüne güvenmesin.
Varsayılan algoritma jeton kovası, dağıtık sayaç atomik Lua ile. Her rotanın "Redis düşerse ne olur" cevabı yazılı olsun.
Tek global timeout/retry/CB ayarı yoktur. Altı sütunlu matrisi yapılandırmaya dönüştürün ve yeni rota eklerken zorunlu kılın.
Yalnızca idempotent, en fazla 1–2 deneme, jitter'lı geri çekilme, %10 retry bütçesi. Bütçesiz retry küçük olayları tam kesintiye çevirir.
Çoklu AZ, N+2 örnek, fail-static kontrol düzlemi. İstek yolundaki senkron bağımlılıkları sayın. Kritik sistemlerde hücresel dağıtımı ciddi değerlendirin.
Cloudflare'in 2025 kesintisi kod değil veri yüzündendi. Yapılandırma ve politika verisi de canary'den, boyut/şema doğrulamasından geçmeli.
Üç aşamalı test, açık model yük üreteci, JVM'de ısınma. Satıcı kıyaslamalarını karar girdisi değil ön eleme olarak kullanın.
JVM + özel politika → Spring Cloud Gateway · K8s-native çok dilli → Envoy Gateway / APISIX · kurumsal portal → Kong / WSO2 / Apigee · AWS serverless → AWS API Gateway.
Protokol katmanını kanıtlanmış bir ürüne bırakın; farklılaştığınız yeri kendiniz yazın. "Custom gateway" ihtiyacının %90'ı aslında budur.
Hiçbir ürün kurum hiyerarşinizi, idempotency ihtiyacınızı, regülasyon yükümlülüğünüzü veya iş önceliklerinizi bilemez. Gateway'inizi ayıran şey hız değil, bu bağlamı bilmesi olacak.
| Dönem | Hedef | Kapsam |
|---|---|---|
| 0–3 ay | Temeli kur | PoC'yi tamamla, ürünü seç, dış gateway'i tek bir alanla üretime al. Kimlik, kota, correlation ID, temel metrikler. |
| 3–6 ay | Yaygınlaştır ve sertleştir | Tüm dış trafiği taşı, iç/partner filolarını ayır, dayanıklılık matrisini uygula, canary'yi otomatikleştir, SLO ve alarm setini kur. |
| 6–12 ay | Farklılaştır | Alana özgü eklentiler (idempotency, kimlik zenginleştirme, maliyet muhasebesi, öncelikli yük atma), self-servis rota yönetimi, sürüm otomasyonu, çoklu bölge. |