HTML WebSockets her istemci için açık bir bağlantı sağlıyor mu? Bu ölçek mi?


160

Herkes HTML WebSockets ölçeklenebilirliği hakkında herhangi bir bilgi olup olmadığını merak ediyorum. Okuduğum her şey için, her istemcinin sunucuyla açık bir iletişim hattı sürdüreceği anlaşılıyor. Sadece bunun nasıl ölçeklendiğini ve bir sunucunun kaç tane açık WebSocket bağlantısını işleyebileceğini merak ediyorum. Belki de bu bağlantıları açık bırakmak gerçekte bir sorun değildir, ama sanki öyle.


1
HTML WebSocket diye bir şey yoktur. HTTP WebSocket demek istediniz.
Lorne Marquis

Yanıtlar:


209

Çoğu durumda WebSockets muhtemelen AJAX / HTML isteklerinden daha iyi ölçeklenir. Ancak, bu WebSockets'in AJAX / HTML'nin tüm kullanımlarının yerini aldığı anlamına gelmez.

Her bir TCP bağlantısı, sunucu kaynakları açısından çok az tüketir. Genellikle bağlantı kurmak pahalı olabilir, ancak boşta bir bağlantıyı korumak neredeyse ücretsizdir. Genellikle karşılaşılan ilk sınırlama, aynı anda açılabilen maksimum dosya tanımlayıcı sayısıdır (soketler dosya tanımlayıcılarını tüketir). Bu genellikle varsayılan olarak 1024 olur ancak kolayca daha yüksek yapılandırılabilir.

Hiç on binlerce AJAX istemcisini desteklemek için bir web sunucusu yapılandırmayı denediniz mi? Bu istemcileri WebSockets istemcileri olarak değiştirin ve bu mümkün olabilir.

HTTP bağlantıları, açık dosyalar oluşturmasalar veya bağlantı noktası numaralarını uzun süre kullanmasalar da, hemen hemen her şekilde daha pahalıdır:

  • Her HTTP bağlantısı çoğu zaman kullanılmayan çok fazla bagaj taşır: çerezler, içerik türü, conetent uzunluğu, kullanıcı aracısı, sunucu kimliği, tarih, son değiştirilme, vs. Bir WebSockets bağlantısı kurulduktan sonra, yalnızca uygulamanın gerektirdiği verilerin ileri geri gönderilmesi gerekir.

  • Genellikle, HTTP sunucuları disk ve CPU zamanını alan her HTTP isteğinin başlangıcını ve tamamlanmasını günlüğe kaydedecek şekilde yapılandırılır. WebSockets verilerinin başlangıcını ve tamamlanmasını günlüğe kaydetmek standart hale gelecektir, ancak dubleks aktarımı yapan WebSockets bağlantısı ek günlük kaydı yükü olmayacaktır (bunu yapmak için tasarlanmışsa uygulama / hizmet hariç).

  • Genellikle, AJAX kullanan etkileşimli uygulamalar sürekli olarak yoklar veya bir tür uzun yoklama mekanizması kullanır. WebSockets, sunucunun ve istemcinin mevcut bağlantı üzerinden rapor edecek bir şeyleri olduğunda birbirlerine bildirdiği daha olaylı bir model yapmanın çok daha temiz (ve daha düşük kaynak) bir yoludur.

  • Üretimdeki popüler web sunucularının çoğunda HTTP isteklerini işlemek için bir işlem havuzu (veya iş parçacığı) vardır. Basınç arttıkça, her işlem / iş parçacığı bir seferde bir HTTP isteğini işlediğinden havuzun boyutu artacaktır. Her ek işlem / iş parçacığı daha fazla bellek kullanır ve yeni işlemler / iş parçacıkları oluşturmak, yeni soket bağlantıları oluşturmaktan (bu işlem / iş parçacıklarının hala yapmak zorunda olduğu) biraz daha pahalıdır. Popüler WebSockets sunucu çerçevelerinin çoğu, daha iyi ölçeklendirme ve performans gösterme olayı rotasına gidiyor.

WebSockets'in birincil avantajı, etkileşimli web uygulamaları için düşük gecikmeli bağlantılar olacaktır. HTTP AJAX / uzun anketten daha iyi ölçeklenir ve daha az sunucu kaynağı tüketir (uygulamanın / sunucunun düzgün bir şekilde tasarlandığı varsayılarak), ancak IMO düşük gecikmesi WebSockets'in birincil avantajıdır çünkü mümkün olmayan yeni web uygulamaları sınıflarını etkinleştirir AJAX / uzun anketin mevcut ek yükü ve gecikmesi ile.

WebSockets standardı daha kesin hale geldiğinde ve daha geniş bir desteğe sahip olduğunda, sunucuyla sık iletişim kurması gereken çoğu yeni etkileşimli web uygulaması için kullanılması mantıklı olacaktır. Mevcut etkileşimli web uygulamaları için, mevcut AJAX / uzun anket modelinin ne kadar iyi çalıştığına bağlı olacaktır. Dönüştürme çabası önemsiz olacaktır, bu nedenle çoğu durumda maliyet faydaya değmez.

