İçeriğe geç

Backpressure ve Yük Atma — Kuyruk Dolarsa Ne Olur?

Orta 9 dk Sık karşılaşılır

Önce şunu oku: Rate Limiting — Kapıdan Saniyede Kaç Kişi Geçer?

30 saniyede özet

Bir kuyruk kısa bir patlamayı emer, ama sürekli fazla yükü çözmez: yalnızca geciktirir. Sınırsız kuyrukta bekleme süresi ve bellek durmadan büyür. Sınırlı kuyruk ya fazlasını hızlıca reddeder ya da çağıranı yavaşlatır.

Saatte 100 ekmek pişiren bir fırın düşün. Sabah kalabalığında kapıda sıra oluşur, öğlene doğru erir. Ama her saat 120 kişi gelirse sıra hiç erimez; her saat biraz daha uzar.

  1. Bayt: Bildirim servisimiz hiçbir isteği reddetmiyor. Hepsini kuyruğa alıyor, hepsini işliyor!

  2. Sen: Kullanıcılar bildirimlerin dakikalar sonra geldiğini söylüyor.

  3. Bayt: Ama hiçbiri kaybolmadı... yalnızca çok bekledi.

  4. Bayt: Kaybolmamak ile zamanında gelmek ayrı şeyler. Kuyruğun içine bakalım.

Kuyruk neyi çözer?

Bir servis saniyede 100 istek işliyorsa, kısa süreli 150’lik bir patlamayı önündeki kuyruk emer. Patlama geçince kuyruk erir ve herkes biraz gecikmeyle de olsa cevap alır.

Gelen yük sürekli 120 ise hesap değişir: kuyruk her saniye 20 istek büyür. Hiçbir istek reddedilmez, ama hiçbiri de zamanında cevap almaz.

Kafam karıştı, daha basit anlat

Kuyruk kısa kalabalığı emer. Sürekli fazla yükte ise yalnızca büyür.

Hızlı kontrolBaşlangıç

Bir servisin önündeki kuyruğun asıl işi nedir?

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

Servis saniyede 100 işliyor, saniyede sürekli 120 istek geliyor ve kuyruk sınırsız. 10 saniye sonra kuyrukta kaç istek olur?

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

Bekleme ne kadar?

Servis saniyede 100 istek işliyor ve önünde 200 istek bekliyor. Kuyruğa yeni giren bir istek yaklaşık kaç saniye bekler? Cevabı göster

Yaklaşık 2 saniye. Önündeki 200 isteğin işlenmesi, saniyede 100 hızla 2 saniye sürer.

Kuyruk patlamayı emer, fazlalığı çözmez.
Adım adım oku
  1. Sabah kalabalığı: sıra uzar, sonra erir.
  2. Her saat kapasiteden fazla insan gelirse sıra hep uzar.
  3. Sıra sınırı: ya 'sonra gelin' ya da 'şimdilik gönderme'.
  4. Kuyruk patlamayı emer; sürekli fazlalığı çözmez.

Bu hesap Little yasasıKuyruktaki iş sayısı, geliş hızı ile ortalama bekleme süresinin çarpımıdır (L = λW). Kuyruk büyürse bekleme de aynı oranda büyür.Sözlükte gör →ndan gelir: bekleme süresi, kuyruk uzunluğunun işleme hızına bölümüdür. Kuyruk büyüdükçe bekleme de aynı oranda büyür.

Sürekli fazla yükte iki dürüst seçenek var. Kuyruğu sınırlayıp fazlasını hızlıca reddetmek load sheddingKapasite aşıldığında fazla istekleri bilerek ve hızlıca reddetmek (örneğin 429). Kabul edilenlerin zamanında cevap almasını korur.Sözlükte gör →dır; kuyruk doluyken çağıranı bekletmek ise backpressureÜretici tüketiciden hızlı olduğunda akışı yavaşlatma mekanizması. Kuyruk büyütmek backpressure değildir — sadece çöküşü erteler.Sözlükte gör →.

