Birçok Engelleme VS Tek Engellemeyen İşçi


9

Bağlantıları kabul eden bir HTTP sunucusu olduğunu varsayalım ve daha sonra bir şekilde başlıkların tamamen gönderilmesini bekler. Bunu uygulamanın en yaygın yolu ve kalan artıları ve eksileri nelerdir merak ediyorum. Sadece bunları düşünebilirim:

Birçok engelleme çalışanı iyidir çünkü:

  • Daha duyarlı.
  • Yeni bağlantılar tanıtmak daha kolay (işçiler, senkronize bir listeye ekleyene kadar yabancıdan beklemek yerine onları kendiliğinden alırlar).
  • Bağlantı sayısı arttıkça ve azaldıkça CPU kullanımı otomatik olarak (ek çaba gerektirmeden) dengelenir.
  • Daha az CPU kullanımı (engellenen iş parçacıkları yürütme döngüsü dışına alınır ve istemciler arasında atlama için herhangi bir mantık gerektirmez).

Tek engelleme yapmayan işçi iyidir çünkü:

  • Daha az bellek kullanır.
  • Tembel istemcilere karşı daha az savunmasızdır (sunucuya bağlanır ve başlıkları yavaş gönderir veya hiç göndermez).

Muhtemelen görebileceğiniz gibi, bence birden fazla işçi iş parçacığı genel olarak biraz daha iyi bir çözüm gibi görünüyor. Bununla ilgili tek sorun, böyle bir sunucuya saldırmanın daha kolay olmasıdır.

Düzenleme (daha fazla araştırma): Web'de bulduğum bazı kaynaklar ( Binler İş Parçacığı ve G / Ç Engelleme - Java Sunucuları yazmanın eski yolu Paul Tyma tarafından tekrar Yeni (ve daha iyi) ), engelleme yaklaşımının genellikle daha iyi olduğunu ancak Sahte bağlantılarla nasıl başa çıkacağımı hala bilmiyorum.

PS Görev için bazı kütüphane veya uygulamaların kullanılmasını önermeyin. Çalışmasını değil, aslında nasıl çalıştığını veya çalışabileceğini bilmekle daha fazla ilgileniyorum.

PSS Ben mantığı birden çok parçaya ayırdım ve bu sadece HTTP üstbilgilerini kabul etmekle ilgileniyor. Onları işlemez.


Lo, bu yıllar önce, yazımı kolay olduğu için G / Ç'yi engelleyen dişli bir sunucu yazdım. Bir meslektaşım diğer türünü yazdı ve takdirle çalıştı. Bunlar, eskiden çalıştığım bir şirkette ana ürün teklifinin iki biçimiydi. Engelleme senaryosundaki "tembel istemciler" için veri alımında zaman aşımı olabilir.

Yanıtlar:


4

Gümüş mermi yok

Uygulamada duruma göre değişir ...

tl; dr - kolay çözüm, nginx kullanın ...

Engelleme:

Örneğin, Apache varsayılan olarak, işlemin her bağlantı için çatallandığı bir engelleme şeması kullanır. Bu, her bağlantının kendi bellek alanına ihtiyacı olduğu ve bağlantı sayısı arttıkça bağlam değiştirme yükünün daha fazla arttığı anlamına gelir. Ancak fayda, bir bağlantı kapatıldığında bağlam atılabilir ve herhangi bir / tüm bellek kolayca alınabilir.

Çok iş parçacıklı bir yaklaşım, bağlam anahtarlamasının ek yükünün bağlantı sayısıyla artmasıyla benzerdir, ancak paylaşılan bir bağlamda daha fazla bellek verimliliği sağlayabilir. Böyle bir yaklaşımla ilgili sorun, paylaşılan belleği güvenli bir şekilde yönetmenin zor olmasıdır. Bellek senkronizasyonu sorunlarının üstesinden gelmek için yaklaşımlar genellikle kendi ek yüklerini içerir, örneğin kilitleme CPU-yoğun yüklerde ana iş parçacığını dondurabilir ve değişmez türlerin kullanılması, verilerin çok sayıda gereksiz kopyalanmasını ekler.

