Her gün bir blog Tek seferlik üretim CPU'su% 100 optimizasyon uygulaması

Sağ üst tarafa tıklayın, açık kaynak Çin OSC başlık numarasını takip edin, en son teknik bilgileri alın

Önsöz

Yıl sonuna kadar tedirgin oldu Son zamanlarda bir çalışma ve bakım alarmı aldım: bazı sunucular çok fazla yüke sahip. Sorunu bulalım.

Bunu gerçekten düşünüyordum.Birkaç gün önce bazı sunucuların yükünü bilinçli olarak artırdım (evet, patron benden bir hata yazmamı istedi!), Ama neyse ki, farklı ortamların birbirleri üzerinde hiçbir etkisi yok.

Konumlandırma sorunu

Sorunu aldıktan sonra önce sunucuya gittim ve sadece Java uygulamamızın çalıştığını gördüm. Bu nedenle, uygulamanın PID'sini almak için önce ps komutunu kullanın.

Sonra bu işlemin iş parçacığını görüntülemek için top -Hp pid'i kullanın. İşlemcileri CPU kullanım oranına göre sıralamak için büyük harf P'yi girin, böylece aşağıdaki sonuçlar elde edilir.

Elbette, bazı iş parçacığının CPU kullanımı çok yüksek.

Sorunun yerini kolaylaştırmak için hemen jstack pid kullanıyorum > pid.log, iş parçacığı yığınını günlük dosyasına döker.

İş parçacığının% 100'ünden rastgele bir pid = 194283 seçtim, onu onaltılık (2f6eb) haline dönüştürdüm ve iş parçacığı anlık görüntüsünde sorguladım:

Çünkü iş parçacığı anlık görüntüsündeki iş parçacığı kimliği onaltılık olarak saklanır.

Bunun Disruptor'un bir yığını olduğunu buldum Bir süre önce Disruptor kuyruğunun neden olduğu bir OOM'yi çözdüm: Disruptor'da bir bellek taşması olması daha mı iyi?

Beklenmedik bir şekilde tekrar çıktı.

İş parçacığının durum bilgisini daha sezgisel olarak görüntülemek için anlık görüntü bilgilerini özel olarak analiz edilmiş bir platforma yükledim.

CPU kullanan tüm iş parçacıkları gösteren bir menü var Daha yakından baktım ve neredeyse hepsinin yukarıdaki yığınla aynı olduğunu gördüm.

Başka bir deyişle, hepsi Disruptor kuyruğunun yığınlarıdır ve hepsi java.lang.Thread.yield işlevini yürütmektedir.

Hepimizin bildiği gibi, verim fonksiyonu mevcut iş parçacığının CPU kaynaklarından vazgeçmesine ve diğer iş parçacığının rekabet etmesine izin verecektir.

Şu andaki iş parçacığı anlık görüntüsüne göre, ÇALIŞTIRILABİLİR durumda yaklaşık 30 iş parçacığı olduğu ve tümünün verim işlevini çalıştırdığı bulundu.

Bu nedenle, ön karar, verim fonksiyonunu çalıştırdıktan sonra çok sayıda iş parçacığının birbiriyle rekabet ettiği ve bu da CPU kullanımında bir artışa yol açtığı ve yığının Disruptor kullanımıyla ilişkili olduğu tespit edildi.

Problemi çöz

Sonra kodu kontrol ettim ve her iş senaryosuna göre, iki Disruptor kuyruğunun dahili olarak ayrıştırmak için kullanıldığını gördüm.

Şu anda 7 iş türü olduğunu varsayarsak, 2 * 7 = 14 Disruptor kuyruğu oluşturmaya eşdeğerdir ve her kuyruğun bir tüketicisi vardır, yani toplamda 14 tüketici vardır (daha fazla üretim ortamı).

Aynı zamanda yapılandırılmış tüketim bekletme stratejisinin YieldingWaitStrategy olduğu bulunmuştur Bu bekleme stratejisi gerçekten CPU'dan vazgeçmek için verimi uygulayacaktır.

kod aşağıdaki gibi gösterilir:

Başlangıçta, bu bekleme stratejisiyle çok ilgisi var gibi görünüyor.

Yerel simülasyon

Doğrulamak için yerel olarak 15 Disruptor kuyruğu oluşturdum ve CPU kullanımını gözlemlemek için izleme ile birleştirdim.

15 Disruptor kuyrukları oluşturulur ve her kuyruk Disruptor kuyruğuna / kuyruğundan 100 W veri parçası göndermek için bir iş parçacığı havuzu kullanır.

Tüketici programı sadece bir baskıdır.

Bir süre çalıştıktan sonra CPU kullanımının gerçekten yüksek olduğunu gördüm.

Aynı zamanda, dökümü iş parçacığı keşfi ve üretimi olgusu da tutarlıdır: tüketen iş parçacıkları ÇALIŞTIRILABİLİR durumundadır ve hepsi verim gerçekleştiriyor.

Resmi Bozucu belgesini sorgulayarak şunu buldum:

YieldingWaitStrategy, performansı artırmak için spin + verim kullanarak CPU'yu tamamen sıkıştırmak için bir stratejidir. Bu strateji, olay işleyici iş parçacığı sayısı CPU çekirdeği sayısından az olduğunda önerilir.

Aynı zamanda, bir kilit mekanizması kullanan ve yüksek bir CPU kullanmayan BlockingWaitStrategy'yi (ayrıca varsayılan strateji) diğer bekleme stratejilerine de göz atın.

