Configurazione di High Availability

La soluzione client standard dell'API di WhatsApp Business viene eseguita su un singolo contenitore Docker. Infatti, avere più contenitori Docker in esecuzione provocherà dei problemi e il tuo account verrà temporaneamente escluso. Questa guida ti aiuterà a configurare High Availability, consentendoti di mettere i contenitori Docker in standby nel caso in cui non funzioni il contenitore Docker primario.

Questa soluzione High Availability richiede l'installazione di un'istanza singola del client dell'API di WhatsApp Business esistente da eseguire su di essa. Se non hai ancora configurato il numero di telefono del client dell'API di WhatsApp Business, consulta la documentazione relativa all'installazione prima di procedere con questa soluzione.

Panoramica

Un cluster High Availability richiede almeno due nodi Master e due nodi Coreapp come mostrato nello schema seguente:

Cluster High Availability

Ti consigliamo di eseguire ogni nodo su una macchina o un rack differente, per evitare che possibili guasti a un'unica macchina o rack si riflettano su più nodi contemporaneamente.

Avvio

All'avvio di un cluster, tutti i nodi Master competeranno per ottenere il lease principale per diventare primari. Solo un nodo avrà successo e gli altri diventeranno Master secondari. Se nel cluster è presente un numero N di nodi Master, saranno presenti un Master primario e N-1 Master secondari. Il Master primario è responsabile della registrazione, dell'aggiornamento dello schema del database, della trasmissione delle modifiche alla configurazione, della comunicazione delle statistiche del database, della gestione dei cluster ecc. Se il Master primario smette di funzionare e perde il lease principale, gli altri m=Master secondari competeranno per assumere la posizione di Master primario.

Quando un Master diventa primario, per prima cosa carica la tabella della mappa partizioni dal database per sapere chi è l'attuale Coreapp primario. Se non sono presenti Coreapp primari nel cluster, il Master primario promuoverà un Coreapp secondario funzionante a Coreapp primario e aggiornerà la tabella della mappa partizioni nel database in modo che Webapp possa cercare il nodo Coreapp a cui inviare richieste API. In questo modo, anche se tutti i Master sono inattivi, potrebbe comunque mostrare le richieste API nei nodi Coreapp per ottenere High Availability.

All'avvio, un nodo Coreapp sarà eseguito come Coreapp secondario fino a quando il Master primario non lo promuoverà a Coreapp primario per la connessione al server WhatsApp. Successivamente, sarà responsabile della gestione delle richieste API.

Monitoraggio basato su database

Ogni nodo Coreapp aggiornerà il database ogni minuto per risultare funzionante. Il Master primario controllerà periodicamente il database per rilevare i nodi Coreapp non correttamente funzionanti. Se il nodo Coreapp primario non aggiorna il database per più di 2 minuti, il Master primario lo considera non correttamente funzionante e promuove un nodo Coreapp differente al ruolo di primario. In questo modo, il tempo di inattività è di circa 2 minuti.

Monitoraggio basato su heartbeat

Se un cluster ha più di un Master in esecuzione, il monitoraggio basato su heartbeat rileva gli errori dei nodi più velocemente rispetto al monitoraggio basato su database. Nel monitoraggio basato su heartbeat, tutti i Master sono responsabili del monitoraggio dei nodi Coreapp attraverso l'invio di heartbeat ogni 5 secondi (tempo configurato da heartbeat_interval). Se un Coreapp primario non risponde al Master primario e a un Master secondario per 30 secondi (tempo configurato da unhealthy_interval), viene considerato non correttamente funzionante e il Master primario promuove un Coreapp secondario funzionante a Coreapp primario. In questo modo, il tempo di inattività è di circa 30 secondi per impostazione predefinita. Puoi ridurre il valore unhealthy_interval se desideri un tempo di inattività inferiore. Consulta la documentazione relativa alle impostazioni per payload di esempio.

Configurazione iniziale

In un cluster High Availability sono presenti tre tipi di nodo: Webapp, Master e Coreapp. Questi potrebbero essere avviati separatamente su macchine diverse, ma devono essere nella stessa rete, così da poter parlare tra loro.

Un nodo Webapp è responsabile della gestione del traffico API come il contenitore Webapp originale. Un nodo Coreapp è responsabile della gestione del traffico dei messaggi da e verso WhatsApp. Infine, un nodo Master è responsabile del monitoraggio dei nodi Coreapp nel cluster, quindi se un nodo Coreapp smette di funzionare, reindirizzerà il traffico verso un altro nodo Coreapp per High Availability. Potrebbero essere presenti più nodi Webapp, Coreapp e Master nel cluster.

I nodi attivi non vengono più indicati come nodi slave. Vengono chiamati nodi Coreapp.

