Apakah HTML WebSockets mempertahankan koneksi terbuka untuk setiap klien? Apakah skala ini?

159

Saya ingin tahu apakah ada yang punya informasi tentang skalabilitas HTML WebSockets. Untuk semua yang saya baca, tampaknya setiap klien akan mempertahankan jalur komunikasi terbuka dengan server. Saya hanya ingin tahu bagaimana skala dan berapa banyak koneksi WebSocket terbuka yang dapat ditangani oleh server. Mungkin membiarkan koneksi-koneksi itu terbuka bukanlah masalah pada kenyataannya, tetapi rasanya seperti itu.

Ryan Montgomery
sumber
1
Tidak ada yang namanya HTML WebSocket. Maksud Anda HTTP WebSocket.
Marquis of Lorne

Jawaban:

209

Dalam banyak hal, WebSockets mungkin akan berskala lebih baik daripada permintaan AJAX / HTML. Namun, itu tidak berarti WebSockets adalah pengganti untuk semua penggunaan AJAX / HTML.

Setiap koneksi TCP dengan sendirinya mengkonsumsi sangat sedikit sumber daya server. Seringkali pengaturan koneksi bisa mahal tetapi mempertahankan koneksi idle itu hampir gratis. Keterbatasan pertama yang biasanya ditemui adalah jumlah maksimum file deskriptor (soket mengkonsumsi file deskriptor) yang dapat dibuka secara bersamaan. Ini sering default ke 1024 tetapi dapat dengan mudah dikonfigurasi lebih tinggi.

Pernah mencoba mengkonfigurasi server web untuk mendukung puluhan ribu klien AJAX simultan? Ubah klien tersebut menjadi klien WebSockets dan mungkin saja layak.

Koneksi HTTP, meskipun tidak membuat file terbuka atau menggunakan nomor port untuk waktu yang lama, lebih mahal dalam hampir semua hal lain:

  • Setiap koneksi HTTP membawa banyak bagasi yang tidak sering digunakan: cookie, tipe konten, panjang conetent, agen-pengguna, id server, tanggal, terakhir diubah, dll. Setelah koneksi WebSockets dibuat, hanya data yang dibutuhkan oleh aplikasi perlu dikirim bolak-balik.

  • Biasanya, server HTTP dikonfigurasikan untuk mencatat awal dan penyelesaian setiap permintaan HTTP yang menghabiskan waktu disk dan CPU. Ini akan menjadi standar untuk mencatat awal dan penyelesaian data WebSockets, tetapi sementara koneksi WebSockets melakukan transfer duplex tidak akan ada tambahan overhead logging (kecuali oleh aplikasi / layanan jika itu dirancang untuk melakukannya).

  • Biasanya, aplikasi interaktif yang menggunakan AJAX baik secara terus-menerus polling atau menggunakan semacam mekanisme polling panjang. WebSockets adalah cara yang jauh lebih bersih (dan sumber daya lebih rendah) untuk melakukan model lebih banyak acara di mana server dan klien saling memberitahukan ketika mereka memiliki sesuatu untuk dilaporkan melalui koneksi yang ada.

  • Sebagian besar server web populer dalam produksi memiliki kumpulan proses (atau utas) untuk menangani permintaan HTTP. Ketika tekanan meningkat, ukuran pool akan meningkat karena setiap proses / utas menangani satu permintaan HTTP pada suatu waktu. Setiap proses / utas tambahan menggunakan lebih banyak memori dan membuat proses / utas baru sedikit lebih mahal daripada membuat koneksi soket baru (yang masih harus dilakukan oleh proses / utas tersebut). Sebagian besar kerangka kerja server WebSockets populer akan rute event'd yang cenderung untuk skala dan berkinerja lebih baik.

Manfaat utama WebSockets adalah koneksi latensi yang lebih rendah untuk aplikasi web interaktif. Ini akan skala lebih baik dan mengkonsumsi sumber daya server lebih sedikit daripada HTTP AJAX / jajak pendapat panjang (dengan asumsi aplikasi / server dirancang dengan benar), tetapi latensi rendah IMO adalah manfaat utama dari WebSockets karena akan memungkinkan kelas baru aplikasi web yang tidak mungkin dengan overhead saat ini dan latensi AJAX / jajak pendapat panjang.

Setelah standar WebSockets menjadi lebih final dan memiliki dukungan yang lebih luas, akan masuk akal untuk menggunakannya untuk sebagian besar aplikasi web interaktif baru yang perlu sering berkomunikasi dengan server. Untuk aplikasi web interaktif yang ada, itu akan sangat tergantung pada seberapa baik model AJAX / jajak pendapat saat ini bekerja. Upaya konversi akan menjadi non-sepele sehingga dalam banyak kasus biayanya tidak sebanding dengan manfaatnya.

