WhatsApp usa RabbitMQ
WhatsApp usa RabbitMQ
Il coniglio è costruito su Erlang Lingua di programmazione per uso generale ed è anche usato da WhatsApp per la messaggistica.
Riepilogo
WhatsApp usa RabbitMQ, che è costruito su Erlang, come la sua coda di messaggistica per la consegna dei messaggi.
Quando si progetta un sistema di chat in tempo reale, è importante considerare la coda utilizzata da piattaforme di messaggistica popolari come WhatsApp e Facebook Messenger. Sebbene possa sembrare logico avere una coda per persona o un tema di kafka per ciascun utente, dati i miliardi di utenti su queste piattaforme, questo approccio richiederebbe un numero poco pratico di code o argomenti. Tuttavia, è stato osservato che WhatsApp e Facebook Messenger usano una coda chiamata “Iris” (simile a Kafka) per la consegna dei messaggi.
Esistono sistemi interni che popolano i database (come Hbase e MyRocks) dalla coda dei messaggi, ma questi database non sono il sistema di consegna primario.
Domande e risposte
1. Su cosa è costruito RabbitMQ?
RabbitMQ è costruito sul linguaggio di programmazione generale di Erlang.
2. In che modo WhatsApp usa RabbitMQ?
WhatsApp usa RabbitMQ come coda di messaggistica per la consegna dei messaggi.
3. Qual è lo scopo di una coda di messaggistica?
Una coda di messaggistica viene utilizzata per disaccoppiarsi i componenti di un sistema, consentendo l’invio di messaggi tra loro in modo asincrono.
4. È possibile utilizzare una coda per persona per la consegna dei messaggi in WhatsApp o Facebook Messenger?
Mentre una coda per persona può sembrare logica, richiederebbe un numero poco pratico di code dati i miliardi di utenti su queste piattaforme.
5. Quale coda viene utilizzata da WhatsApp e Facebook Messenger per la consegna dei messaggi?
WhatsApp e Facebook Messenger usano una coda chiamata “Iris” per la consegna dei messaggi. “Iris” è simile a Kafka.
6. Quali sono alcuni dei database utilizzati da WhatsApp per l’archiviazione dei messaggi?
WhatsApp utilizza database come Hbase e MyRocks per archiviare i messaggi. Questi database sono popolati dalla coda dei messaggi.
7. È RabbitMQ il sistema di consegna primario per WhatsApp?
No, RabbitMQ non è il sistema di consegna primario per WhatsApp. Viene usato come coda di messaggistica per la consegna dei messaggi.
8. La consegna dei messaggi in WhatsApp e Facebook Messenger sincrono o asincrona?
La consegna dei messaggi in WhatsApp e Facebook Messenger è asincrona, il che significa che i messaggi vengono inviati e ricevuti indipendentemente l’uno dall’altro.
9. Quali sono i vantaggi dell’utilizzo di una coda di messaggistica come RabbitMQ?
L’uso di una coda di messaggistica come RabbitMQ consente il disaccoppiamento dei componenti, una migliore scalabilità e una comunicazione asincrona tra elementi di sistema.
10. RabbitMQ può gestire elevati volumi di messaggi?
Sì, RabbitMQ è progettato per gestire elevati volumi di messaggi ed è in grado di consegnarli in modo efficiente e affidabile.
11. Quali sono le alternative a RabbitMQ per l’implementazione di una coda di messaggistica?
Alcune alternative a RabbitMQ includono Apache Kafka, ActiveMQ e Redis Streams.
12. Ci sono limitazioni all’utilizzo di una coda di messaggistica come RabbitMQ?
Alcune limitazioni dell’utilizzo di una coda di messaggistica come RabbitMQ includono la necessità di configurarla e sintonizzarla correttamente per prestazioni ottimali, potenziale perdita di messaggi se non correttamente configurati e la necessità di un’infrastruttura aggiuntiva per supportare la coda di messaggistica.
13. Può essere utilizzato RabbitMQ per altri scopi oltre alla messaggistica?
Sì, RabbitMQ può essere utilizzato per altri scopi oltre alla messaggistica, come la pianificazione delle attività, le architetture basate sugli eventi e lo streaming dei dati.
14. RabbitMQ supporta la persistenza del messaggio?
Sì, RabbitMQ supporta la persistenza dei messaggi, consentendo di archiviare e recuperare i messaggi anche in caso di guasti del sistema.
15. In che modo RabbitMQ garantisce l’affidabilità della consegna dei messaggi?
RabbitMQ garantisce l’affidabilità della consegna dei messaggi attraverso funzionalità come il riconoscimento dei messaggi, l’editore conferma e la durata della coda.
WhatsApp usa RabbitMQ
Il coniglio è costruito su Erlang Lingua di programmazione per uso generale ed è anche usato da WhatsApp per la messaggistica.
Coda usata in WhatsApp o FB Messenger
Mentre penso attraverso una progettazione del sistema per la chat in tempo reale, sono curioso di sapere che tipo di coda WhatsApp o FB Messenger sta usando sul lato server per consegnare il messaggio al destinatario. Quello che stavo pensando era che esiste una coda per persona/topi di kafka, quindi quando un nuovo messaggio deve essere consegnato all’utente A, il messaggio è accennato alla coda di A. Tuttavia, potrebbero esserci miliardi di utenti (FB ha 2 miliardi di utenti), significa che abbiamo bisogno di 2 miliardi di code/argomenti (in termini di kafka)? In tal caso, quale coda può gestirlo per favore. Qualsiasi commento è il benvenuto! Grazie!
Chiesto il 25 giugno 2019 alle 16:44
1.669 8 8 badge d’oro 23 23 badge d’argento 37 37 badge di bronzo
Puoi trovare la documentazione che Messager è stato costruito su Hbase e ora Myrocks. Esistono sistemi interni che popolano quei database da una coda, sì, ma non è il sistema di consegna primario. codice.fb.com/core-data/…
26 giugno 2019 alle 3:08
@cricket_007 grazie per i commenti. Yeap, sembra che FB usi Iris (Kafka come) come coda per la consegna.
Alifzl/Yomkippur
Questo commit non appartiene a nessun ramo in questo repository e può appartenere a una forchetta al di fuori del repository.
Switch Branches/Tags
Tag di rami
Impossibile caricare i rami
Niente da mostrare
Impossibile caricare tag
Niente da mostrare
Nome già in uso
Un tag esiste già con il nome della filiale fornito. Molti comandi git accettano nomi di tag e ramo, quindi la creazione di questo ramo può causare comportamenti imprevisti. Sei sicuro di voler creare questo ramo?
Annulla Crea
- Locale
- Codpaces
Https github cli
Utilizzare GIT o checkout con SVN utilizzando l’URL Web.
Lavorare velocemente con la nostra CLI ufficiale. Ulteriori informazioni sulla CLI.
Autenticazione richiesta
Si prega di accedere per utilizzare Codespaces.
Avvio del desktop GitHub
Se non succede nulla, scarica Github Desktop e riprova.
Avvio del desktop GitHub
Se non succede nulla, scarica Github Desktop e riprova.
Avvio di Xcode
Se non succede nulla, scarica Xcode e riprova.
Avvio del codice Visual Studio
Il tuo Codpace si aprirà una volta pronto.
C’è stato un problema a preparare il tuo codice, riprova.
Ultimo commit
Statistiche git
File
Impossibile caricare le ultime informazioni sulla commissione.
Ultimo messaggio di commit
Commettere tempo
Readme.MD
Yom Kippur è uno strumento di automazione WhatsApp che mira a essere una soluzione coerente e permanente per l’uso non commerciale di WhatsApp come bot automatizzato.
Che cosa fa?
- Invia/riceve un singolo messaggio in un’applicazione WhatsApp preconfigurata nel dispositivo AVD (Android Virtual)
- Crea un elenco di contatti in AVD e usalo per le cose di invio/ricezione
- Letteralmente può fare tutto con AVD (crea numerose possibilità da persuadere)
Al primo posto, ho visto Yowsup la mia unica scelta, ma a causa dei problemi elencati di seguito ho cambiato idea per implementarlo in un altro modo:
- Varietà di problemi di comunità (collegati qui)
- Yosup è un tipo di API asincrono che interagisce con WhatsApp Ristapi, per quanto riguarda le considerazioni di alta sicurezza di WhatsApp, è diventato molto sensibile alle attuali sessioni attive di ogni utente e non sarà molto amichevole con soluzioni sincronate. (Come probabilmente conosci le restrizioni all’utilizzo della vista web di WhatsApp che dice che dovremmo avere una connessione Internet attiva coerente nel telefono contemporaneamente)
- la mia pigrizia e mi sfidano anche a farlo nel modo più duro
Bene, le dipendenze in questo progetto, sono piuttosto molto! Il primo di voi dovrebbe avere questo requisito soddisfatto:
Gli installatori di Windows sono rivolti, ma può essere implicito nella macchina Linux o MacOS (entrambi non testati)
Dipendenza | Descrizione / Download Link |
---|---|
Android Studio | Android Studio con API Android 28 |
GIAVA | Java JDK 11 |
Mysql | Mysql installar community 8.X o sopra |
Python 2.7 | Python 2.7 |
Appium | V1.10 o sopra |
Rabbitmq | Ultima versione di RabbitMQ |
Postino | Ultima versione di Postman |
Considerazioni: Puoi usare Conda Virenv per Python 2.7, ma mi ha fatto un grave mal di testa (non consigliato)
Il motivo principale che ho usato Python 2 per questo progetto è che Appium, MySQL Connector Client e RabbitMQ erano incompatibili insieme nella versione 3.
Prima di tutto, sii paziente in questa parte. Mi ci sono voluti sangue e lacrime per asciugare le merda di dipendenza per fare questo un compito così semplice.
1.Dispositivo virtuale Android
Luanch AVD Manager di Android Studio, imposta un dispositivo con Android 9.0 con API 28 (scegli e nome appropriato per AVD perché ne abbiamo bisogno in ulteriori passaggi).
Si noti che dovresti installare WhatsApp tramite AVD stesso, quindi seleziona la versione supportata da PlayStore.
Controlla che hai queste variabili di ambiente nel tuo account:
Nome variabile | Valore variabile |
---|---|
Android_home | C: \ Users \ fzl \ appdata \ local \ Android \ SDK |
Java_home | C: \ Programmi \ java \ jdk-11.0.2 |
Pythonpath | C: \ python27; c: \ python27 \ lib \ site-packages; c: \ python27 \ lib; c: \ pithon27 \ dlls; c: \ python27 \ scripts |
Toppa | C: \ python27; c: \ python27 \ scripts; c: \ python27 \ lib \ site-packages; c: \ programmi file \ java \ jdk-11.0.2; c: \ Programmi \ java \ jdk-11.0.2 \ bin; |
Quindi dovresti avviare il tuo AVD, installare WhatsApp in questo e anche autorizzare l’ADB con il tuo dispositivo (obbligatorio)
Per fare ciò è necessario eseguire dispositivi ADB o ADB USB per verificare l’autorizzazione dell’AVD.
C:\ USERS\FZl\UNppdata\ Local\UNndoride\SDK\PTOOL LATFORM: Elenco dei dispositivi ADB dei dispositivi Emulator-5554 allegati
Se stai vedendo il risultato non autorizzato, dovresti seguire questo link.
2.Configurazione di RabbitMQ
Dopo l’installazione di RAABITMQ, è necessario eseguire RabbitMQ-Plugins Abilita RabbitMQ_Management nella directory di RabbitMQ Sbin al fine di abilitare il Web-GUI di RabbitMQ Management Sytem. Potrebbe essere necessario limitare il servizio di coniglio.
Successivamente dovresti essere in grado di accedere a RabbitMQ Web-gui con http: // localhost: 15672/#/indirizzo nella macchina locale. Se sì, crea un nuovo utente con i comandi seguenti e rendilo amministratore:
Password del nome utente ADD_USER CABBITMQCTL # Questo rende l'utente un amministratore Rabbitmqctl set_user_tags Nome utente amministratore # Questo imposta le autorizzazioni per l'utente rabbitmqctl set_permissions -p / nome utente ".*" ".*" ".*"
Accedi con credenziali appena create e importa le specifiche della coda che sono già allegate in questo repository che chiamava rabbitmq_conf.JSON nelle sezioni delle definizioni di importazione sotto il menue di panoramica.
Creerebbe le configurazioni necessarie per RabbitMQ e consentirebbe i privati necessari.
3.Appium
Basta eseguire il server Appium con le impostazioni predefinite. Appium-Default-Capabilities ” è già incorporato nel codice. Tl; dr: non c’è nulla da fare in questo passaggio.
4.Mysql
Installa l’edizione della community di MySQL, crea un account DB appropriato e impostare automaticamente il servizio all’avvio del sistema operativo.
5.Installa le dipendenze Python
Basta eseguire PIP Installa –R dipendenze.txt per risolvere la dipendenza delle librerie usate.
Potresti affrontare la versione deprecata della libreria MySQLDB che è risolvibile con l’installazione di questo e questo. Prenditi cura di installare il Python 2.X Versione delle biblioteche menzionate.
6.Crea directory per i file di registro
Crea le directory e i file come’s menzionato di seguito:
# directory C:\ var\ lOG [directory] c:\ var\ lOg\ whatsapp_api [directory] # log files C:\ var\ lOg\UNpi.Log C:\ var\ lOg\ whatsapp_single_consumer.Log C:\ var\ lOg\ whatsapp_single_worker.Log C:\ var\ log \
7.Imposta lo Yom Kippur’S file di configurazione
Vai a Yomkippur-Master \ configs \ config.CFG e inserire quanto segue.
(Non cambiare nulla a meno che tu non sappia cosa stai facendo)
[mysql] host = 127.0.0.1 nome utente ='Il tuo nome utente MySQL' password ='la tua password mysql' database = whatsapp [rabbitmq] ip = 127.0.0.1 ipqueuename = ipaddr.coda nome utente ='Il tuo nome utente di RabbitMQ' password ='La tua password di RabbitMQ' [queue_name] single_message = whatsapp_singlemessage_queue broadcast_message = whatsapp_broadcastmessage_queue add_contact = whatsapp_newcontact_listener_queue ascolta_message = whatsapp_messagelistener_queueue
Eseguire il principale.PY e ADD_NEW_CONTACT_PRODUCER.Py in due ambienti terminali/cmd separati.
Se non hai visto alcun errore, sei a posto.
- Assicurati che il server MySQL sia in esecuzione
- Assicurati che RabbitMQ sever sia runnig
- Esegui Appium con impostazioni di Defualt
- Esegui questi script
Python Main.py python add_new_contact_producer.Py Python single_message_producer.Py
- Esegui Postman e crea comandi postali desiderabili dall’elenco qui sotto:
Aggiunta di contatti nell’app di Google Contacts
Invio di un solo messaggio tramite WhatsApp
Sviluppo e contributo?
Voglio contribuire? Grande! Sentiti libero di bloccarmi a un.fazeli95 [at] gmail [dot] com o semplicemente crea una richiesta pull.
Tutti i componenti utilizzati in questo progetto sono open-source e hanno la licenza MIT e possono essere utilizzati in qualsiasi prodotto non commerciale
Di
WhatsApp Message Broker con RabbitMQ, AVD e Appium
Introduzione a RabbitMQ
Qui impareremo cos’è RabbitMQ, usi di RabbitMQ e perché dobbiamo usare RabbitMQ nelle nostre applicazioni con esempi.
Cos’è RabbitMQ?
Rabbitmq è un AMQP Broker di messaggistica ed è il broker di messaggi open source e multipiattaforma più popolare.
RabbitMQ è anche un modo per scambiare i dati tra diverse applicazioni della piattaforma come un messaggio inviato .Netto L’applicazione può essere letta da a Nodo.js applicazione o Giava applicazione.
Il coniglio è costruito su Erlang Lingua di programmazione per uso generale ed è anche usato da WhatsApp per la messaggistica.
Cos’è AMQP?
Il protocollo avanzato di coda di messaggi (AMQP) è un protocollo a livello di applicazione standard aperto per orientato ai messaggi e le caratteristiche di AMQP sono orientamento, coda, routing dei messaggi (compresi point-to-point e pubblicazione e sottoscrizione), affidabilità e sicurezza.
È stato sviluppato da JPMorgan e Imatix Corporation. AMQP è stato progettato con le seguenti caratteristiche principali come obiettivi:
- Sicurezza
- Affidabilità
- Interoperabilità
- Standard
- Aprire
RabbitMQ è leggero e facile da distribuire su locali disponibili e supporta più protocolli di messaggistica. RabbitMQ può essere distribuito in configurazioni distribuite e federate per soddisfare i requisiti di alta disponibilità ad alta scala.
Di seguito è riportata la rappresentazione pittorica di come RabbitMQ fungerà da mediatore tra mittente e consumatore nelle nostre applicazioni.
Perché e quando usare RabbitMQ?
Ora un giorno la maggior parte delle persone eseguirà più attività in una singola applicazione come l’invio di e -mail o SMS, report e creerà un carico pesante sull’applicazione, quindi se si separano queste attività, otterremo più spazio (memoria) per servire più richieste.
Usando RabbitMQ, possiamo rimuovere alcuni lavori pesanti dalle nostre applicazioni Web come l’invio di report in formato Excel o PDF’s o inviare un’e -mail, SMS o un’altra attività come attivare alcune altre applicazioni per iniziare l’elaborazione.
RabbitMQ è un broker di messaggi open source e multipiattaforma’è facile da usare con molte lingue come .Net, Java, Python, Ruby, Node.Js.
RabbitMQ supportate le librerie client
RabbitMQ supporterà più sistemi operativi e linguaggi di programmazione. RabbitMQ ha fornito varie librerie clienti per i seguenti linguaggi di programmazione.
- .Netto
- Giava
- Framework di primavera
- Rubino
- Pitone
- PHP
- Obiettivo-C e Swift
- JavaScript
- ANDARE
- Perl
Progettazione del sistema: WhatsApp
Progettiamo un servizio di messaggistica istantanea simile a WhatsApp, simile a servizi come WhatsApp, Facebook Messenger e WeChat.
Cos’è Whatsapp?
WhatsApp è un’applicazione di chat che fornisce servizi di messaggistica istantanea ai suoi utenti. È una delle applicazioni mobili più utilizzate sul pianeta che collega oltre 2 miliardi di utenti in 180+ paesi. WhatsApp è disponibile anche sul web.
Requisiti
Il nostro sistema dovrebbe soddisfare i seguenti requisiti:
Richieste funzionali
- Dovrebbe supportare la chat one-to-one.
- Chat di gruppo (max 100 persone).
- Dovrebbe supportare la condivisione dei file (immagine, video, ecc.).
Requisiti non funzionali
- Alta disponibilità con latenza minima.
- Il sistema dovrebbe essere scalabile ed efficiente.
Requisiti estesi
- Invia, consegnate e leggi le ricevute dei messaggi.
- Mostra l’ultimo tempo visto degli utenti.
- Le notifiche push.
Stima e vincoli
Cominciamo con la stima e i vincoli.
Nota: assicurati di controllare qualsiasi scala o ipotesi relative al traffico con il tuo intervistatore.
Traffico
Supponiamo che abbiamo 50 milioni di utenti attivi giornalieri (dau) e in media ogni utente invia almeno 10 messaggi a 4 persone diverse ogni giorno. Questo ci dà 2 miliardi di messaggi al giorno.
50 m i l l i o n × 20 m e s s a g e s = 2 b i l l i o n / d a y 50 \ spazio milione \ volte 20 \ messaggi spaziali = 2 \ space miliari / giorno 50 mi ll i o n × 20 m ess a g es = 2 bi ll i o n / d a y y y
I messaggi possono anche contenere supporti come immagini, video o altri file. Possiamo supporre che il 5 percento dei messaggi sia file multimediali condivisi dagli utenti, il che ci fornisce ulteriori 200 milioni di file di cui avremmo bisogno per archiviare.
5 p e r c e n t × 2 b i l l i o n = 200 m i l l i o n / d a y 5 \ spazio percentuale \ tempi \ space miliardi = 200 \ spazio milione / giorno 5 p erce n t × 2 bi ll i o n = 200 mi ll i o n / d a y
Cosa sarebbero richieste al secondo (RPS) per il nostro sistema? 2 miliardi di richieste al giorno si traducono in 24k richieste al secondo.
2 b i l l i o n (24 h r s × 3600 s e c o n d s) = ∼ 24 k r e q u e s t s / s e c o n d \ frac<2 \space billion> <(24 \space hrs \times 3600 \space seconds)>= \ SIM 24K \ Space Richieste / Second (24 H Rs × 3600 seco n d s) 2 bi ll i o n = ∼ 24 k re q u es t s / seco n d2>
### archivia.
2 b i l l i o n × 100 b y t e s = ∼ 200 g b / d a y 2 \ space miliari \ tempi \ space byte = \ sim 200 \ Space Gb / Day 2 bi ll i o n × 100 b y t es = ∼ 200 gb / d a y y
Secondo i nostri requisiti, sappiamo anche che circa il 5 percento dei nostri messaggi quotidiani (100 milioni) sono file multimediali. Se supponiamo che ogni file sia in media di 50 kb, richiederemo 10 TB di archiviazione ogni giorno.
100 m i l l i o n × 100 k b = 10 t b / d a y 100 \ spazio milione \ volte 100 \ spazio kb = 10 \ spazio tb / giorno 100 mi ll i o n × 100 k b = 10 tb / d a y
E per 10 anni, richiederemo circa 38 PB di archiviazione.
(10 T B + 0.2 t b) × 10 y e a r s × 365 d a y s = ∼ 38 p b (10 \ spazio tb + 0.2 \ Space Tb) \ Times 10 \ Space Years \ Times 365 \ Space Days = \ Sim 38 \ Space Pb (10 Tb + 0.2 tb) × 10 ye a rs × 365 d a ys = ∼ 38 pb
### larghezza di banda mentre il nostro sistema sta gestendo 10.2 TB di ingresso ogni giorno, richiederemo una larghezza di banda minima di circa 120 MB al secondo.
10.2 t b (24 h r s × 3600 s e c o n d s) = ∼ 120 m b / s e c o n d \ frac<10.2 \space TB> <(24 \space hrs \times 3600 \space seconds)>= \ SIM 120 \ Space Mb/Second (24 H Rs × 3600 seco n d s) 10.2 tb = ∼ 120 mb / seco n d10.2>
### stima di alto livello ecco la nostra stima di alto livello:
Tipo | Stima |
---|---|
Utenti attivi quotidiani (dau) | 50 milioni |
Richieste al secondo (RPS) | 24k/s |
Archiviazione (al giorno) | ~ 10.2 TB |
Spazio di archiviazione (10 anni) | ~ 38 pb |
Larghezza di banda | ~ 120 mb/s |
Progettazione del modello di dati
Questo è il modello di dati generale che riflette i nostri requisiti. Abbiamo le seguenti tabelle: utenti Questa tabella conterrà le informazioni di un utente come nome, foneenumber e altri dettagli. messaggi Come suggerisce il nome, questa tabella memorizzerà messaggi con proprietà come tipo (testo, immagine, video, ecc.), contenuto e timestamp per la consegna dei messaggi. Il messaggio avrà anche una chatid o un gruppo corrispondente . chat Questa tabella rappresenta sostanzialmente una chat privata tra due utenti e può contenere più messaggi. utenti_chat Questa tabella mappa gli utenti e le chat come più utenti possono avere più chat (N: M Relationship) e viceversa. gruppi Questa tabella rappresenta un gruppo tra più utenti. utenti_groups Questa tabella mappa gli utenti e i gruppi come più utenti possono far parte di più gruppi (relazione N: M) e viceversa.
Che tipo di database dovremmo usare?
Mentre il nostro modello di dati sembra abbastanza relazionale, non dobbiamo necessariamente archiviare tutto in un singolo database, in quanto ciò può limitare la nostra scalabilità e diventare rapidamente un collo di bottiglia. Divideremo i dati tra diversi servizi che hanno proprietà su una tabella particolare. Quindi possiamo utilizzare un database relazionale come PostgreSQL o un database NOSQL distribuito come Apache Cassandra per il nostro caso d’uso.
Design API
Facciamo un design API di base per i nostri servizi:
Ottieni tutte le chat o i gruppi
Questa API riceverà tutte le chat o i gruppi per un determinato utente .
prendi tutto(ID utente: Uuid) Chiacchierata[ | Gruppo[
Immettere la modalità a schermo intero
Esci dalla modalità a schermo intero
Parametri ID utente (UUID): ID dell’utente corrente. ritorna Risultato (chat [] | group []): tutte le chat e i gruppi di cui l’utente fa parte.
Ricevi messaggi
Ottieni tutti i messaggi per un utente fornito a ChannelID (chat o ID gruppo).
getMessages(ID utente: Uuid, Canale ID: Uuid) Messaggio[
Immettere la modalità a schermo intero
Esci dalla modalità a schermo intero
Parametri ID utente (UUID): ID dell’utente corrente. ID canale (UUID): ID del canale (chat o gruppo) da cui è necessario recuperare i messaggi. ritorna Messaggi (messaggio []): tutti i messaggi in una determinata chat o gruppo.
Invia messaggio
Invia un messaggio da un utente a un canale (chat o gruppo).
invia messaggio(ID utente: Uuid, Canale ID: Uuid, Messaggio: Messaggio) booleano
Immettere la modalità a schermo intero
Esci dalla modalità a schermo intero
Parametri ID utente (UUID): ID dell’utente corrente. ID canale (UUID): ID del canale (chat o gruppo) L’utente desidera inviare un messaggio a. Messaggio (messaggio): il messaggio (testo, immagine, video, ecc.) che l’utente desidera inviare. ritorna Risultato (booleano): rappresenta se l’operazione ha avuto successo o meno.
Unisciti o lascia un gruppo
Invia un messaggio da un utente a un canale (chat o gruppo).
unirsi al gruppo(ID utente: Uuid, Canale ID: Uuid) booleano Leavegroup(ID utente: Uuid, Canale ID: Uuid) booleano
Immettere la modalità a schermo intero
Esci dalla modalità a schermo intero
Parametri ID utente (UUID): ID dell’utente corrente. ID canale (UUID): ID del canale (chat o gruppo) l’utente desidera unirsi o lasciare. ritorna Risultato (booleano): rappresenta se l’operazione ha avuto successo o meno.
Design di alto livello
Ora facciamo un design di alto livello del nostro sistema.
Architettura
Utilizzeremo l’architettura dei microservizi poiché renderà più facile ridimensionare e disaccoppiarsi in orizzontale. Ogni servizio avrà la proprietà del proprio modello di dati. Proviamo a dividere il nostro sistema in alcuni servizi fondamentali. Servizio utente Questo è un servizio basato su HTTP che gestisce le preoccupazioni relative all’utente come l’autenticazione e le informazioni sull’utente. Servizio di chat Il servizio di chat utilizzerà WebSocket e stabilisce connessioni con il client per gestire la funzionalità relativa ai messaggi di chat e gruppo. Possiamo anche usare la cache per tenere traccia di tutte le connessioni attive un po ‘di sessioni che ci aiuteranno a determinare se l’utente è online o no. Servizio di notifica Questo servizio invierà semplicemente notifiche push agli utenti. Sarà discusso in dettaglio separatamente. Servizio di presenza Il servizio di presenza terrà traccia dell’ultimo stato visto di tutti gli utenti. Sarà discusso in dettaglio separatamente. Servizio multimediale Questo servizio gestirà i media (immagini, video, file, ecc.) carichi. Sarà discusso in dettaglio separatamente. Che dire della comunicazione inter-servizio e della scoperta del servizio? Poiché la nostra architettura è basata su microservizi, i servizi comunicheranno anche tra loro. Generalmente, REST o HTTP funziona bene, ma possiamo migliorare ulteriormente le prestazioni usando GRPC, che è più leggero ed efficiente. La scoperta del servizio è un’altra cosa che dovremo prendere in considerazione. Possiamo anche utilizzare una mesh di servizio che consenta una comunicazione gestita, osservabile e sicura tra i singoli servizi. Nota: scopri di più su Rest, GraphQL, GRPC e come si confrontano tra loro.
Messaggistica in tempo reale
Come inviare e ricevere messaggi in modo efficiente? Abbiamo due opzioni diverse: Modello di tiro Il client può periodicamente inviare una richiesta HTTP ai server per verificare se ci sono nuovi messaggi. Questo può essere ottenuto tramite qualcosa di simile a un lungo polling. Push Model Il client apre una connessione di lunga durata con il server e una volta disponibili nuovi dati verranno spinti al client. Possiamo utilizzare WebSockets o Server-Sent Events (SSE) per questo. L’approccio del modello pull non è scalabile in quanto creerà un sovraccarico di richieste non necessarie sui nostri server e il più delle volte la risposta sarà vuota, sprecando così le nostre risorse. Per ridurre al minimo la latenza, l’utilizzo del modello push con WebSocket è una scelta migliore perché possiamo spingere i dati al client una volta che è disponibile senza alcun ritardo dato che la connessione è aperta con il client. Inoltre, WebSockets fornisce una comunicazione a tutto duplex, a differenza degli eventi Server-Sent (SSE) che sono solo unidirezionali. NOTA: saperne di più su Long Polling, WebSockets, Server-Sent Events (SSE).
Ultima visualizzazione
Per implementare l’ultima funzionalità vista, possiamo usare un meccanismo cardiaco, in cui il cliente può periodicamente eseguire il ping dei server che indicano la sua vita. Poiché questo deve essere il più basso possibile, possiamo archiviare l’ultimo timestamp attivo nella cache come segue:
Chiave | Valore |
---|---|
Utente A | 2022-07-01T14: 32: 50 |
Utente b | 2022-07-05T05: 10: 35 |
Utente c | 2022-07-10T04: 33: 25 |
Questo ci darà l’ultima volta che l’utente è stato attivo. Questa funzionalità sarà gestita dal servizio di presenza combinato con Redis o Memcached come la nostra cache. Un altro modo per implementarlo è tenere traccia dell’ultima azione dell’utente, una volta che l’ultima attività attraversa una certa soglia, come “L’utente non ha eseguito alcuna azione negli ultimi 30 secondi”, Possiamo mostrare l’utente come offline e l’ultima volta con l’ultimo timestamp registrato. Questo sarà più un approccio di aggiornamento pigro e potrebbe avvantaggiarci al battito cardiaco in alcuni casi.
Notifiche
Una volta che un messaggio viene inviato in una chat o in un gruppo, verificheremo prima se il destinatario è attivo o meno, possiamo ottenere queste informazioni prendendo in considerazione la connessione attiva dell’utente e l’ultima volta. Se il destinatario non è attivo, il servizio di chat aggiungerà un evento a una coda di messaggi con metadati aggiuntivi come la piattaforma del dispositivo del client che verrà utilizzata per instradare la notifica sulla piattaforma corretta in seguito. Il servizio di notifica consumerà quindi l’evento dalla coda dei messaggi e inoltrerà la richiesta di Firebase Cloud Messaging (FCM) o Apple Push Notification Service (APNS) in base alla piattaforma del dispositivo del client (Android, iOS, Web, ecc.). Possiamo anche aggiungere supporto per e -mail e SMS. Perché stiamo usando una coda di messaggi? Poiché la maggior parte delle code di messaggi fornisce un ordine di miglior effetto che garantisce che i messaggi siano generalmente consegnati nello stesso ordine in cui vengono inviati e che un messaggio venga consegnato almeno una volta, il che è una parte importante della nostra funzionalità di servizio. Sebbene questo sembra un caso d’uso classico della pubblicazione-sottoscrizione, in realtà non è come dispositivi mobili e browser hanno ciascuno il loro modo di gestire le notifiche push. Di solito, le notifiche vengono gestite esternamente tramite Firebase Cloud Messaging (FCM) o Apple Push Notification Service (APNS) a differenza del ventilatore dei messaggi che vediamo comunemente nei servizi di backend. Possiamo usare qualcosa come Amazon SQS o RabbitMQ per supportare questa funzionalità.
Leggi le ricevute
La gestione delle ricevute di lettura può essere complicata, per questo caso d’uso possiamo attendere una sorta di riconoscimento (ACK) dal client per determinare se il messaggio è stato consegnato e aggiornare il corrispondente campo di consegna. Allo stesso modo, segneremo il messaggio il messaggio visualizzato una volta che l’utente apre la chat e aggiorneremo il campo Timestamp VEADAT corrispondente.
Progetto
Ora che abbiamo identificato alcuni componenti di base, facciamo la prima bozza della progettazione del nostro sistema.
Design dettagliato
È tempo di discutere in dettaglio le nostre decisioni di progettazione.
Partizionamento dei dati
- Partizionamento basato su hash
- Partizionamento basato su elenco
- Partizionamento basato sulla gamma
- Partizionamento composito
Gli approcci di cui sopra possono ancora causare dati irregolari e distribuzione del carico, possiamo risolverlo utilizzando hashing coerente.
Cache
In un’applicazione di messaggistica, dobbiamo fare attenzione a utilizzare la cache poiché i nostri utenti si aspettano i dati più recenti, ma molti utenti richiederanno gli stessi messaggi, specialmente in una chat di gruppo. Quindi, per evitare picchi di utilizzo dalle nostre risorse, possiamo memorizzare nella cache dei messaggi più vecchi.
Alcune chat di gruppo possono avere migliaia di messaggi e inviare che sulla rete saranno davvero inefficienti, per migliorare l’efficienza possiamo aggiungere impaginazione alle nostre API di sistema. Questa decisione sarà utile per gli utenti con larghezza di banda di rete limitata in quanto non dovranno recuperare vecchi messaggi a meno che.
Quale politica di sfratto della cache utilizzare?
Possiamo usare soluzioni come Redis o Memcached e Cache il 20% del traffico giornaliero, ma che tipo di politica di sfratto della cache si adatterebbe meglio alle nostre esigenze?
Meno recentemente usato (LRU) può essere una buona politica per il nostro sistema. In questa politica, scartiamo prima la chiave meno usata.
Come gestire la cache miss?
Ogni volta che c’è una cache, i nostri server possono colpire direttamente il database e aggiornare la cache con le nuove voci.
Per maggiori dettagli, consultare la memorizzazione nella cache.
Accesso e memoria dei media
Come sappiamo, la maggior parte del nostro spazio di archiviazione verrà utilizzata per archiviare file multimediali come immagini, video o altri file. Il nostro servizio multimediale gestirà sia l’accesso che l’archiviazione dei file multimediali utente.
Ma dove possiamo archiviare i file su scala? Bene, l’archiviazione degli oggetti è ciò che stiamo cercando. Oggetto archivia i file di dati a pezzi chiamati oggetti. Quindi memorizza quegli oggetti in un singolo repository, che può essere distribuito su più sistemi in rete. Possiamo anche utilizzare l’archiviazione di file distribuiti come HDFS o GlusterFS.
Fatto divertente: WhatsApp elimina i media sui suoi server una volta che è stato scaricato dall’utente.
Possiamo utilizzare negozi di oggetti come Amazon S3, Azure BLOB Storage o Google Cloud Storage per questo caso d’uso.
Rete di consegna dei contenuti (CDN)
Content Delivery Network (CDN) aumenta la disponibilità e la ridondanza del contenuto riducendo al contempo i costi di larghezza di banda. Generalmente, file statici come immagini e video sono serviti da CDN. Possiamo utilizzare servizi come Amazon CloudFront o CloudFlare CDN per questo caso d’uso.
API Gateway
Dal momento che utilizzeremo più protocolli come HTTP, WebSocket, TCP/IP, distribuire più bilanciatori di carico L4 (livello di trasporto) o L7 (Applicazione) per ciascun protocollo sarà costoso. Invece, possiamo usare un gateway API che supporta più protocolli senza problemi.
API Gateway può anche offrire altre funzionalità come autenticazione, autorizzazione, limitazione della tariffa, limitazione e versioni API che miglioreranno la qualità dei nostri servizi.
Possiamo utilizzare servizi come Amazon API Gateway o Azure API Gateway per questo caso d’uso.
Identifica e risolvi i colli di bottiglia
Identifichiamo e risolviamo i colli di bottiglia come singoli punti di fallimento nel nostro design:
- “E se uno dei nostri servizi si arresta?”
- “Come distribuiremo il nostro traffico tra i nostri componenti?”
- “Come possiamo ridurre il carico sul nostro database?”
- “Come migliorare la disponibilità della nostra cache?”
- “API Gateway non sarebbe un singolo punto di fallimento?”
- “Come possiamo rendere il nostro sistema di notifica più robusto?”
- “Come possiamo ridurre i costi di archiviazione dei media”?
- “Il servizio di chat ha troppa responsabilità?”
Per rendere il nostro sistema più resiliente possiamo fare quanto segue:
- Esecuzione di più istanze di ciascuno dei nostri servizi.
- Presentazione dei bilanciatori di carico tra client, server, database e server cache.
- Utilizzo di repliche di lettura multipla per i nostri database.
- Più istanze e repliche per la nostra cache distribuita.
- Possiamo avere una replica di standby del nostro gateway API.
- Esattamente una volta che l’ordinamento della consegna e dei messaggi è impegnativo in un sistema distribuito, possiamo utilizzare un broker di messaggi dedicato come Apache Kafka o Nats per rendere il nostro sistema di notifica più robusto.
- Possiamo aggiungere funzionalità di elaborazione e compressione dei media al servizio multimediale per comprimere file di grandi dimensioni simili a WhatsApp che risparmieranno molto spazio di archiviazione e ridurrà i costi.
- Possiamo creare un servizio di gruppo separato dal servizio di chat per disaccoppiare ulteriormente i nostri servizi.
Questo articolo fa parte del mio corso di progettazione del sistema open source disponibile su GitHub.
KaranPratapsingh / System-Design
Scopri come progettare sistemi su vasta scala e preparati per le interviste di progettazione del sistema
Corso di progettazione del sistema
Ehi, benvenuti al corso. Spero che questo corso offra una grande esperienza di apprendimento.
Questo corso è disponibile anche sul mio sito Web e come ebook su Leanpub. Si prega di lasciare un ⭐ come motivazione se questo è stato utile!
Sommario
- Iniziare
- Cos’è la progettazione del sistema?
- IP
- Modello OSI
- TCP e UDP
- Sistema di nomi di dominio (DNS)
- Bilancio del carico
- Clustering
- Cache
- Rete di consegna dei contenuti (CDN)
- Proxy
- Disponibilità
- Scalabilità
- Magazzinaggio
- Database e DBM
- Database SQL
- Database NoSQL
- Database SQL vs NoSQL
- Replica del database
- Indici
- Normalizzazione e denormalizzazione
- Modelli di consistenza acida e di base
- Teorema del cappello
- Teorema di Pacelc
- Transazioni
- Transazioni distribuite
- Sharding
- Hashing costante
- Federazione del database
- Architettura a livello n
- Broker di messaggi
- Code di messaggi
- Pubblica sottoscrizione
- Bus di servizio aziendale (ESB)
- Monoliti e microservizi
- Architettura guidata da eventi (EDA)
- Sourcing per eventi
- Segregazione di responsabilità di comando e query (CQRS)
- API Gateway
- Riposo, graphql, GRPC
- Polling lungo, WebSockets, Server-Sent Events (SSE)