Bir web sunucusu kaç soket bağlantısını idare edebilir?


114

Diyelim ki paylaşılan, sanal veya adanmış barındırma alacak olsaydım, bir yerde bir sunucu / makine bir seferde yalnızca 64.000 TCP bağlantısını kaldırabilir, bu doğru mu? Bant genişliğinden bağımsız olarak herhangi bir barındırma türü kaç tanesini kaldırabilir? HTTP'nin TCP üzerinden çalıştığını varsayıyorum.

Bu, web sitesine yalnızca 64.000 kullanıcının bağlanabileceği anlamına mı gelir ve daha fazla hizmet vermek istersem bir web çiftliğine taşınmam gerekir mi?


2
Müdahale edenlerden özür dilerim, bu ipliği bir kasırga gibi delirdim. Benim beğenime göre çok fazla yanlış cevap vardı ve hala doğrudan cevap yok. Stackoverflow'u çok kullanıyorum ve birçok yüksek kaliteli yanıt buluyorum. Umarım başkaları bu konuyu bulabilir ve faydalı ve bilgiye dayalı bir cevap bulabilir.
Todd

Merhaba David, bu soruya doğru cevabı buldun mu?
Çanak

Tek sunucu IP'si üzerinden 64000 TCP bağlantısı. Sunucu ağınızı 64000'den fazlasını ölçeklendirecek ve destekleyecek şekilde yükseltebilirsiniz.
Airy

Yanıtlar:


109

Kısacası: Milyonlarca eşzamanlı etkin TCP bağlantısı ve uzantı HTTP isteklerini gerçekleştirebilmelisiniz. Bu size, doğru konfigürasyona sahip doğru platformdan bekleyebileceğiniz maksimum performansı söyler.

Bugün, ASP.NET ile IIS'nin 100 eşzamanlı bağlantı sırasını destekleyip desteklemeyeceğinden endişeleniyordum (güncellememe bakın, eski ASP.Net Mono sürümlerinde saniyede ~ 10.000 yanıt bekliyoruz). Bu soruyu / cevapları görünce kendime cevap vermekten kendimi alamadım, buradaki soruya verilen cevapların çoğu tamamen yanlış.

En iyi senaryo

Bu sorunun cevabı, olası aşağı akış olası sayısız değişken ve yapılandırmadan ayırmak için yalnızca en basit sunucu yapılandırmasıyla ilgilenmelidir.

Cevabım için şu senaryoyu düşünün:

  1. Canlı tutma paketleri haricinde, TCP oturumlarında trafik yok (aksi takdirde, açıkça karşılık gelen miktarda ağ bant genişliğine ve diğer bilgisayar kaynaklarına ihtiyacınız olacaktır)
  2. Bir havuzdan gelen istek başına bir donanım iş parçacığı yerine zaman uyumsuz soketler ve programlama kullanmak üzere tasarlanmış yazılım. (ör. IIS, Node.js, Nginx ... web sunucusu [ancak Apache değil], eşzamansız tasarlanmış uygulama yazılımıyla)
  3. İyi performans / dolar CPU / Ram. Bugün keyfi olarak 8GB RAM ile i7 (4 çekirdekli) diyelim.
  4. Eşleşecek iyi bir güvenlik duvarı / yönlendirici.
  5. Sanal sınır / vali yok - yani. Linux somaxconn, IIS web.config ...
  6. Diğer daha yavaş donanıma bağımlılık yok - sabit diskten okuma yok, çünkü ağ GÇ'si değil, en düşük ortak payda ve darboğaz olacaktır.

Ayrıntılı Cevap

Eşzamanlı iş parçacığına bağlı tasarımlar, Eşzamansız GÇ uygulamalarına göre en kötü performans gösterme eğilimindedir.

WhatsApp, tek bir Unix aromalı işletim sistemi makinesinde İLE bir milyon trafik kazanıyor - https://blog.whatsapp.com/index.php/2012/01/1-million-is-so-2011/ .

Ve son olarak bu, http://highscalability.com/blog/2013/5/13/the-secret-to-10-million-concurrent-connections-the-kernel-i.html , birçok ayrıntıya giriyor 10 milyona bile nasıl ulaşılabileceğini keşfediyor. Sunucularda genellikle donanımsal TCP yük aktarım motorları vardır, ASIC'ler bu özel rol için genel amaçlı bir CPU'dan daha verimli tasarlanmıştır.