Perbarui :

Tautan yang berguna: koneksi websocket 600k bersamaan di AWS menggunakan Node.js

kanaka
sumber
4
Anser yang luar biasa. Terima kasih telah meluangkan waktu untuk merespons.
Ryan Montgomery
7
Saya masih tidak tahu bagaimana skala setelah Anda menabrak dinding. Memang benar bahwa WebSockets mengkonsumsi lebih sedikit sumber daya (skala mereka secara vertikal), tetapi HTTP bagus untuk penskalaan horizontal. Secara teoritis saya dapat menambahkan server ke skala tanpa batas. Saya selalu bingung tentang bagaimana skala setelah Anda menggunakan kapasitas satu kotak. Pikiran?
Sean Clark Hess
6
@Sean. WebSockets tidak selalu lebih buruk dalam skala secara horizontal. Itu hanya membuka aplikasi baru yang tidak perlu skala dengan mudah. Misalnya, untuk menyajikan data statis, sekelompok server WebSocket akan menskala dengan baik (atau lebih baik) daripada sekelompok server HTTP. Gim real-time dengan latensi rendah sulit untuk diukur terlepas dari transpornya (dan itu benar-benar tidak layak menggunakan HTTP). Pertanyaan sebenarnya adalah seberapa baik skala data / aplikasi Anda. Jika itu berskala, maka pilihan Anda HTTP vs WebSockets harus didasarkan pada faktor-faktor lain: latensi, opsi penempatan, dukungan browser, dll.
kanaka
2
Satu koreksi - koneksi TCP terdiri dari ip tujuan & port tujuan. Itu berarti bahwa batas port ± 64k sebenarnya HANYA untuk satu klien. Secara teoritis, server dapat memiliki sejumlah koneksi terbuka, HANYA dibatasi oleh perangkat kerasnya.
Rizon
@ Rizon, itu benar. Saya telah memperbarui jawabannya dan mengubah batasan port terbuka dan alih-alih menyebutkan batasan deskriptor file yang merupakan salah satu yang sering ditemui orang terlebih dahulu.
kanaka
36

Hanya klarifikasi: jumlah koneksi klien yang dapat didukung server tidak ada hubungannya dengan port dalam skenario ini, karena server [biasanya] hanya mendengarkan koneksi WS / WSS pada satu port tunggal. Saya pikir apa yang dimaksud oleh komentator lain untuk merujuk adalah deskriptor file. Anda dapat mengatur jumlah maksimum deskriptor file cukup tinggi, tetapi kemudian Anda harus berhati-hati untuk menambahkan ukuran buffer socket untuk setiap soket TCP / IP terbuka. Berikut ini beberapa info tambahan: /server/48717/practical-maximum-open-file-descriptors-ulimit-n-for-a-high-volume-system

Adapun latensi menurun melalui WS vs HTTP, itu benar karena tidak ada lagi penguraian header HTTP di luar jabat tangan WS awal. Plus, karena semakin banyak paket yang berhasil dikirim, jendela kongesti TCP melebar, secara efektif mengurangi RTT.

Michael
sumber
AFAIR ada satu port masuk, tetapi selalu satu port keluar dibuka untuk setiap koneksi. Ini dalam akta hanya satu bagian dari masalah C10k .
Arnaud Bouchez
14

Server tunggal modern mana pun dapat server ribuan klien sekaligus . Perangkat lunak server HTTP-nya hanya berorientasi pada Event-Driven (IOCP) (kami tidak berada di Apache satu koneksi lama = satu thread / persamaan proses lagi). Bahkan server HTTP yang dibangun di Windows (http.sys) berorientasi pada IOCP dan sangat efisien (berjalan dalam mode kernel). Dari sudut pandang ini, tidak akan ada banyak perbedaan dalam penskalaan antara WebSockets dan koneksi HTTP biasa. Satu koneksi TCP / IP menggunakan sedikit sumber daya (lebih sedikit daripada utas), dan OS modern dioptimalkan untuk menangani banyak koneksi bersamaan: WebSockets dan HTTP hanyalah protokol lapisan aplikasi OSI 7, yang diwarisi dari spesifikasi TCP / IP ini.

Namun, dari percobaan, saya telah melihat dua masalah utama dengan WebSockets:

  1. Mereka tidak mendukung CDN;
  2. Mereka memiliki masalah keamanan potensial.