Bu nedenle, öncekiyle aynı koşullar altında, bekleme stratejisini BlockingWaitStrategy olarak değiştirin.

Şu anda CPU ile karşılaştırıldığında, kullanım oranının daha sonra önemli ölçüde azalacağını göreceksiniz; aynı zamanda, iş parçacığı atıldıktan sonra, iş parçacıklarının çoğunun bekleme durumunda olduğunu göreceksiniz.

Optimize edilmiş çözüm

Bekleme stratejisini BlockingWaitStrategy olarak değiştirmek CPU kullanımını yavaşlatabilir,

Ancak YieldingWaitStrategy'nin resmi açıklamasının şunu söylediğine dikkat edin: Bu strateji, olay işleyici iş parçacığı sayısı CPU çekirdeği sayısından az olduğunda önerilir.

Mevcut kullanım senaryosunda, tüketici iş parçacığı sayısının çekirdek CPU sayısını büyük ölçüde aştığı açıktır.Kullanım yöntemim Disruptor kuyruğu ve bir tüketici olduğu için kuyruğu yalnızca 1 olarak ayarlayıp tekrar denedim (strateji hala YieldingWaitStrategy).

Bir dakika çalıştıktan sonra, CPU kullanımının nispeten kararlı olduğunu ve yüksek olmadığını buldum.

sonuç olarak

Yani araştırmadan sonra bir sonuca varabiliriz Bu sorunu temelden çözmek için mevcut işimizi bölmemiz gerekiyor; şimdi N işletme aynı anda tek bir uygulamada işleniyor ve her işletme birkaç Disruptor kuyruğu kullanıyor.

Bir sunucuda çalıştığı için CPU kaynakları paylaşılır ve bu da CPU kullanımının yüksek kalmasına neden olur.

Dolayısıyla ayarlama yöntemimiz aşağıdaki gibidir:

  • Bu sorunu hızlı bir şekilde hafifletmek için, önce bekleme stratejisini BlockingWaitStrategy olarak değiştirin, bu da CPU kullanımını etkili bir şekilde azaltabilir (bu, iş dünyasında da kabul edilebilir).
  • İkinci adımda, uygulamanın bölünmesi gerekir (yukarıda simüle edilmiş bir Disruptor kuyruğu) ve bir uygulama bir iş türünü ele alır; daha sonra bunlar ayrı ayrı dağıtılır, böylece birbirlerini etkilemeden birbirlerinden izole edilebilirler.

Elbette başka optimizasyonlar da var, çünkü bu da eski bir sistem, bu sefer döküm iş parçacığı 800'den fazla iş parçacığının yaratıldığını keşfetti.

Bir iş parçacığı havuzu oluşturmanın yolu da çekirdek iş parçacığı sayısı ve maksimum iş parçacığı sayısı ile aynıdır, bu da bazı boş iş parçacıklarının geri dönüştürülmemesine neden olur; bu, çok fazla anlamsız kaynak tüketimine neden olur.

Bu nedenle, iş parçacığı havuzunun işle bağlantılı olarak yaratılma şeklini de ayarlayacağız, iş parçacığı sayısını azaltacağız ve onu en iyi şekilde kullanacağız.

Blog Yazarı: crossoverJie

Aşağıya tıklayın " daha fazlasını anla ", bu makalenin demo kodunu alın.

Bu uyuşturucu kartelinin 100.000'den fazla insanı var ve silahları ve teçhizatı ordununkilerden daha iyi, tepeden tırnağa silahlı.
önceki
Kadınlara istihdamda ayrımcılık yapılıyor mu? Ülke harekete geçiyor, müjde geliyor ...
Sonraki
Forbes, 2018'de teknolojide en etkili kadınların listesini yayınladı: Liu Qing, dünyada sekizinci sırada
Yatırım istatistikleri: mobil İnternet finansmanı 2017'de düştü, sermaye mobil oyun projelerinin peşinde
Tıbbi güzellik kurumları ve özel hastaneler, 50.000 kişinin "kanseri önleyebileceğini" iddia ederek "arınmayı ve güzelliği" teşvik ediyor
Aylık 10.000 yuan maaş hala insanları işe alamıyor, gençler fabrikaya gitmek yerine yiyecek dağıtmayı tercih ediyor
Şu andan itibaren kimlik kartı, ortodonti ve diş implantları ile bu 10 masrafın tamamı ücretsiz!
3 yaşındaki kızım kıyafet değiştirdiğinde annem kırmızı yapışkan bir salgı buldu! Bu kanser olduğu ortaya çıktı
2018'de Çin'in otomotiv lojistiği endüstrisinin pazar durumu ve beklenti analizi Araç lojistiği + satış sonrası hizmet, endüstrinin sağlıklı gelişimini destekler
BMW Daimler, otonom sürüş patentlerini paylaşıyor: el ele tutuşan "kan davalarının" arkasındaki acı verici hareket
Günlük blog | Kafka çok iş parçacıklı işleme ağı G / Ç ve iş dağıtımı
İsrail tarafından geliştirilen en son siyah teknoloji: düşmana iki gözle nişan alın ve dokunarak da kullanılabilir
Tek viteste iki zombi arabası, otobüs durağı bir "hizmet odası" haline geldi
WeChat çok fazla hafızaya sahip mi? Temizlemeyi bırakın, bu üç işlevi kapatın, telefon hemen pürüzsüz olacak
To Top