İyi yazılım tasarımı seçenekleri

Eşzamansız GÇ tasarımı, İşletim Sistemleri ve Programlama platformları arasında farklılık gösterecektir. Node.js, eşzamansız olarak tasarlanmıştır . En azından Promises kullanmalısınız ve ECMAScript 7 ortaya çıktığında, async/ await. C # /. Net zaten node.js gibi tam eşzamansız desteğe sahiptir. İşletim sistemi ve platform ne olursa olsun, zaman uyumsuzluğun çok iyi performans göstermesi beklenmelidir. Ve hangi dili seçerseniz seçin, "eşzamansız" anahtar kelimesini arayın, çoğu modern dil, bir tür eklenti olsa bile bir miktar desteğe sahip olacaktır.

WebFarm'a mı?

Özel durumunuz için sınır ne olursa olsun, evet bir web çiftliği ölçeklendirmeye yönelik iyi bir çözümdür. Bunu başarmak için birçok mimari var. Biri bir yük dengeleyici kullanıyor (barındırma sağlayıcıları bunları sunabilir, ancak bunların bile bant genişliği tavanıyla birlikte bir sınırı vardır), ancak bu seçeneği tercih etmiyorum. Uzun süreli bağlantılara sahip Tek Sayfalı Uygulamalar için, bunun yerine istemci uygulamasının başlangıçta rastgele seçeceği ve uygulamanın ömrü boyunca yeniden kullanacağı açık bir sunucu listesine sahip olmayı tercih ediyorum. Bu, tek hata noktasını (yük dengeleyici) ortadan kaldırır ve birden çok veri merkezi aracılığıyla ölçeklendirmeye ve dolayısıyla çok daha fazla bant genişliğine olanak tanır.

Bir efsaneyi yıkmak - 64K bağlantı noktası

"64.000" ile ilgili soru bileşenini ele alacak olursak, bu bir yanılgıdır. Bir sunucu, 65535'den fazla istemciye bağlanabilir. Bkz. Https://networkengineering.stackexchange.com/questions/48283/is-a-tcp-server-limited-to-65535-clients/48284

Bu arada, Windows üzerindeki Http.sys, birden çok uygulamanın HTTP URL şeması altında aynı sunucu bağlantı noktasını paylaşmasına izin verir. Her biri ayrı bir etki alanı bağlaması kaydeder, ancak nihayetinde istekleri doğru uygulamalara proxy yapan tek bir sunucu uygulaması vardır.

Güncelleme 2019-05-30

İşte en hızlı HTTP kitaplıklarının güncel bir karşılaştırması - https://www.techempower.com/benchmarks/#section=data-r16&hw=ph&test=plaintext

  • Test tarihi: 2018-06-06
  • Kullanılan donanım: Dell R440 Xeon Gold + 10 GbE
  • Liderin saniyede ~ 7 milyon düz metin yanıtı var (yanıtlar bağlantı değil)
  • Golang için ikinci bir Fasthttp, 1.5 milyon eşzamanlı bağlantının reklamını yapar - bkz. Https://github.com/valyala/fasthttp
  • Önde gelen diller Rust, Go, C ++, Java, C ve hatta C # rütbesi 11'dir (saniyede 6,9 ​​milyon). Scala ve Clojure daha aşağı sıralanır. Python saniyede 2,7 milyon ile 29. sırada yer alıyor.
  • Listenin en altında laravel ve cakephp, raylar, aspnet-mono-ngx, symfony, zend var. Hepsi saniyede 10.000'in altında. Unutmayın, bu çerçevelerin çoğu dinamik sayfalar için oluşturulmuştur ve oldukça eskidir, listede daha üst sıralarda yer alan daha yeni varyantlar olabilir.
  • Bunun Websocket uzmanlığı için değil, HTTP düz metin olduğunu unutmayın: Buraya gelen birçok kişi muhtemelen websocket için eşzamanlı bağlantılarla ilgilenecektir.

2
Bunu nasıl yaptıkları hakkında konuşan insanlara bağlantılar eklediğiniz için teşekkür ederiz.
Rick Smith

Ya istemcinin bağlı olduğu tek sunucu çökerse? Ya tüm SPA'nız rastgele bir şekilde bir sunucuya bağlanırsa ve onu aşırı yüklerse?
Yük dengeleyicileri