AFAIK, engellenen bir HTTP sunucusunda çok işlemli bir yaklaşım kullanarak genellikle tercih edilir, çünkü belleği güvenli bir şekilde yönetmek / kurtarmak daha güvenlidir / daha basittir. Belleği kurtarmak bir işlemi durdurmak kadar basit olduğunda, çöp toplama sorunu olmaz. Uzun süren süreçler (yani bir daemon) için bu özellik özellikle önemlidir.

Bağlam değiştirme yükü az sayıda işçiyle önemsiz gibi görünse de, yük yüzlerce ila binlerce eşzamanlı bağlantıya kadar ölçeklendiğinden dezavantajlar daha alakalı hale gelir. Bağlam değiştirme en iyi ihtimalle O (n) 'yi mevcut işçi sayısına göre ölçeklendirir, ancak pratikte daha kötüdür.

Engelleme kullanan sunucuların IO ağır yükleri için ideal bir seçenek olmadığı durumlarda, CPU-yoğun çalışma için idealdir ve mesaj aktarımı minimumda tutulur.

Sigara Engelleme:

Engellememek Node.js veya nginx gibi bir şey olacaktır. Bunlar özellikle IO-yoğun yük altında düğüm başına çok daha fazla sayıda bağlantıya ölçeklendirme için bilinir. Temel olarak, insanlar hangi iş parçacığı / süreç tabanlı sunucuların üstesinden gelebileceğinin üst sınırına ulaştığında alternatif seçenekleri keşfetmeye başladılar. Bu başka türlü C10K problemi olarak bilinir (yani 10.000 eşzamanlı bağlantıyı yönetme yeteneği).

Engellemeyen asenkron sunucular genellikle ana iş parçacığını aşırı yüklemek istemediğiniz için CPU yoğun yüklerden kaçınmaya dikkat etmeniz gerektiğinden, çok iş parçacıklı ve kilitli bir yaklaşımla birçok özelliği paylaşır. Avantaj, bağlam değiştirme ile ortaya çıkan ek yükün esasen ortadan kaldırılması ve sadece bir bağlam mesajının iletilmesinin bir sorun haline gelmesidir.

Birçok ağ protokolü için çalışmayabilir, ancak HTTP'lerin durumsuz yapısı özellikle engellemeyen mimariler için iyi çalışır. Bir ters proxy ve birden çok engellenmeyen HTTP sunucusu birleşimini kullanarak, ağır yük yaşayan düğümleri tanımlamak ve yönlendirmek mümkündür.

Yalnızca bir düğümü olan bir sunucuda bile, verimi en üst düzeye çıkarmak için kurulumun işlemci çekirdeği başına bir sunucu içermesi çok yaygındır.

Her ikisi de:

'İdeal' kullanım durumu her ikisinin bir kombinasyonu olacaktır. Ön taraftaki üstteki yönlendirme isteklerine adanmış bir ters proxy, ardından engelleme ve engellemeyen sunucuların bir karışımı. Statik içerik sunma, önbellek içeriği, html içeriği gibi IO görevleri için engellemesiz. Görüntü / video kodlama, içerik akışı, sayı kırma, veritabanı yazma vb. Gibi CPU-ağır görevler için engelleme.

Senin durumunda:

Yalnızca başlıkları kontrol ediyorsanız, ancak istekleri gerçekten işlemiyorsanız, temelde açıkladığınız şey ters bir proxy'dir. Böyle bir durumda kesinlikle asenkron bir yaklaşımla giderdim.

Nginx yerleşik ters proxy için belgelere göz atmanızı öneririm .

kenara:

Yazmayı sağladığınız bağlantıdan okudum ve asenkronun özel uygulamaları için kötü bir seçim olduğu mantıklı. Sorun tek bir açıklamada özetlenebilir.

İstemciler arasında geçiş yaparken, değerleri / durumu kaydetme ve geri yükleme kodunun zor olduğunu bulduk

Devlet dolu bir platform inşa ediyorlardı. Böyle bir durumda, zaman uyumsuz yaklaşım, bağlam her değiştiğinde (yani bir olay tetiklendiğinde) durumu sürekli olarak kaydetmeniz / yüklemeniz gerektiği anlamına gelir. Ayrıca, SMTP tarafında çok fazla CPU yoğunluklu iş yapıyorlar.

Görünüşe göre oldukça zayıf bir async kavrayışına sahipler ve sonuç olarak çok sayıda kötü varsayım yapmışlar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.