İçeriğe geç

Mikroservis Katmanları — İstek Nereden Geçiyor

Orta 10 dk Çok sık karşılaşılır

Önce şunu oku: Servisler Arası İletişim Desenleri

30 saniyede özet

Mimari çizimlerdeki her kutu ayrı bir soruya cevap verir: gateway ortak kapıdır, BFF bir ekranı tanır, servis kuralı tutar. Bir kutuyu atlarsan onun işi başka bir yere sızar.

Mikroservis mimarisi diyagramlarında kutular üst üste dizilir: gateway, BFF, servisler, veri. Sorun şu ki hiç kimse her kutunun hangi soruyu cevapladığını söylemez.

Danışma, hemşire, doktor, laboratuvar: her biri tek bir soruya cevap verir.
Adım adım oku
  1. Gateway danışma gibidir: isteği karşılar, kimliğe bakar ve doğru servise yönlendirir.
  2. BFF, tek bir ekran için gereken bilgileri toplayan hemşire gibidir.
  3. Servisler asıl uzmanlığın, yani iş kurallarının yaşadığı doktorlardır; altındaki veri katmanı laboratuvardır.
  4. Her kutu tek bir soruya cevap verir: kim ve nereye, bu ekran neye ihtiyaç duyar, iş kuralı ne, veri nerede saklanır.
  1. Bayt: Mimari çizimimizde kat kat kutular var: gateway, BFF, servisler, veri...

  2. Sen: Her biri ne işe yarıyor?

  3. Bayt: Açıkçası bunu kimse bize hiç söylemedi.

  4. Bayt: Hastanede danışma, hemşire ve doktor aynı işi yapmaz. Katmanlar da öyle.

Her katman bir soruya cevap verir

KatmanCevapladığı soruBilmediği şey
GatewayBu isteği kim yaptı ve nereye gidecek?İşin ne olduğu
BFFBu ekran için hangi veriler, hangi şekilde?Kuralların ne olduğu
Domain servisiBu iş kuralı nedir, geçerli mi?İsteğin hangi ekrandan geldiği
Veri katmanıBu veri nerede duruyor ve nasıl okunur?Neden okunduğu

Sağdaki sütun soldakinden daha önemli. Bir katman bilmemesi gereken şeyi bilmeye başlayınca katman olmaktan çıkar: ekran adını bilen bir domain servisi artık o ekrana bağlıdır.

Kafam karıştı, daha basit anlat

Her katmanın bir işi var, ve bilmemesi gereken şeyler de var. Kapıdaki görevli indirim hesaplamaya başlarsa, artık kapı görevlisi değildir.

Hızlı kontrolBaşlangıç

API gateway'in asıl varlık sebebi nedir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Gateway ile BFF arasındaki fark nedir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Gateway neyi çözer, neyi çözmez?

API gatewayDışarıdan gelen her isteğin girdiği tek kapı. Auth, rate limit, TLS sonlandırma ve yönlendirme gibi her servisi ilgilendiren işleri tek yerde toplar.Gateway yönlendirir, birleştirmez. Sayfa için beş servis gerekiyorsa istemci yine beş kez gidip gelir — gecikmeyi çözen şey gateway değil, sunucu tarafında birleştirme yapan BFF'tir.Sözlükte gör →’in varlık sebebi gecikme değil. Çözdüğü şey tekrar: auth, rate limit, TLS sonlandırma ve log korelasyonu gibi kesişen ilgiHer servisi ilgilendiren ama hiçbirinin iş kuralı olmayan işler: auth, rate limit, log korelasyonu, TLS sonlandırma.Bunlar her serviste tekrarlanırsa aynı kural N yerde tutulur ve biri geride kalır. Gateway'in asıl varlık sebebi gecikme değil, bu tekrarın tek yere toplanmasıdır.Sözlükte gör →ler her serviste ayrı ayrı yazılırsa aynı kural beş yerde tutulur ve er geç biri geride kalır.

Ama gateway yönlendirir, birleştirmez. Sayfa beş servisten veri istiyorsa istemci yine beş kez gidip gelir — üstüne bir hop daha eklenmiş olur.

Gateway koymak sayfanın açılma süresini düşürür mü? Cevabı göster

Hayır, biraz artırır. Çağrı sayısı aynı kaldı ve araya bir hop girdi. Süreyi düşüren şey sunucu tarafında birleştirme yapan BFF’tir.

Kafam karıştı, daha basit anlat