3
İstemciler rastgele bir sunucu seçer. Birine rastgele bağlanma şansı neredeyse imkansızdır. Her ne kadar biri istemci sayısını takip edebilir ve sunucu çok kalabalıksa istemciden başka bir sunucuya geçmesini isteyebilir.
Todd

1
Ynt: 64K sınırlaması - söyledikleriniz doğrudur, ancak bir sunucu uygulamasının bazı arka uç hizmet (ler) i aracılığıyla istekleri proxy yapması oldukça yaygındır, bu durumda "sunucu" artık bir "istemci" olur ve muhtemelen geçici bağlantı noktası tükenmesi konusunda endişelenmek için (örneğin: nginx.com/blog/overcoming-ephemeral-port-exhaustion-nginx-plus ). Eminim bunu biliyorsunuzdur, ancak başkaları için
bundan bahsediyorsunuz

@jwd iyi bir nokta, bir web uygulamasında nginx için bağlamsal, ancak temel bir web sitesi için böyle bir proxy oluşturmanın gerçekleşmesi gerekmez. Aynı şey, bir web uygulamasıyla TCP aracılığıyla bir veri tabanına bağlanmak için de söylenebilir. Teorik olarak, bu 127. *. *. * Aralığındaki tüm adresler kullanılarak çözülür, ancak pratikte bunun kullanılabilir bir seçenek olup olmadığını bilmiyorum.
Todd

54

Bu soru oldukça zor bir sorudur. Bir makinenin sahip olabileceği aktif bağlantıların sayısı konusunda gerçek bir yazılım sınırlaması yoktur, ancak bazı işletim sistemleri diğerlerinden daha sınırlıdır. Sorun, kaynaklardan biri haline gelir. Örneğin, tek bir makinenin 64.000 eşzamanlı bağlantıyı desteklemek istediğini varsayalım. Sunucu bağlantı başına 1MB RAM kullanıyorsa, 64GB RAM gerekir. Her istemcinin bir dosyayı okuması gerekiyorsa, disk veya depolama dizisi erişim yükü, bu aygıtların kaldırabileceğinden çok daha büyük hale gelir. Bir sunucunun bağlantı başına bir işlemi çatallaması gerekiyorsa, işletim sistemi zamanının çoğunu bağlam değiştirme veya CPU zamanı için işlemleri aç bırakarak harcayacaktır.

C10K problemi sayfası bu konuda çok iyi bir tartışma vardır.


3
Biraz karışık bir cevap. OP, en kötü durumu bulmak ve ardından çözüme sahip olabilecek bir makaleye atıfta bulunmak yerine, en iyi durum senaryosuna atıfta bulunuyor ve nasıl faydalı olacağını da içeriyor gibi görünüyor. Disk darboğazını not etmek faydalıdır. Eşzamansız G / Ç kullanarak çok yüksek miktarda eşzamanlı istemciye ulaşılabilir.
Todd

Bağlantı noktası boyutunun kendisi 16 bit olduğu için gerçek bir yazılım sınırlaması olmadığını nasıl söyleyebilirsin ki bu da maksimumun herhangi bir anda maksimum 65.5K'da kullanılmamasını sağlar. Cevabınızın yanlış olduğuna inanıyorum.
आनंद

Makineniz 1'den fazla IP'ye sahip olabilir, bu nedenle 2 ^ 16'dan fazla bağlantı noktası kullanılabilir.
Arman Ordookhani

8

Konuşmaya iki sentimi eklemek için, bir işlem aynı anda bu sayıya eşit bir dizi soket açabilir (Linux tipi sistemlerde) / proc / sys / net / core / somaxconn

cat / proc / sys / net / core / somaxconn

Bu numara anında değiştirilebilir (tabii ki sadece kök kullanıcı tarafından)

echo 1024> / proc / sys / net / core / somaxconn

Ancak tamamen sunucu sürecine, makinenin donanımına ve ağa, sistemi çökertmeden önce bağlanabilecek gerçek soket sayısına bağlıdır.


1
Muhtemelen Linux için doğru olsa da, bu bir olasılıklar kıyaslamasını değil, sanal bir sınırı ifade eder. Bu cevap benim zevkime göre biraz spesifiktir ve eşzamanlı bağlantıların sayısını veya göstergesini sağlamaz. Çabalarınıza rağmen, pek kullanışlı değil. Belki bir soruyu kendi kendinize yanıtlayabilirsiniz: "Linux'ta neden eşzamanlı X'den fazla TCP bağlantısından daha fazlasını
Todd,