Kafam karıştı, daha basit anlat

Bekleme, kuyruk uzunluğu bölü hız. Fazla yükte ya fazlasını geri çevir ya da göndereni yavaşlat.

Hızlı kontrolOrta

Saniyede 100 işleyen bir servisin önünde 200 istek var. Yeni gelen bir istek yaklaşık ne kadar bekler?

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

Load shedding (yük atma) ile backpressure arasındaki fark nedir?

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

Kendin gör

Kuyruk dolarsa ne olur?

Tohum 831741
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10

Oynat ya da adımla: her adım iki saniye.

Hız
Adım 0

Şu an ne oldu?

Sınırsız kuyruk · Sürekli fazla yük (120/sn)

Servis saniyede 100 istek işliyor. Fazlası bir yere gitmek zorunda.

Görevler0/3

  • Hiçbir isteği reddetmeden beklemeyi 2 saniyeye çıkaraçık

    İpucu

    Varsayılan ayarlar yeter.

  • Sürekli fazla yükte beklemeyi yarım saniyede tutaçık

    İpucu

    Bir kısmını hızlıca geri çevir.

  • Kısa bir patlamayı hiç reddetmeden em ve kuyruğu boşaltaçık

    İpucu

    Kuyruğun asıl işi bu.

Olay günlüğü (0)

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

  1. Varsayılanla oynat. Sınırsız kuyruk, sürekli fazla yük: bekleme 2 saniyeye çıktı ve büyüyor.
  2. “Reddet” politikasına geç. Bekleme yarım saniyede kaldı, fazlası 429 aldı.
  3. “Çağıranı beklet” seç. Reddedilen yok, ama baskı yukarıya taşındı.
  4. Yükü “kısa patlama” yap, sınırsız kuyrukla oynat. Patlama emildi ve kuyruk boşaldı.
  5. Aynı patlamayı “reddet” ile dene. Sınır küçük olduğu için 50 iyi istek reddedildi.
Hızlı kontrolOrta

Kısa bir patlamada (2 saniye 150/sn) çok küçük sınırlı bir kuyruk ret politikasıyla kullanıldı. Ne olur?

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

Java'da new ThreadPoolExecutor(..., new LinkedBlockingQueue<>()) ile kurulan havuzun kuyruğu nasıldır?

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

Tuzaklar

Sınırsız kuyruk varsayılanı. Birçok kütüphanenin varsayılan kuyruğu sınırsızdır. Fazla yükte sessizce bellek tüketir ve sonunda servisi düşürür; sınırı bilerek koy.

Zaman aşımını unutmak. Kuyrukta 30 saniye bekleyen bir isteğin çağıranı 5 saniyede vazgeçmiş olabilir. Vazgeçilmiş işi yapmak kapasiteyi boşa harcar; kuyruktan çıkarken isteğin hâlâ beklenip beklenmediğine bak.

Reddi hata gibi göstermek. 429 bir kaza değil, bir karardır. Retry-After ile ne zaman tekrar denenebileceğini söyle; çağıranlar da hemen değil, artan aralıklarla tekrar denesin.

Kafam karıştı, daha basit anlat

Kuyruğu sınırla, vazgeçilmiş işi atla, reddi açık ve kibar yap.

Hızlı kontrolOrta

Kuyrukta 30 saniye bekleyen bir isteğin çağıranı 5 saniyede vazgeçmişti. İşi yine de yapmanın sorunu nedir?

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

Aşağıdaki örnek bir bankanın bildirim servisinden: sınırlı kuyruk, dolunca hızlı ret, kuyruktan çıkarken süre kontrolü.

Derinleş · Bildirim servisi: sınırlı kuyruk, hızlı ret, süresi geçmiş işi atlama 4 dosya · ~62 satır · ilk okumada atlayabilirsin
Proje dosyaları

src/main/java/com/bank/notify/ NotifyExecutor.java Havuz: sınırlı kuyruk; dolunca istek bekletilmez, reddedilir.