Gateway binanın tek giriş kapısıdır: kimlik kontrolü ve yönlendirme orada yapılır. Ama beş farklı odadan bilgi toplamaz, seni sadece doğru odaya yollar.

Hızlı kontrolOrta

Beş servisten veri çeken bir sayfanın önüne gateway koydun. Açılma süresi ne olur?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Satır satır: bir ürün sayfası

Aynı sayfa, katman katman

urun-sayfasi.http
şu an çalışan satırGET /api/products/42
2GET /api/prices/42
3GET /api/stock/42
4GET /api/reviews?productId=42
5GET /api/recommendations?productId=42
6
7# gateway sonrası: aynı beş çağrı, tek adres
8GET /gw/products/42
9
10# BFF sonrası: tek çağrı, sayfaya biçilmiş yanıt
11GET /mobile/product-page/42

Debug

Adım 1/6

doğrudan İstemci beş servisi de tanıyor. Her biri kendi yetkilendirmesini yapıyor — aynı kural beş yerde.

istemci çağrısı
= 5
auth
= 5 yerde
HTTPUTF-8LF1:1

Sol/sağ ok tuşlarıyla da gezebilirsin.

Buradaki asıl fikir şu: over-fetchingİstemcinin ihtiyacından fazla veri indirmesi. Servis kendi modelini döndürdüğü, ekranın neye ihtiyacı olduğunu bilmediği için olur.Mobilde asıl maliyet baytların kendisi değil, o baytları taşıyan ek gidiş-dönüşlerdir. Under-fetching tersidir: tek çağrı yetmez, istemci ikinci bir çağrı yapmak zorunda kalır.Sözlükte gör →’in maliyeti baytlarda değil, o baytları taşıyan gidiş-dönüşlerde. Mobil bir ağda tek bir round trip, veri merkezi içindeki yirmi hop’tan pahalıdır.

Hızlı kontrolOrta

Mobil istemcide over-fetching'in asıl maliyeti nedir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Her sorumluluğu, ait olduğu katmana göre ayır.

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Sınıflandırılmamış

Gateway veya BFF

