HTML WebSocket mantiene una connessione aperta per ciascun client? Questa scala?


159

Sono curioso di sapere se qualcuno ha qualche informazione sulla scalabilità di HTML WebSocket. Per tutto quello che ho letto sembra che ogni client manterrà una linea aperta di comunicazione con il server. Mi chiedo solo come si ridimensiona e quante connessioni WebSocket aperte può gestire un server. Forse lasciare aperte quelle connessioni non è un problema nella realtà, ma sembra che lo sia.


1
Non esiste un WebSocket HTML. Intendi HTTP WebSocket.
Marchese di Lorne,

Risposte:


209

In molti modi WebSocket probabilmente ridimensionerà meglio delle richieste AJAX / HTML. Tuttavia, ciò non significa che WebSocket sia un sostituto di tutti gli usi di AJAX / HTML.

Ogni connessione TCP in sé consuma pochissimo in termini di risorse del server. Spesso l'impostazione della connessione può essere costosa, ma mantenere una connessione inattiva è quasi gratuita. La prima limitazione che si incontra di solito è il numero massimo di descrittori di file (i socket utilizzano descrittori di file) che possono essere aperti contemporaneamente. Questa impostazione predefinita è 1024, ma può essere facilmente configurata più in alto.

Hai mai provato a configurare un server web per supportare decine di migliaia di client AJAX simultanei? Cambia quei client in client WebSocket e potrebbe essere fattibile.