Güncelleme :

Yararlı bağlantı: Node.js kullanarak AWS'de 600k eşzamanlı websocket bağlantısı


4
Müthiş anser. Cevap vermek için zaman ayırdığınız için teşekkürler.
Ryan Montgomery

7
Yine de duvara çarptığınızda nasıl ölçekleneceğini bilmiyorum. WebSockets'in daha az kaynak tükettiği doğrudur (dikey olarak ölçeklenirler), ancak HTTP yatay olarak ölçeklemek için mükemmeldir. Sonsuza kadar ölçeklemek için teorik olarak sunucuları ekleyebilirim. Tek bir kutunun kapasitesini kullandığınızda her zaman nasıl ölçekleneceği konusunda kafam karıştı. Düşünceler?
Sean Clark Hess

6
@Sean. WebSockets yatay olarak ölçeklendirmede mutlaka daha kötü değildir. Sadece kolayca ölçeklenmesi gerekmeyen yeni uygulamalar açar. Örneğin, statik veri sunmak için, bir grup WebSocket sunucusu bir grup HTTP sunucusundan daha iyi (veya daha iyi) ölçeklendirilir. Düşük gecikmeli gerçek zamanlı bir oyunun aktarımından bağımsız olarak ölçeklendirilmesi zordur (ve HTTP kullanarak gerçekten mümkün değildir). Asıl soru, veri / uygulama ölçeklerinin ne kadar iyi olduğudur. Bu ölçekleniyorsa, HTTP ve WebSockets seçiminiz diğer faktörlere dayanmalıdır: gecikme, dağıtım seçenekleri, tarayıcı desteği, vb.
kanaka

2
Bir düzeltme - TCP bağlantısı, hedef ip ve hedef bağlantı noktasından oluşur. Bu, ± 64k bağlantı noktası sınırının SADECE tek bir istemci için olduğu anlamına gelir. Teorik olarak, sunucu SADECE donanımı ile sınırlı sayıda açık bağlantıya sahip olabilir.
Rizon

@Rizon, bu doğru. Cevabı güncelledim ve açık bağlantı noktası sınırlamasını değiştirdim ve bunun yerine insanların sık sık ilk karşılaştıkları dosya tanımlayıcı sınırlamasından bahsettim.
kanaka

36

Sadece bir açıklama: Bir sunucunun destekleyebileceği istemci bağlantılarının sayısının bu senaryoda bağlantı noktaları ile bir ilgisi yoktur, çünkü sunucu [tipik olarak] yalnızca tek bir bağlantı noktasında WS / WSS bağlantılarını dinler. Diğer yorumculardan bahsetmek istediklerinin dosya tanımlayıcılar olduğunu düşünüyorum. Maksimum dosya tanımlayıcı sayısını oldukça fazla ayarlayabilirsiniz, ancak daha sonra her bir açık TCP / IP soketi için soket arabellek boyutlarına dikkat etmeniz gerekir. İşte bazı ek bilgiler: /server/48717/practical-maximum-open-file-descriptors-ulimit-n-for-a-high-volume-system

WS'ye karşı HTTP üzerinden gecikme süresine gelince, ilk WS el sıkışmasının ötesinde HTTP başlıklarının ayrıştırılması artık doğru değildir. Ayrıca, giderek daha fazla paket başarıyla gönderildikçe, TCP tıkanıklığı penceresi genişleyerek RTT'yi etkili bir şekilde azaltır.


AFAIR bir gelen bağlantı noktası vardır, ancak her bağlantı için her zaman bir giden bağlantı noktası açılır. Bu, C10k sorununun sadece bir kısmıdır .
Arnaud Bouchez

14