İsteğin kim olduğu ya da hangi ekrana gittiğiyle ilgili

    Domain servisi

    İşin kuralıyla ilgili

      Kendin gör

      Aynı sayfa, dört topoloji

      Tohum 5
      1. Doğrudan çağrı
      2. Gateway
      3. BFF
      4. Katman yığını

      İstemci beş servisi tek tek çağırıyor.

      1. İstemci
      2. 5 servis
      İstemci çağrısı
      5
      Auth kaç yerde
      5
      Sunucu içi hop
      1
      Şekli değiştirmek için
      5 ekip
      Bu ağda sayfa süresi ve fazladan inen veri
      TopolojiSayfa süresiFazla veri
      Doğrudan çağrı605 ms42 KB
      Gateway610 ms42 KB
      BFFen hızlı135 ms3 KB
      Katman yığını145 ms3 KB
      Hız
      Adım 0

      Şu an ne oldu?

      5 çağrı, 605 ms

      Her servis kendi yetkilendirmesini yapıyor — 5 ayrı yerde aynı kural. İstemci 42 KB fazladan veri indiriyor çünkü servisler sayfayı değil kendi modellerini döndürüyor. Bu ağda BFF daha hızlı (135 ms).

      Aklında kalsın: Katmansız topoloji en az hop demektir; bedeli, istemcinin servis sayısını ve her servisin güvenliği bilmesidir.

      Görevler0/3

      • Yetkilendirmeyi beş yerden tek yere indiraçık

        İpucu

        "Gateway koy"a bas. İstemci hâlâ beş çağrı yapıyor, ama güvenlik artık tek kapıda.

      • Sayfayı tek bir istemci gidiş-dönüşüyle ve tek sahip ekiple çizaçık

        İpucu

        Gateway’den sonra "BFF ekle". Birleştirme istemciden sunucuya geçiyor.

      • Doğrudan çağrının en hızlı olduğu bir ağ koşulu bulaçık

        İpucu

        İstemci aynı veri merkezindeyse gidiş-dönüş ucuz, sunucu içi hop pahalı olabilir. Slider’ları iki uca çek.

      Olay günlüğü (0)

      Henüz olay yok. Oynat veya adımla.

      Sırayla dene:

      1. Başlangıçta istemci beş servisi tek tek çağırıyor. “Gateway koy”a bas — auth beş yerden bire indi ama sayfa süresi arttı.
      2. “BFF ekle”ye bas: çağrı sayısı bire düştüğü için süre de düştü. Asıl kazanç burada.
      3. İstemci gidiş-dönüşünü 10 ms’ye, hop maliyetini 60 ms’ye çek. Şimdi doğrudan çağrı kazanıyor — istemci yakın ve sunucu içi pahalıysa her katman bir vergi.
      4. “Katman yığ”a bas: hiçbir ağda kazanmıyor. BFF’in verdiği her şeyi veriyor, üstüne iki hop ve iki ayrı auth noktası ekliyor.
      5. Görevleri tamamla. Sonuncusu, BFF’in her ağda kazanmadığını gösteriyor.

      Tuzaklar

      Gateway’i tek arıza noktası yapmak. Her istek oradan geçiyorsa düştüğünde her şey düşer. En az iki örnek, sağlık kontrolü ve gateway’in kendi bağımlılıklarını en aza indirmek şart.

      Her istemci için BFF, ama sahipsiz. BFF’in değeri istemci ekibinin sahipliğinden gelir. Platform ekibinin baktığı bir BFF, adı değişmiş bir gateway’dir — ve her ekran değişikliği yine başka bir ekibin kuyruğunda bekler.

      Paylaşılan BFF. Mobil ve web aynı BFF’i kullanmaya başladığında yanıt ikisine birden yetecek kadar büyür. O noktada elinde BFF değil, ikinci bir genel amaçlı API vardır.

      Aşağıdaki örnek bir bankanın mobil uygulamasının hesap detay ekranı: her katman yalnızca kendi sorusuna cevap veriyor.

      Derinleş · Hesap detay ekranı: gateway, BFF ve domain servisi 5 dosya · ~98 satır · ilk okumada atlayabilirsin
      Proje dosyaları

      gateway/src/main/resources/ application.yml Gateway: kim olduğunu doğrular, istemci başına hız sınırı koyar ve yönlendirir. İş kuralı yok.

      gateway/src/main/resources/application.yml
      spring:
      cloud:
      gateway:
      routes:
      - id: mobile-bff
      uri: lb://mobile-bff
      predicates:
      - Path=/mobile/**
      filters:
      - TokenRelay= # pass the verified token downstream
      - name: RequestRateLimiter
      args:
      key-resolver: "#{@clientIdKeyResolver}" # per app installation, not per IP
      redis-rate-limiter.replenishRate: 20
      redis-rate-limiter.burstCapacity: 40
      - id: open-banking
      uri: lb://open-banking-api
      predicates:
      - Path=/openbanking/** # third-party apps: a separate route and limit
      security:
      oauth2:
      resourceserver:
      jwt:
      issuer-uri: https://auth.bank.example/realms/retail

      mobile-bff/src/main/java/com/bank/bff/ AccountPageController.java Mobil BFF: ekranın tek çağrısı. Üç servisi sunucu tarafında birleştirir, ekrana biçilmiş cevabı döner.

      mobile-bff/src/main/java/com/bank/bff/AccountPageController.java
      @RestController
      @RequestMapping("/mobile/accounts")
      class AccountPageController {
      private final AccountsClient accounts;
      private final MovementsClient movements;
      private final CardsClient cards;
      AccountPageController(AccountsClient accounts, MovementsClient movements, CardsClient cards) {
      this.accounts = accounts;
      this.movements = movements;
      this.cards = cards;
      }
      // One round trip from the phone. The three calls happen inside the data centre.
      @GetMapping("/{iban}/page")
      AccountPageView page(@PathVariable String iban, @AuthenticationPrincipal Jwt token) {
      var account = accounts.get(iban);
      var lastTen = movements.latest(iban, 10);
      var debitCard = cards.debitCardFor(iban); // may be empty
      return AccountPageView.of(account, lastTen, debitCard);
      }
      }

      mobile-bff/src/main/java/com/bank/bff/ AccountPageView.java Ekranın cevabı: yalnızca bu ekranın gösterdiği alanlar, gösterilecek biçimde (maskeli IBAN, hazır metin).

      mobile-bff/src/main/java/com/bank/bff/AccountPageView.java
      // Shaped for this one screen: nothing the screen does not show, nothing the phone must reformat.
      public record AccountPageView(
      String title, // "Vadesiz TL · …1326"
      String maskedIban, // "TR33 **** **** **** **** **13 26"
      String availableBalance, // "12.450,75 TL", formatted server-side for the tr-TR locale
      List<MovementRow> latest,
      Optional<String> debitCardLast4) {
      public record MovementRow(String date, String description, String amount, boolean incoming) {}
      static AccountPageView of(AccountDto account, List<MovementDto> movements, Optional<CardDto> card) {
      // formatting helpers omitted
      return new AccountPageView(Titles.of(account), Ibans.mask(account.iban()),
      Money.format(account.available()), MovementRow.from(movements),
      card.map(CardDto::last4));
      }
      }

      transfer-service/src/main/java/com/bank/transfer/ TransferLimitPolicy.java Transfer limiti bir iş kuralıdır: domain servisinde yaşar. Hangi ekrandan gelindiğini bilmez.

      transfer-service/src/main/java/com/bank/transfer/TransferLimitPolicy.java
      // The rule lives with the domain that owns it. Mobile, web, branch and the open-banking
      // API all reach it, so they all get the same answer.
      @Component
      class TransferLimitPolicy {
      private final DailyUsage usage;
      private final CustomerLimits limits;
      TransferLimitPolicy(DailyUsage usage, CustomerLimits limits) {
      this.usage = usage;
      this.limits = limits;
      }
      LimitCheck check(String customerNo, Channel channel, BigDecimal amount, LocalDate day) {
      BigDecimal limit = limits.dailyLimit(customerNo, channel); // set by the customer, capped by the bank
      BigDecimal used = usage.of(customerNo, channel, day);
      return used.add(amount).compareTo(limit) <= 0
      ? LimitCheck.ok(limit.subtract(used).subtract(amount))
      : LimitCheck.exceeded(limit.subtract(used));
      }
      }

      gateway/src/main/java/com/bank/gateway/ DoNotDoThis.java Gateway'e sızmış bir kural: 'küçük bir kontrol' olarak başlar, sahipsiz kalır. Doğru yeri bir önceki dosya.

      gateway/src/main/java/com/bank/gateway/DoNotDoThis.java
      // A business rule that leaked into the gateway. It started as "just one check":
      // now web and branch are not covered, nobody owns it, and it cannot see the daily usage.
      @Component
      class TransferAmountFilter implements GlobalFilter {
      @Override
      public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      if (exchange.getRequest().getPath().value().startsWith("/mobile/transfers")) {
      // parse the body, compare the amount with a hard-coded 50 000 … (the smell)
      }
      return chain.filter(exchange);
      }
      }
      Kafam karıştı, daha basit anlat

      Tek bir giriş kapısı kapanırsa bina kapanır. Kapıyı en az iki tane yap ve kapıya iş kuralı taşıma.

      Kendini sına

      Şimşek turu1/5

      Gateway, isteği doğru servise yönlendiren ortak kapıdır.

      Soru 1/4Orta

      BFF beş servisi paralel çağırıyor. Yorum servisi hata döndürüyor — istemci ne görür?

      Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.
      ProductPageBff.java
      1CompletableFuture<Product> p = catalogue.get(id);
      2CompletableFuture<Price> c = pricing.get(id);
      3CompletableFuture<List<Review>> r = reviews.get(id); // bu servis 500 dönüyor
      4
      5CompletableFuture.allOf(p, c, r).join();
      6
      7return new PageDto(p.join(), c.join(), r.join());
      Java 21UTF-8LF

      Aklında kalacak üç şey

      1. 1 Gateway gecikmeyi çözmez, tekrarı çözer: kimlik kontrolü ve istek sınırı gibi ortak işleri tek bir yerde toplar.
      2. 2 Kullanıcının cihazı ile sunucu arasındaki gidiş dönüşleri azaltan katman BFF'tir. Pahalı olan ağ, sunucuların kendi arasındaki değil, kullanıcıya giden ağdır.
      3. 3 Her katman hangi soruyu cevapladığını söyleyebilmeli. Söyleyemeyen katman yalnızca fazladan bir durak ve bir koordinasyon yüküdür.
      Sonraki kapı Mobil ve web aynı arka ucu mu kullanmalı, yoksa her ekranın kendi arka ucu mu olmalı? BFF — Backend for Frontend · 10 dk

      5 kart sonraki derste seni bekliyor

      0/5 kart bu dersten toplandı

      Bu dersin üstüne kurulanlar

      Bunlar bu dersi temel alıyor; hazır olduğunda devam edebilirsin.