Le connessioni HTTP, sebbene non creino file aperti o consumino numeri di porta per un lungo periodo, sono più costose praticamente in tutti gli altri modi:

  • Ogni connessione HTTP trasporta molti bagagli che non vengono utilizzati per la maggior parte del tempo: cookie, tipo di contenuto, lunghezza del conetent, user-agent, ID server, data, ultima modifica, ecc. Una volta stabilita una connessione WebSocket, solo il i dati richiesti dall'applicazione devono essere inviati avanti e indietro.

  • In genere, i server HTTP sono configurati per registrare l'avvio e il completamento di ogni richiesta HTTP che richiede tempo su disco e CPU. Diventerà standard registrare l'inizio e il completamento dei dati di WebSocket, ma mentre la connessione WebSocket esegue il trasferimento duplex non ci sarà alcun sovraccarico di registrazione aggiuntivo (tranne dall'applicazione / servizio se è progettato per farlo).

  • In genere, le applicazioni interattive che utilizzano AJAX eseguono continuamente il polling o utilizzano una sorta di meccanismo di polling lungo. WebSocket è un modo molto più pulito (e con una risorsa inferiore) di creare un modello più dettagliato in cui il server e il client si notificano reciprocamente quando hanno qualcosa da segnalare sulla connessione esistente.

  • La maggior parte dei server Web più diffusi in produzione ha un pool di processi (o thread) per la gestione delle richieste HTTP. All'aumentare della pressione, le dimensioni del pool verranno aumentate poiché ogni processo / thread gestisce una richiesta HTTP alla volta. Ogni ulteriore processo / thread utilizza più memoria e la creazione di nuovi processi / thread è un po 'più costosa rispetto alla creazione di nuove connessioni socket (cosa che tali processi / thread devono ancora fare). La maggior parte dei popolari framework di server WebSocket sta seguendo la rotta dell'evento che tende a ridimensionarsi e ad avere prestazioni migliori.

Il vantaggio principale di WebSocket saranno le connessioni a latenza inferiore per le applicazioni Web interattive. Scalerà meglio e consumerà meno risorse del server rispetto a HTTP AJAX / sondaggio lungo (supponendo che l'applicazione / server sia progettata correttamente), ma una latenza inferiore dell'IMO è il vantaggio principale di WebSocket perché consentirà nuove classi di applicazioni Web che non sono possibili con l'attuale sovraccarico e latenza di AJAX / sondaggio lungo.

Una volta che lo standard WebSocket diventa più finalizzato e ha un supporto più ampio, avrà senso utilizzarlo per la maggior parte delle nuove applicazioni Web interattive che devono comunicare frequentemente con il server. Per le applicazioni web interattive esistenti dipenderà davvero dal funzionamento dell'attuale modello AJAX / sondaggio lungo. Lo sforzo di conversione sarà non banale, quindi in molti casi il costo non ne trarrà vantaggio.

Aggiornamento :

Link utile: 600k connessioni websocket simultanee su AWS usando Node.js


4
Risposta eccezionale. Grazie per aver dedicato del tempo per rispondere.
Ryan Montgomery,

7
Tuttavia, non so ancora come scalare una volta colpito il muro. È vero che i WebSocket consumano meno risorse (si adattano in scala verticale), ma HTTP è ottimo per il ridimensionamento in orizzontale. Posso teoricamente aggiungere server per scalare all'infinito. Sono sempre stato confuso su come ridimensionare una volta esaurita la capacità di una singola scatola. Pensieri?
Sean Clark Hess il

6
@Sean. WebSocket non è necessariamente peggiore nel ridimensionamento orizzontale. Apre solo nuove applicazioni che non si adattano necessariamente facilmente. Ad esempio, per servire dati statici, un gruppo di server WebSocket si ridimensionerebbe altrettanto (o meglio) di un gruppo di server HTTP. Un gioco in tempo reale a bassa latenza è difficile da ridimensionare indipendentemente dal trasporto (e non è proprio possibile con HTTP). La vera domanda è quanto bene i dati / l'applicazione vengono ridimensionati. Se ciò si ridimensiona, la tua scelta di HTTP vs WebSocket dovrebbe essere basata su altri fattori: latenza, opzioni di distribuzione, supporto del browser, ecc.
kanaka,

2
Una correzione: una connessione TCP è composta da ip di destinazione e porta di destinazione. Ciò significa che il limite di porte ± 64k è effettivamente SOLO per un singolo client. Teoricamente, il server può avere un numero qualsiasi di connessioni aperte, limitato SOLO dal suo hardware.
Rizon,

@Rizon, è vero. Ho aggiornato la risposta e modificato la limitazione della porta aperta e ho invece menzionato la limitazione del descrittore di file che è quella che le persone incontrano spesso per prima.
Kanaka,

36

Solo un chiarimento: il numero di connessioni client che un server può supportare non ha nulla a che fare con le porte in questo scenario, poiché il server [in genere] sta solo ascoltando le connessioni WS / WSS su una singola porta. Penso che ciò a cui gli altri commentatori intendevano fare riferimento fossero descrittori di file. È possibile impostare un numero massimo di descrittori di file piuttosto elevato, ma è necessario fare attenzione alle dimensioni del buffer socket che si sommano per ciascun socket TCP / IP aperto. Ecco alcune informazioni aggiuntive: /server/48717/practical-ma maximum - open-file - descriptors - ulimit-n - for-a - high - volume - system

Per quanto riguarda la latenza ridotta tramite WS vs. HTTP, è vero poiché non esiste più l'analisi delle intestazioni HTTP oltre l'handshake iniziale WS. Inoltre, poiché sempre più pacchetti vengono inviati correttamente, la finestra di congestione TCP si allarga, riducendo efficacemente l'RTT.


AFAIR c'è una porta in entrata, ma sempre una porta in uscita aperta per ogni connessione. Questo è in realtà solo una parte del problema C10k .
Arnaud Bouchez,

14

Qualsiasi moderno server singolo è in grado di gestire migliaia di client contemporaneamente . Il suo software server HTTP deve solo essere orientato agli eventi (IOCP) (non siamo più nella vecchia connessione Apache una connessione = un'equazione thread / processo più). Anche il server HTTP integrato in Windows (http.sys) è orientato all'IOCP e molto efficiente (in esecuzione in modalità kernel). Da questo punto di vista, non ci sarà molta differenza nel ridimensionamento tra WebSocket e la normale connessione HTTP. Una connessione TCP / IP utilizza una piccola risorsa (molto meno di un thread) e i sistemi operativi moderni sono ottimizzati per gestire molte connessioni simultanee: WebSocket e HTTP sono solo protocolli di livello applicazione OSI 7, ereditati da queste specifiche TCP / IP.

Ma, dall'esperimento, ho riscontrato due problemi principali con WebSocket:

  1. Non supportano la CDN;
  2. Hanno potenziali problemi di sicurezza.

Quindi consiglierei quanto segue, per qualsiasi progetto:

  • Usa WebSocket solo per le notifiche dei client (con un meccanismo di fallback per il polling lungo - ci sono molte librerie in giro);
  • Utilizzare RESTful / JSON per tutti gli altri dati, utilizzando un CDN o proxy per la cache.

In pratica, le applicazioni WebSocket complete non si adattano bene. Basta usare WebSocket per quello per cui sono stati progettati: inviare notifiche dal server al client.

Informazioni sui potenziali problemi dell'utilizzo di WebSocket:

1. Considerare l'utilizzo di una CDN

Oggi (quasi 4 anni dopo), il ridimensionamento web implica l'utilizzo di front-end Content Delivery Network (CDN), non solo per i contenuti statici (html, css, js) ma anche per i dati dell'applicazione (JSON) .

Naturalmente, non inserirai tutti i tuoi dati nella cache della CDN, ma in pratica molti contenuti comuni non cambieranno spesso. Ho il sospetto che l'80% delle tue risorse REST possa essere memorizzato nella cache ... Anche un timeout di scadenza CDN di un minuto (o 30 secondi) potrebbe essere sufficiente per dare al tuo server centrale un nuovo live e migliorare molto la reattività dell'applicazione, dal momento che CDN può essere geograficamente sintonizzato ...

Per quanto ne sappia, non esiste ancora alcun supporto WebSocket nella CDN e sospetto che non lo sarebbe mai stato. WebSocket sono statefull, mentre HTTP è senza stato, quindi è molto facilmente memorizzato nella cache. In effetti, per rendere WebSockets compatibile con CDN, potrebbe essere necessario passare a un approccio RESTful senza stato ... che non sarebbe più WebSocket.

2. Problemi di sicurezza

I WebSocket presentano potenziali problemi di sicurezza, in particolare sugli attacchi DOS. Per informazioni sulle nuove vulnerabilità di sicurezza, vedere questo set di diapositive e questo ticket Webkit .

I WebSocket evitano qualsiasi possibilità di ispezione dei pacchetti a livello di applicazione OSI 7, che al giorno d'oggi è abbastanza standard, in qualsiasi sicurezza aziendale. In effetti, WebSocket rende la trasmissione offuscata, quindi potrebbe essere una grave violazione della perdita di sicurezza.


2
@ArnaudBouchez - +1 per la bella mostra su CDN. Domanda di follow-up rapido: cosa pensi della fattibilità delle reti di consegna degli eventi? Basato su CDN ma orientato alla trasmissione di dati in streaming, ecc. Su socket Web o su qualche altra tecnologia non ancora vista.
Quixver,

8

Pensala in questo modo: cosa è più economico, mantenere una connessione aperta o aprire una nuova connessione per ogni richiesta (con il sovraccarico di negoziazione di farlo, ricorda che è TCP).

Naturalmente dipende dall'applicazione, ma per connessioni in tempo reale a lungo termine (ad es. Una chat AJAX) è molto meglio mantenere aperta la connessione.

Il numero massimo di connessioni sarà limitato dal numero massimo di porte libere per le prese.


È possibile mantenere aperta la connessione senza utilizzare un WebSocket (grazie all'opzione keep alive di HTTP / 1.1). Non sono sicuro di aver capito il tuo punto qui.
Arnaud Bouchez,

1
+1. Le persone tendono a dimenticare che l'impostazione di una connessione TCP implica un syn / ack / ack e TLS richiede più round trip per lo scambio di chiavi.
Quixver,

1
@ArnaudBouchez check it.wikipedia.org/wiki/HTTP_persistent_connection#HTTP_1.1 I WebSocket sono aperti quanto vuoi e non sono hacker (come il polling lungo e altre alternative).
Kaao,

-5

No, non si ridimensiona, offre un lavoro eccezionale agli interruttori di percorsi intermedi. Quindi sul lato server gli errori di pagina (è necessario mantenere tutti quei descrittori) stanno raggiungendo valori elevati e aumenta il tempo per portare una risorsa nell'area di lavoro. Si tratta per lo più di server scritti JAVA e potrebbe essere più veloce trattenere quei supporti di socket e poi distruggerne / crearne uno. Quando si esegue un server di questo tipo su una macchina, qualsiasi altro processo non può più muoversi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.