Herhangi bir modern tek sunucu aynı anda binlerce istemciye sunucu gönderebilir . HTTP sunucu yazılımı sadece Olay Odaklı (IOCP) odaklı olmalıdır (artık eski Apache'de bir bağlantı = bir iş parçacığı / işlem denkleminde değiliz). Windows (http.sys) yerleşik HTTP sunucusu bile IOCP yönelimli ve çok verimlidir (çekirdek modunda çalışıyor). Bu açıdan, WebSockets ve normal HTTP bağlantısı arasında ölçeklendirme konusunda çok fazla fark olmayacaktır. Bir TCP / IP bağlantısı küçük bir kaynak kullanır (bir iş parçacığından çok daha az) ve modern işletim sistemi birçok eşzamanlı bağlantıyı işlemek için optimize edilmiştir: WebSockets ve HTTP, bu TCP / IP özelliklerinden devralınan sadece OSI 7 uygulama katmanı protokolleridir.

Ancak, denemeden sonra WebSockets ile ilgili iki ana sorun gördüm:

  1. CDN'yi desteklemezler;
  2. Potansiyel güvenlik sorunları var.

Bu yüzden, herhangi bir proje için aşağıdakileri tavsiye ederim:

  • WebSockets uygulamasını yalnızca istemci bildirimleri için kullanın (uzun yoklama için bir geri dönüş mekanizmasıyla - çevresinde çok sayıda kitaplık vardır);
  • Önbellek için bir CDN veya proxy kullanarak diğer tüm veriler için RESTful / JSON kullanın.

Uygulamada, tam WebSockets uygulamaları iyi ölçeklenmez. WebSockets'i tasarlandıkları şey için kullanmanız yeterlidir: bildirimleri sunucudan istemciye aktarın.

WebSockets kullanımının olası sorunları hakkında:

1. Bir CDN kullanmayı düşünün

Bugün (neredeyse 4 yıl sonra), web ölçeklendirme yalnızca statik içerik (html, css, js) için değil, aynı zamanda (JSON) uygulama verileriniz için İçerik Dağıtım Ağı (CDN) kullanıcı arabirimlerini kullanmayı içerir .

Elbette, tüm verilerinizi CDN önbelleğinize koymazsınız, ancak pratikte birçok ortak içerik sık sık değişmez. REST kaynaklarınızın% 80'inin önbelleğe alınabileceğinden şüpheleniyorum ... Bir dakika (veya 30 saniye) CDN son kullanma zaman aşımı bile, merkezi sunucunuza yeni bir canlı vermek ve uygulama yanıt hızını çok artırmak için yeterli olabilir, çünkü CDN coğrafi olarak ayarlanabilir ...

Bildiğim kadarıyla CDN'de henüz WebSockets desteği yok ve bunun asla olmayacağından şüpheleniyorum. WebSockets durum bilgisi vardır, ancak HTTP durum bilgisi içermez, bu nedenle kolayca önbelleğe alınır. Aslında, WebSockets CDN dostu hale getirmek için, artık WebSockets olmayacak durumsuz bir RESTful yaklaşımına geçmeniz gerekebilir.

2. Güvenlik sorunları

WebSockets, özellikle DOS saldırıları hakkında potansiyel güvenlik sorunlarına sahiptir. Yeni güvenlik açıkları hakkında açıklama için bkz slaytları bu seti ve bu webkit bilet .

WebSockets, herhangi bir iş güvenliğinde günümüzde oldukça standart olan OSI 7 uygulama katmanı düzeyinde paket denetimi olasılığını önler. Aslında, WebSockets iletimi gizlendirir, bu nedenle güvenlik sızıntısının büyük bir ihlali olabilir.


2
@ArnaudBouchez - CDN'deki güzel sergi için +1. Hızlı takip sorusu - Etkinlik dağıtım ağlarının fizibilitesi hakkında ne düşünüyorsunuz? CDN'lerden sonra şekillendirilmiş ancak websockets veya henüz görünmeyen bir teknoloji üzerinden akış verileri vb. İletmeye yöneliktir.
quixver

8

Bunu şu şekilde düşünün: daha ucuz olan şey, açık bir bağlantı tutmak veya her istek için yeni bir bağlantı açmak (bunu müzakere yükü ile TCP olduğunu unutmayın).

Tabii ki uygulamaya bağlı, ancak uzun süreli gerçek zamanlı bağlantılar (örneğin bir AJAX sohbet) için bağlantıyı açık tutmak çok daha iyidir.

Maksimum bağlantı sayısı, soketler için maksimum boş bağlantı noktası sayısıyla sınırlanacaktır.


WebSocket kullanmadan bağlantıyı açık tutabilirsiniz (HTTP / 1.1'in canlı tutma seçeneği sayesinde). Burada ne demek istediğini anladığımdan emin değilim.
Arnaud Bouchez

1
+1. İnsanlar bir TCP bağlantısı kurmayı bir syn / ack / ack içerir ve TLS anahtar değişimi için daha fazla gidiş-dönüş gerektirir.
quixver

1
@ArnaudBouchez check en.wikipedia.org/wiki/HTTP_persistent_connection#HTTP_1.1 WebSockets istediğiniz kadar açıktır ve hacklenmez (uzun sorgulama ve diğer alternatifler gibi).
kaoD

-5

Hayır ölçeklenmez, ara geçiş anahtarlarına muazzam işler sağlar. Daha sonra sunucu tarafında sayfa hataları (tüm bu tanımlayıcıları tutmanız gerekir) yüksek değerlere ulaşır ve çalışma alanına bir kaynak getirme süresi artar. Bunlar çoğunlukla JAVA yazılı sunuculardır ve bu soket gazilyonlarını tutmak ve yok etmek / oluşturmak daha hızlı olabilir. Böyle bir sunucuyu bir makinede çalıştırdığınızda, başka hiçbir işlem artık taşınamaz.

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.