2
Bildiğim kadarıyla bu yanlış . somaxconn, açık bir sokette sıraya alınmış maksimum bağlantı sayısıdır (yani bu, listen(int socket, int backlog)
biriktirme

8

Görünüşe göre etli bir sunucunuz varsa, cevap en az 12 milyon, sunucu yazılımınız bunun için optimize edilmiş, yeterli müşteriniz var. Bir istemciden bir sunucuya test ederseniz, istemcideki bağlantı noktası numaralarının sayısı, açık kaynak sınırlarından biri olacaktır (Her TCP bağlantısı, kaynak ve hedefteki IP ve bağlantı noktası numaralarının benzersiz birleşimi ile tanımlanır).

(Aksi takdirde önce bağlantı noktası numaralarında 64K sınırına ulaştığınız için birden fazla istemci çalıştırmanız gerekir)

Söz konusu olduğunda, bu, "teori ve pratik arasındaki farkın pratikte teoriden çok daha büyük olduğu" şeklindeki witticizmin klasik bir örneğidir - pratikte daha yüksek sayılara ulaşmak a döngüsü gibi görünür. özel yapılandırma / mimari / kod değişiklikleri önermek, b. bir sınıra ulaşana kadar test edin, c. Bitirdim mi Değilse o zaman d. sınırlayıcı faktörün ne olduğunu bulmak, e. a adımına geri dönün (durulayın ve tekrarlayın).

İşte Phoenix'i çalıştıran etli bir kutuya (128GB RAM ve 40 çekirdek) 2 milyon TCP bağlantısı olan bir örnek http://www.phoenixframework.org/blog/the-road-to-2-million-websocket-connections - sona erdi sadece istemci yükünü sağlamak için 50 veya daha fazla makul derecede önemli sunucuya ihtiyaç duyuyor (ilk küçük istemcileri erkenden maksimuma çıktı, örneğin "4 çekirdekli / 15 gb kutu @ 450k istemcilerimizi maksimize etti").

İşte bu sefer 10 milyonda gitmek için başka bir referans: http://goroutines.com/10m .

Bu, java tabanlı ve 12 milyon bağlantı gibi görünüyor: https://mrotaru.wordpress.com/2013/06/20/12-million-concurrent-connections-with-migratorydata-websocket-server/


Sorunun doğru anlaşılmasıyla harika yeni bağlantılar. Hit-barrier -> fix barrier için genel tavsiyeleri seviyorum. Herkesin kendine özgü farklı bir durumu vardır, ancak en azından burada ekonomik / pratik olarak neyin başarılabilir olduğuna dair bir göstergeye sahiptirler. Yakın zamanda bir müşteriye sunucu başına 100 milyon söz verilmemelidir.
Todd

5

HTTP'nin tipik olarak TCP bağlantılarını, sayfayı istemciye iletmek için gereken süreden daha uzun süre açık tutmadığını unutmayın; ve genellikle kullanıcının bir web sayfasını okuması, sayfayı indirmek için gerekenden çok daha fazla zaman alır ... kullanıcı sayfayı görüntülerken, sunucuya hiç yük eklemez.

Dolayısıyla, web sitenizi aynı anda görüntüleyebilecek kişi sayısı, aynı anda hizmet verebileceği TCP bağlantılarının sayısından çok daha fazladır.


12
Bu soruya hiç cevap vermiyor. Söylediklerinizin doğruluğuna bakılmaksızın, belirli bir zamanda hala birkaç eşzamanlı TCP bağlantısı olacaktır, maksimum nedir? Sorunun özü budur.
Todd

3
Katkıda bulunmaya değer bir şeyin varsa Todd, kesinlikle devam et ve bunu yap.
Jeremy Friesner

8
28 Mart'ta zaten bir Cevabım vardı, kaçırmış olmalısın. Uzun yoklama ve web soketi bağlantılarına sahip modern Tek Sayfa Uygulamaları dünyasında, HTTP her zaman kısa ömürlü değildir. Ancak kısa ömürlü olsa bile, yine de maksimum sayıda eşzamanlı bağlantı vardır. Soruyu açıklamaya çalışmak bir cevap değil IMO. Bu cevap soruya bir yorum olarak yerleştirilmesi daha iyi olur, kesinlikle faydalıdır, ancak soru "insanlar" değil "soket bağlantıları" ile ilgilidir. Oranla ilgili bir soru (kullanıcılar: aktif bağlantılar) istenirse ayrı bir soru olmalıdır.
Todd

1
HTTP'de Canlı Tutun TCP bağlantıları son milenyumdan beri etrafta dolaşıyor ve tarayıcılar tarafından talep ediliyor - bağlantının canlı kalmasına izin verip vermediği ve boşta kalma zaman aşımı süresinin ne olacağı sunucuya bağlıdır. Keep Alive'e izin vermek, bir grup isteğin (örneğin bir html sayfası ve ilişkili varlıkları) gecikmesini azaltır, ancak sunucuda kaynak kullanımını artırır.
iheggie

1

IPv4 protokolü durumunda, tek bir IP adresine sahip olan ve bir bağlantı noktasında dinleyen sunucu, yalnızca 2 ^ 32 IP adresi x 2 ^ 16 bağlantı noktası, yani 2 ^ 48 benzersiz soketi işleyebilir. Fiziksel bir makine olarak bir sunucudan bahsediyorsanız ve tüm 2 ^ 16 bağlantı noktasını kullanabiliyorsanız, bir IP adresi için maksimum 2 ^ 48 x 2 ^ 16 = 2 ^ 64 benzersiz TCP / IP soketi olabilir. Lütfen bazı bağlantı noktalarının işletim sistemi için ayrıldığını, bu nedenle bu sayının daha düşük olacağını unutmayın. Sonuç olarak:

1 IP ve 1 bağlantı noktası -> 2 ^ 48 soket

1 IP ve tüm bağlantı noktaları -> 2 ^ 64 soket

evrendeki tüm benzersiz IPv4 soketleri -> 2 ^ 96 soket


0

Burada iki farklı tartışma vardır: Birincisi, sunucunuza kaç kişinin bağlanabileceğidir. Bu soru başkaları tarafından yeterince cevaplandı, bu yüzden buna girmeyeceğim.

Diğer, sunucunuzun dinleyebileceği kaç bağlantı noktasıdır? 64K numarasının nereden geldiğine inanıyorum. Aslında, TCP protokolü bir bağlantı noktası için 65536'ya (64K'dan biraz daha fazla) çeviren 16 bitlik bir tanımlayıcı kullanır. Bu, sunucuda IP Adresi başına o kadar çok farklı "dinleyiciye" sahip olabileceğiniz anlamına gelir.


