JVM Konteynerde CPU — Ortalama Düşük, İstek Neden Yavaş?
Önce şunu oku: JVM Konteynerde — Bellek Sınırı Heap'ten Büyüktür
30 saniyede özet
Konteynerin CPU limiti, her 100 ms'lik dilimde bütün thread'lerin paylaştığı bir zaman kotasıdır. Kısa anda çok çekirdek kullanan iş kotayı erken bitirip bekler; ortalama CPU düşük görünürken istekler yavaşlar.
Bir havuzun bileti saatte altmış dakika yüzme hakkı veriyor. Dört arkadaş birlikte yüzerse bu dakikaları çeyrek saatte bitirir. Kalan kırk beş dakikayı kenarda bekleyerek geçirirler.
-
Bayt: Ödeme servisinin CPU grafiğine baktım: limitin yüzde otuzu. Rahat görünüyor.
-
Sen: Ama bazı istekler normalin üç katı sürüyor. Ne veritabanı yavaş ne ağ.
-
Bayt: Konteynerin throttle sayacı durmadan artıyor! CPU boştaymış gibi görünürken bekliyormuşuz.
-
Bayt: Limit bir çekirdek sayısı değilmiş; bir zaman kotasıymış.
Limit aslında ne?
Kubernetes’te bir konteynere CPU request ve limitKubernetes'te request, pod'un yerleştirilirken garanti edilen CPU payıdır; limit ise aşılamayan tavandır.Sözlükte gör → verilir. Linux bu limiti, her 100 ms’lik dilimde kullanılabilecek bir CPU zamanı kotası olarak uygular.
Kota bütün thread’ler arasında paylaşılır. Dört thread aynı anda çalışırsa, bir CPU’luk kotayı 25 ms’de bitirir.
Kafam karıştı, daha basit anlat
CPU limiti, her 100 ms’de kullanılabilecek bir zaman payıdır; bütün thread’ler aynı payı harcar.
Konteynere limits.cpu: 1 verildi. Bu tam olarak ne demektir?
Request ile limit arasındaki fark nedir?
Ortalama neden yanıltır?
Limit 1 CPU. Bir istek 300 ms CPU işi istiyor ve bunu dört thread'e bölüyor. Limitsiz 75 ms'de biterdi. Bu limitle ne kadar sürer? Cevabı göster
Yaklaşık 225 ms. Her 100 ms’lik dilimde kota ilk 25 ms’de biter; dört thread kalan 75 ms’yi bekler. Üç dilim sürer ve istek üç kat yavaşlar.
Adım adım oku
- Havuz bileti: saatte altmış dakika yüzme.
- Dört arkadaş birlikte yüzüyor.
- On beş dakikada bilet bitti, kırk beş dakika kenarda.
- Günlük ortalama az; bekleme yine de gerçek.
Kota bitince bütün thread’lerin beklemesine CPU throttlingKonteynerin bir zaman dilimindeki CPU kotası bitince bütün thread'lerinin bir sonraki dilime kadar bekletilmesi.Sözlükte gör → denir. Saniyede bir böyle istek gelirse, ortalama CPU kullanımı limitin yalnızca yüzde otuzu görünür.
Bu yüzden throttling’i ortalama değil, konteynerin cgroupLinux çekirdeğinin bir süreç grubuna bellek ve CPU sınırı koyduğu mekanizma. Docker ve Kubernetes konteyner sınırlarını bununla uygular.JDK 10'dan beri JVM sınırları cgroup'tan okur (UseContainerSupport). Bellek sınırı sürecin bütün belleğini sayar.Sözlükte gör → sayaçları gösterir: kaç dilimde beklendiği ve toplam ne kadar beklendiği.
Kafam karıştı, daha basit anlat
Kısa patlamalar kotayı erkenden bitirir. Ortalama düşük görünürken istek bekler.
Kota bir dilimin ortasında biterse ne olur?
Ortalama CPU kullanımı limitin %30'u görünüyor ama istekler yavaş. Ne olabilir?
Kendin gör
Bir ödeme isteği, dört thread, bir CPU limiti
Tohum 849024Geçen: 0 ms · iş: 0/300 ms · ⏸ bekleme: 0 ms · saniyelik ortalama: limitin %30’i
Şu an ne oldu?
limits.cpu: 1
İstek 300 ms CPU işi istiyor; dört thread aynı anda çalışıyor.
Görevler0/3
İstek kotaya takılıp beklesinaçık
İpucu
Limiti düşür.
İstek limitsiz hâlinin üç katı sürsünaçık
İpucu
Tek CPU.
İstek hiç beklemeden bitsinaçık
İpucu
Limiti kaldır.
Olay günlüğü (0)
Henüz olay yok. Oynat veya adımla.
- Varsayılanla oynat. Limit 1 CPU: her dilim bir “çalış” ve üç “bekle”. İstek 225 ms sürdü, 150 ms’si bekleyerek geçti.
- “limits.cpu: 2” seç. İstek 125 ms’de bitti; yine de 50 ms bekledi.
- “Limit yok” seç. Dört thread hiç beklemeden 75 ms’de bitirdi.
Throttling'i doğrudan gösteren ölçüm hangisi?
limits.cpu: 1 olan bir konteynerde JDK 17 için Runtime.availableProcessors() ne döner?
Tuzaklar
JVM’in gördüğü CPU sayısını unutmak. Modern JVM limiti görür; availableProcessors() 1 dönerse GC ve ortak havuzların boyutları küçülür, varsayılan GC bile değişebilir. Bunu -XX:ActiveProcessorCount ile açıkça belirleyebilirsin.
Thread sayısını artırmak. Daha çok thread, aynı kotayı daha hızlı bitirir. Throttling’i azaltmaz, genelde artırır.
Limiti düşünmeden kaldırmak. Limitsiz CPU patlamaları kolaylaştırır, ama aynı makinedeki komşularla çekirdek için yarışılır. Throttle sayaçlarını ve gecikme yüzdeliklerini ölçerek karar ver.
Kafam karıştı, daha basit anlat
JVM’in CPU sayısına bak, thread ekleyerek çözmeye çalışma, limiti ölçerek ayarla.
availableProcessors() 1 döndüğünde JVM'de ne değişir?
Derinleş · Ödeme servisi: CPU limiti, JVM ve throttle ölçümü 3 dosya · ~58 satır · ilk okumada atlayabilirsin
Kendini sına
limits.cpu: 1 uygulamanın tek bir thread çalıştırabileceği anlamına gelir.
Bir ekip throttling yüzünden CPU limitini kaldırıp yalnızca request bırakıyor. Değiş tokuş nedir?
Aklında kalacak üç şey
- 1 CPU limiti bir çekirdek sayısı değil, her 100 ms'lik dilimde bütün thread'lerin paylaştığı bir CPU zamanı kotasıdır.
- 2 Kısa anda çok thread çalıştıran iş kotayı dilimin başında bitirir ve kalan süreyi bekler. Saniyelik ortalama ise düşük görünür.
- 3 Throttling'i ortalama CPU değil, cgroup'un throttle sayaçları ve gecikmenin yüksek yüzdelikleri gösterir.
4 kart sonraki derste seni bekliyor