Chat ad alto traffico - come verificare se c'è un nuovo messaggio e mostrarlo a tutti gli utenti

2

Avevo già una domanda in proposito, ma ovviamente non è stata accettata molto bene, apparentemente troppo a lungo quando sono effettivamente più informazioni, quindi potresti darmi una risposta migliore.

Ok, sarò molto più chiaro ora. La migliore logica possibile per sviluppare una chat scalabile in termini di stabilità, memorizzazione / lettura dei messaggi sulla chat, aggiornamento della chat sul nuovo messaggio per tutti gli utenti, ecc.? Ho sviluppato la maggior parte di questo, la logica che penso mi manchi è - > controlla se c'è un nuovo messaggio e mostralo a tutti gli utenti. Ho implementato questo, ma si blocca il sito a causa del suo traffico di 300k-400k persone, quindi questa è la mia domanda principale.

La chat è basata su PHP e utilizza Pusher (www.pusher.com) per l'instant messaging, ma manca di quello che mi serve perché è più simile a un websocket.

Sto usando file hardcoded per mantenere i messaggi (voglio evitare il database il più possibile). È un tipo di estensione senza file, sono sicuro che lo sai. Sto andando in crash con

$fp = fopen(..., "w"); // pretend ... is the path and filename
fwrite($fp, $msg); //hardcode the message
fclose($fp);

dove $msg è il messaggio stesso. Sto avendo 1 file per messaggio. Mostro gli ultimi 150 messaggi = 150 accessi ai file e letture, sì è troppo suppongo. Ora ho una logica migliore che sto perseguendo e cioè 1 file con gli ultimi 50-100 messaggi in ogni momento. Certo dovrebbe essere molto meglio.

Come fa crash, questa è la parte più difficile perché tutto sembra ordinario, credimi è difficile determinare cosa blocca esattamente il sito, ma in circa 5 minuti quando provo ad aprire il sito non c'è più, quindi metto il vecchio contenuto senza chat ed è di nuovo online.

Sto facendo jquery post ogni 1 secondo per verificare se c'è un nuovo messaggio. Sto usando il timestamp in un file speciale dove tengo il tempo dell'ultimo messaggio inviato e if ((time() - time in file) <= 2) = ricarica gli ultimi 150 messaggi incluso l'ultimo. Troppa input / output, scrivere / leggere o comunque dirlo credo sia ciò che blocca il sito.

    
posta user2633999 31.07.2013 - 03:54
fonte

3 risposte

5

Prima di tutto, potresti fornirmi qualche chiarimento: stai codificando una chat room (one-to-many) o individuali (one-to-one)?

Ci sono un paio di difetti evidenti nel design del tuo sistema attuale che vorrei sottolineare. Per prima cosa, inizierò con una breve analisi e poi spiegherò che cosa c'è che non va e che cosa puoi fare per risolverlo. Ovviamente se vuoi eseguire un progetto di successo dovresti iniziare dal primo passaggio e sporcarti le mani con l'analisi e la progettazione dei sistemi.

Problema

Il sito riceve un volume elevato di traffico e alla fine si arresta in modo anomalo.

Requisiti

  1. Sostenere un volume elevato di traffico web
  2. Mostra i 150 precedenti messaggi
  3. Percorso di comunicazione sicuro tra i clienti

Analisi del problema

È ovvio che il tuo sito si sta arrestando in modo anomalo perché il codice che apre il file viene chiamato centinaia di migliaia di volte al secondo . L'apertura di file e la scrittura su di essi richiede molta memoria .

Il FILE Probem: I file non gestiscono molto bene la concorrenza. In realtà, sono terribili con la concorrenza. Pensaci in questo modo, in sostanza hai aperto lo stesso file con il blocco note con centinaia di migliaia di finestre aperte / processi e stai modificando il contenuto in tutti contemporaneamente . Quando si tenta di risolvere un problema con questo tipo di soluzione si finisce con risultati non deterministici . Fondamentalmente, è impossibile prevedere quali dati saranno nel file.