Senin yararın için, yanlış anlamanı ele alan cevabıma fazladan bir bölüm ekledim. Ayrıca bu soru, bu soru bağlamında önemli bir ayrım olan "insanlar" ile değil "soket bağlantıları" ile ilgilidir.
Todd

Tek bir sunucu makinesi ve tek bir yönlendiriciden bahsediyorsak, bu cevabın doğru olduğunu düşünüyorum. Ancak @Todd, kullanıcının bir yük dengeleyici aracılığıyla rastgele herhangi birine bağlanabileceği bir sunucu makineleri çiftliğini ele alıyor.
Amr

@amr bu yanlış. Cevabım tek bir makineyle ilgili. "Webfarm" mı? bölümü kontrast ve ötesine geçme tavsiyeleri için oradadır ve iyi mimaride yük dengeleyicilerin gerekli olmadığı sonucuna varır. Cevabımı henüz tam olarak okumadınız.
Todd

0

Bir web sunucusunun işleyebileceği eşzamanlı soket bağlantılarının sayısının büyük ölçüde her bir bağlantının tükettiği kaynak miktarına ve diğer web sunucusu kaynak sınırlayıcı yapılandırmasını engelleyen sunucuda bulunan toplam kaynak miktarına bağlı olduğunu düşünüyorum.

Örneğin, her soket bağlantısı 1 MB sunucu kaynağı tüketiyorsa ve sunucuda 16 GB kullanılabilir RAM varsa (teorik olarak) bu, yalnızca (16 GB / 1 MB) eşzamanlı bağlantıları idare edebileceği anlamına gelir. Sanırım bu kadar basit ... GERÇEKTEN!

Dolayısıyla, web sunucusunun bağlantıları nasıl ele aldığına bakılmaksızın, her bağlantı sonuçta bir miktar kaynak tüketecektir.

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.