src/main/java/com/bank/notify/NotifyExecutor.java
@Configuration
class NotifyExecutor {
@Bean
ThreadPoolExecutor notifyPool() {
return new ThreadPoolExecutor(
8, 8, 0, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(500), // bounded: never an unbounded queue here
new ThreadPoolExecutor.AbortPolicy()); // full -> RejectedExecutionException, fast
}
}

src/main/java/com/bank/notify/ NotifyController.java Uç nokta: ret 429 ve Retry-After ile dönüyor; çağıran ne zaman deneyeceğini biliyor.

src/main/java/com/bank/notify/NotifyController.java
@RestController
@RequestMapping("/notifications")
class NotifyController {
private final ThreadPoolExecutor pool;
private final Notifier notifier;
NotifyController(ThreadPoolExecutor notifyPool, Notifier notifier) {
this.pool = notifyPool;
this.notifier = notifier;
}
@PostMapping
ResponseEntity<Void> send(@RequestBody Notification notification) {
Instant deadline = Instant.now().plusSeconds(5);
try {
pool.execute(() -> notifier.sendIfStillWanted(notification, deadline));
return ResponseEntity.accepted().build();
} catch (RejectedExecutionException full) {
// Load shedding as a decision, not an accident.
return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).header("Retry-After", "2").build();
}
}
}

src/main/java/com/bank/notify/ Notifier.java İş: kuyruktan çıktığında süresi dolmuşsa yapılmıyor; kapasite vazgeçilmiş işe gitmiyor.

src/main/java/com/bank/notify/Notifier.java
@Component
class Notifier {
private final PushGateway push;
private final Clock clock;
Notifier(PushGateway push, Clock clock) {
this.push = push;
this.clock = clock;
}
void sendIfStillWanted(Notification notification, Instant deadline) {
if (clock.instant().isAfter(deadline)) {
return; // the caller gave up long ago; spending capacity here helps no one
}
push.send(notification);
}
}

src/main/java/com/bank/notify/ NotifyMetrics.java Metrikler: kuyruk uzunluğu ve ret sayısı izleniyor; bekleme, kuyruk bölü hızdan okunur.

src/main/java/com/bank/notify/NotifyMetrics.java
@Component
class NotifyMetrics {
NotifyMetrics(MeterRegistry registry, ThreadPoolExecutor notifyPool) {
// Wait ≈ queue length / throughput: watch the length, not just CPU.
Gauge.builder("notify.queue.size", notifyPool, pool -> pool.getQueue().size()).register(registry);
Gauge.builder("notify.queue.remaining", notifyPool, pool -> pool.getQueue().remainingCapacity()).register(registry);
}
}

Kendini sına

Şimşek turu1/4

Sınırsız bir kuyruk sürekli fazla yükü çözer, çünkü hiçbir isteği reddetmez.

Soru 1/3İleri

Bir istemci 429 aldıktan sonra hemen ve sürekli tekrar deniyor. Ne olur ve nasıl düzeltilir?

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

Aklında kalacak üç şey

  1. 1 Kuyruk kısa patlamaları emmek içindir. Gelen yük işleme kapasitesini sürekli aşıyorsa kuyruk her saniye büyür; hiçbir istek reddedilmez ama her biri daha uzun bekler.
  2. 2 Bekleme süresi, kuyruk uzunluğunun işleme hızına bölümüdür. Saniyede 100 işleyen bir servisin önünde 200 kişilik kuyruk, yeni gelen için 2 saniye bekleme demektir.
  3. 3 Sürekli fazla yükte iki dürüst seçenek var: fazlasını hızlıca reddetmek (yük atma) ya da çağıranı yavaşlatmak (backpressure). Sınırsız kuyruk sorunu yalnızca saklar.
Sonraki kapı Servis üç saniyeliğine düştü. Neden bir dakika sonra hâlâ ayağa kalkamıyor? Retry, Backoff ve Jitter — Herkes Aynı Anda Tekrar Denerse · 9 dk

4 kart sonraki derste seni bekliyor

0/4 kart bu dersten toplandı