Fortunatamente, esiste un modo per ottenere risultati deterministici mentre si usano ancora i file se li si blocca correttamente . Sfortunatamente, questa non è una soluzione per il tuo problema . In tuo caso , solo una persona sarebbe in grado di inviare un messaggio alla volta. Sicuramente è NON la soluzione che desideri!

Aspetta ... c'è IS una soluzione:

Tu PUOI UTILIZZARE un database!

I database sono particolarmente buoni per risolvere questo tipo di problema di concorrenza! A seconda del database / motore che usi, la tua tabella potrebbe bloccarsi o solo un singolo record potrebbe bloccarsi. Nel tuo caso, ti suggerirei un database gratuito come MySQL e un motore di blocco dei record come InnoDB . Se non sei un novellino del database, potresti voler esaminare MariaDB , è un fork del progetto MySQL dello sviluppatore originale ed è un drop binario.

Fondamentalmente, non c'è modo di aggirarlo usando un database per questo tipo di soluzione. In effetti, i database sono molto potenti e puoi programmare le procedure con loro. Dalla query è possibile scegliere di selezionare solo 150 messaggi e quindi ordinarli molto rapidamente. Tutti gli utenti saranno in grado di inviare messaggi allo stesso tempo con un motore di database con blocco della registrazione come InnoDB .

Vorrei inoltre sottolineare che sarei un po 'turbato per scoprire come si presenta il codice per il resto dell'applicazione. È molto facile scrivere codice PHP che sembra buono ma che funziona terribilmente. Non sono sicuro che tu abbia familiarità con analisi asintotica o test delle unità ma ti suggerisco caldamente di testare il codice prima di inviarlo alla produzione . Data la dimensione della tua base utente dovresti preoccuparti dell'ottimizzazione del codice e del runtime. Se la tua applicazione / problema / soluzione è stata analizzata, progettata, implementata, testata e debuggata correttamente avresti una migliore gestione del tuo problema.

È anche molto facile scrivere codice in PHP che è insicuro. Vorrei consigliarti di testare accuratamente il codice (prova a romperlo) durante la scrittura di moduli che interagiscono con il database. Le applicazioni web codificate male possono essere molto facili da sfruttare e, data la base di utenti di 300-400k, non dubito che Cindy Lou Who improvvisamente abbia deciso di dargli il proprio controllo di sicurezza. Se un hacker con cappello bianco scopre la falla nel tuo sistema, probabilmente ti incoraggerà a risolverlo. Se un hacker black hat scopre il difetto, probabilmente lo userà per diffondere malware e rubare informazioni.

    
risposta data 21.08.2013 - 20:19
fonte
1

Personalmente, nel tuo caso di High Traffic , proverei onestamente un server redis o una qualche forma di memoria cache dei messaggi.

In qualsiasi lingua, dalle applicazioni Web PHP alle applicazioni desktop non appena ho la possibilità di leggere qualcosa da un file più di 2 volte in un secondo e la possibilità che cambi in quel secondo è così basso che memorizzo il risultato in cache . Il caching aiuta molto quando si esaminano questi problemi di prestazioni. Gli HDD hanno sempre il peggiore IO e sui server di produzione mi piace usare una maggiore quantità di ram e cache dove possibile.

Modifica Vorrei provare a usare Xdebug per analizzare dove sono le mie costose funzioni PHP. Vorrei provare anche un altro server e quindi un server più potente. Non ha senso cercare di eseguire il tuo sito web su 1gig mem e 1 core cpu. Avresti bisogno di affittare un dedi e un paio di core.

Se non funziona, puoi provare il clustering e utilizzare un server redis.

Inoltre, ciò che potresti provare è aumentare il tempo di conversazione a 4 o 5 secondi. Oppure cerca di personalizzare lo script della chat per utilizzare i socket Web.

    
risposta data 02.08.2013 - 08:00
fonte
0

Quello che potrebbe essere un buon modo per gestire questo è inserire dati usando php in un file xml che ha la stessa struttura del tuo database mysql.

Gli utenti leggono l'xml e quindi non costringono un php a fare troppo.

Ogni quattro giorni è possibile inserire dati da xml nel database che è più vecchio di due giorni e ripulire il file xml.

    
risposta data 25.10.2013 - 16:41
fonte

Leggi altre domande sui tag