Jadi saya akan merekomendasikan yang berikut ini, untuk proyek apa pun:

  • Gunakan WebSockets hanya untuk pemberitahuan klien (dengan mekanisme mundur untuk pemungutan suara panjang - ada banyak perpustakaan di sekitarnya);
  • Gunakan RESTful / JSON untuk semua data lainnya, menggunakan CDN atau proksi untuk cache.

Dalam praktiknya, aplikasi WebSockets lengkap tidak skala dengan baik. Cukup gunakan WebSockets untuk apa yang mereka dirancang untuk: mendorong pemberitahuan dari server ke klien.

Tentang potensi masalah menggunakan WebSockets:

1. Pertimbangkan untuk menggunakan CDN

Hari ini (hampir 4 tahun kemudian), penskalaan web melibatkan penggunaan ujung depan Jaringan Pengiriman Konten (CDN), tidak hanya untuk konten statis (html, css, js) tetapi juga data aplikasi Anda (JSON) .

Tentu saja, Anda tidak akan meletakkan semua data Anda di cache CDN Anda, tetapi dalam praktiknya, banyak konten umum tidak akan sering berubah. Saya menduga bahwa 80% dari sumber daya REST Anda mungkin di-cache ... Bahkan satu menit (atau 30 detik) batas waktu kedaluwarsa CDN mungkin cukup untuk membuat server pusat Anda memiliki live baru, dan banyak meningkatkan respons aplikasi, karena CDN dapat disetel secara geografis ...

Sepengetahuan saya, belum ada dukungan WebSockets di CDN, dan saya kira itu tidak akan pernah terjadi. WebSockets adalah statefull, sedangkan HTTP adalah stateless, jadi lebih mudah di-cache. Bahkan, untuk membuat WebSockets ramah-CDN, Anda mungkin perlu beralih ke pendekatan RESTful tanpa kewarganegaraan ... yang tidak akan menjadi WebSockets lagi.

2. Masalah keamanan

WebSockets memiliki masalah keamanan potensial, terutama tentang serangan DOS. Untuk ilustrasi tentang kerentanan keamanan baru, lihat kumpulan slide ini dan tiket webkit ini .

WebSockets menghindari kemungkinan inspeksi paket pada tingkat lapisan aplikasi OSI 7, yang menjadi standar saat ini, dalam keamanan bisnis apa pun. Bahkan, WebSockets membuat transmisi menjadi kabur, jadi mungkin merupakan pelanggaran utama kebocoran keamanan.

Arnaud Bouchez
sumber
2
@ArnaudBouchez - +1 untuk penjelasan bagus tentang CDN. Pertanyaan tindak lanjut cepat - apa pendapat Anda tentang kelayakan jaringan pengiriman acara? Berpola setelah CDN tetapi diarahkan untuk mengirimkan data streaming dll melalui websockets atau teknologi lainnya yang belum terlihat.
quixver
8

Pikirkan seperti ini: apa yang lebih murah, menjaga koneksi terbuka, atau membuka koneksi baru untuk setiap permintaan (dengan overhead negosiasi melakukannya, ingat itu TCP.)

Tentu saja itu tergantung pada aplikasi, tetapi untuk koneksi realtime jangka panjang (mis. Obrolan AJAX) itu jauh lebih baik untuk menjaga koneksi tetap terbuka.

Jumlah koneksi maksimal akan dibatasi oleh jumlah port bebas maksimum untuk soket.

kaoD
sumber
Anda dapat menjaga koneksi tetap terbuka tanpa menggunakan WebSocket (berkat opsi keep live dari HTTP / 1.1). Saya tidak yakin saya mengerti maksud Anda di sini.
Arnaud Bouchez
1
+1. Orang-orang cenderung lupa mengatur koneksi TCP yang melibatkan syn / ack / ack dan TLS membutuhkan lebih banyak perjalanan bolak-balik untuk pertukaran kunci.
quixver
1
@ArnaudBouchez periksa en.wikipedia.org/wiki/HTTP_persistent_connection#HTTP_1.1 WebSockets terbuka selama yang Anda inginkan dan tidak diretas (seperti polling panjang dan alternatif lain).
kaoD
-5

Tidak itu tidak skala, memberikan pekerjaan luar biasa untuk switch rute menengah. Kemudian di sisi server kesalahan halaman (Anda harus menjaga semua deskriptor itu) mencapai nilai tinggi, dan waktu untuk membawa sumber daya ke area kerja meningkat. Ini adalah sebagian besar server yang ditulis JAWA dan mungkin lebih cepat untuk bertahan pada soket-soket itu kemudian untuk menghancurkan / membuat satu. Ketika Anda menjalankan server seperti itu pada mesin, proses lain tidak dapat bergerak lagi.

pengguna2195463
sumber