Nota: per gli ambienti di produzione, nella maggior parte dei casi il database deve essere eseguito su un server fisico separato dai contenitori Coreapp e Webapp. Per la reale High Availability, è consigliato eseguire i contenitori Master, Webapp e Coreapp su macchine fisiche diverse.

Configurazione di un file system condiviso per i messaggi multimediali

Se non sei interessato ai messaggi multimediali, salta questo passaggio.

Per supportare l'invio/la ricezione di messaggi multimediali, è necessario configurare un file system NFS ed eseguire il mount su una directory locale su tutti i nodi Webapp, Master e Coreapp. Assicurati che le autorizzazioni di lettura/scrittura siano state concesse sulla directory condivisa.

Esempio di comando di mount NFS:

mkdir new-local-directory
mount -t nfs nfs_server_IP_addr:/share_directory new-local-directory

Installazione con Docker Compose

Questa guida richiede Docker, una piattaforma contenitore che consente di eseguire il client dell'API di WhatsApp Business. È inoltre richiesto Docker Compose. Docker Compose è in bundle con Docker per macOS e Windows, ma richiede un'installazione separata su Linux.

Configurazione di sviluppatori con un singolo server

  1. Installa Docker sul tuo sistema.
  2. Se Docker Compose non è in bundle con l'installazione di Docker, installalo.
  3. Scarica i file di configurazione multiconnect-compose.yml e db.env: WhatsApp_Configuration_Files.zip.
  4. Apri una console e vai alla directory in cui hai salvato i file scaricati.
  5. Se hai un'installazione MySQL in esecuzione, modifica i valori nel file db.env per riflettere la tua configurazione MySQL. Se non hai MySQL installato, i file multiconnect-compose.yml e db.env hanno una configurazione predefinita per visualizzare un'istanza in un contenitore locale.
  6. Assicurati che non siano presenti contenitori a connessione singola in esecuzione prima di avviare più contenitori per High Availability:
      docker-compose -f your-single-connect-yml-filename stop
    
  7. Esegui il seguente comando nella console:
    docker-compose -f multiconnect-compose.yml up
    Otterrai dell'output mentre lo script scarica le immagini Docker ed esegue l'impostazione. Per eseguire i contenitori in background, utilizza il parametro -d:
    docker-compose -f multiconnect-compose.yml up -d

Una volta completati questi passaggi, assicurati che i contenitori siano in esecuzione con il seguente comando:

docker-compose ps

Per impostazione predefinita, il contenitore Webapp verrà eseguito sulla porta 9090.

Configurazione di produzione con più server per ciascun contenitore

  1. Installa Docker sui tuoi sistemi.
  2. Se Docker Compose non è in bundle con le installazioni di Docker, installalo.
  3. Scarica i file di configurazione multiconnect-coreapp.yml, multiconnect-master.yml, multiconnect-webapp.yml e db.env: WhatsApp_Configuration_Files.zip e salva ognuno di questi ultimi sul rispettivo server.
  4. Su ciascun server, apri una console e vai alla directory in cui hai salvato i file scaricati.
  5. In una configurazione di produzione, si consiglia vivamente di utilizzare un'istanza MySQL autonoma. Se ne hai una, modifica i valori nel file db.env per riflettere la tua configurazione MySQL.
  6. Assicurati che non siano presenti contenitori a connessione singola in esecuzione prima di avviare più contenitori per High Availability:
    docker-compose -f your-single-connect-yml-filename stop
    
  7. Esegui ciascuno dei seguenti comandi nella console per la rispettiva macchina:

    La variabile di ambiente EXTERNAL_HOSTNAME deve essere un indirizzo IP o nome host accessibile dalle macchine che eseguono altri contenitori. Le porte esposte in un file YML di servizio dovrebbero essere aperte alle connessioni da macchine che eseguono altri contenitori. Ad esempio, le porte definite come COREAPP_EXTERNAL_PORTS in multiconnect-coreapp.yml devono essere aperte per il traffico in entrata sull'host che esegue contenitori coreapp.

    EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-coreapp.yml up # on the Coreapp server
    EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-master.yml up # on the Master server
    EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-webapp.yml up # on the Webapp server
    Otterrai dell'output mentre lo script scarica le immagini Docker ed esegue l'impostazione. Per eseguire i contenitori in background, utilizza il parametro -d:
    EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-coreapp.yml up -d # on the Coreapp server
    EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-master.yml up -d # on the Master server
    EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-webapp.yml up -d # on the Webapp server

Una volta completati questi passaggi, assicurati che i contenitori siano in esecuzione con il seguente comando:

EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-coreapp.yml ps # on the Coreapp server
EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-master.yml ps # on the Master server
EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-webapp.yml ps # on the Webapp server

L'esecuzione di più istanze dello stesso servizio (ad esempio, l'esecuzione di 2 Coreapp sullo stesso host) non funzionerà per impostazione predefinita a causa del conflitto delle porte dell'host. Per evitare conflitti di porte, è necessario modificare il rispettivo file YML di servizio, in questo caso multiconnect-coreapp.yml, in modo da esporre diverse porte dell'host per ogni istanza come segue:

ports:
- "HOST_PORT_RANGE:6250-6253"

Per impostazione predefinita, il contenitore Webapp verrà eseguito sulla porta 9090.

Aggiornamento

Configurazione di sviluppatori con un singolo server

Il file multiconnect-compose.yml ha dei campi che indicano le versioni del contenitore. Ad esempio:

services: ... waweb: image: docker.whatsapp.biz/web:v2.19.4 ... master: image: docker.whatsapp.biz/coreapp:v2.19.4 ... wacore: image: docker.whatsapp.biz/coreapp:v2.19.4

Per aggiornare un'installazione, modifica i numeri di versione nel file multiconnect-compose.yml:

services: ... waweb: image: docker.whatsapp.biz/web:v2.19.7 ... master: image: docker.whatsapp.biz/coreapp:v2.19.7 ... wacore: image: docker.whatsapp.biz/coreapp:v2.19.7

Quindi, riavvia i contenitori Docker:

docker-compose -f multiconnect-compose.yml up

Configurazione di produzione con più server per ciascun contenitore

I file YAML hanno dei campi che indicano le versioni del contenitore. Ad esempio:

services: ... waweb: image: docker.whatsapp.biz/web:v2.19.4
services: ... wacore: image: docker.whatsapp.biz/coreapp:v2.19.4

services: ... master: image: docker.whatsapp.biz/coreapp:v2.19.4

Per aggiornare un'installazione, modifica i numeri di versione nei rispettivi file:

services: ... waweb: image: docker.whatsapp.biz/web:v2.19.7
services: ... wacore: image: docker.whatsapp.biz/coreapp:v2.19.7

services: ... master: image: docker.whatsapp.biz/coreapp:v2.19.7

Quindi, riavvia i contenitori Docker:

EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-coreapp.yml up # on the Coreapp server
EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-master.yml up # on the Master server
EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-webapp.yml up # on the Webapp server

Allegare volumi esistenti

Se hai volumi di contenuti multimediali da un'installazione precedente, sostituisci la seguente definizione di volume nei file YAML:

volumes:
  whatsappData:
      driver: local
  whatsappMedia:
      driver: local

con:

volumes:
  whatsappData:
      external: true
  whatsappMedia:
      external: true

Bind mount

Questo passaggio è consigliato solo se desideri mantenere un volume di bind mount esistente.

Se desideri eseguire direttamente il mount di un percorso dell'host (una posizione esistente sull'host) nel contenitore, puoi farlo modificando la linea del volume all'interno della sezione del servizio in modo che punti al percorso dell'host.

wacore:
    volumes:
        /filepath/waent/data:/usr/local/waent/data
        /filepath/wamedia:/usr/local/wamedia

Disinstallazione

Configurazione di sviluppatori con un singolo server

Dovrai ripetere questo passaggio per tutte le macchine in cui sono presenti nodi in esecuzione.

Se è necessario reimpostare l'ambiente di sviluppo rimuovendo tutti i contenitori, esegui il seguente comando dalla directory che contiene il file multiconnect-compose.yml:

docker-compose -f multiconnect-compose.yml down

Per eliminare tutti i volumi definiti nel file multiconnect-compose.yml in aggiunta ai contenitori, esegui down con il parametro -v:

docker-compose -f multiconnect-compose.yml down -v

Configurazione di produzione con più server per ciascun contenitore

Se è necessario reimpostare l'ambiente di sviluppo rimuovendo tutti i contenitori, esegui il seguente comando dalla directory che contiene il file YAML su ciascun server:

EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-coreapp.yml down # on the Coreapp server
EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-master.yml down # on the Master server
EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-webapp.yml down # on the Webapp server

Per eliminare tutti i volumi definiti nei file YAML in aggiunta ai contenitori, esegui down con il parametro -v:

EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-coreapp.yml down -v # on the Coreapp server
EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-master.yml down -v # on the Master server
EXTERNAL_HOSTNAME=MACHINE_HOSTNAME docker-compose -f multiconnect-webapp.yml down -v # on the Webapp server

Registri per la risoluzione dei problemi

Per ottenere i registri per la risoluzione dei problemi, esegui il seguente comando sui server:

  docker-compose logs > debug_output.txt