Die Standardversion des WhatsApp Business API-Client wird in einem einzelnen Docker-Container ausgeführt. Mehrere parallel ausgeführte Docker-Container verursachen Probleme und führen dazu, dass dein Konto vorübergehend gesperrt wird. Dieser Leitfaden enthält Informationen dazu, wie du die hohe Verfügbarkeit einrichtest und Docker-Container als Standby-Lösungen für den Fall nutzt, dass der primäre Docker-Container ausfällt.
Diese Hochverfügbarkeitslösung erfordert die zusätzliche Ausführung einer vorhandenen Einzelinstanz-Installation des WhatsApp Business API-Client. Wenn du deine WhatsApp Business API-Client-Telefonnummer noch nicht eingerichtet hast, lies dir die Installationsdokumentation durch, bevor du mit dieser Lösung fortfährst.
Ein Hochverfügbarkeits-Cluster erfordert zumindest zwei Master-Nodes und zwei Coreapp-Nodes (siehe Diagramm unten):
Es empfiehlt sich, alle Nodes auf unterschiedlichen Rechnern/Racks auszuführen. So wird verhindert, dass bei Ausfall eines Rechners/Racks gleichzeitig mehrere Nodes betroffen sind.
Wenn ein Cluster hochfährt, konkurrieren alle Master-Nodes um den Master-Lease, um der primäre Node zu werden. Nur ein Node hat Erfolg. Die anderen werden zu sekundären Master-Nodes. Ein Cluster mit N Master-Nodes enthält einen primären Master und N-1 sekundäre Master. Der primäre Master ist zuständig für Registrierung, Upgrade des Datenbankschemas, Übertragung von Konfigurationsänderungen, Reporting on Datenbankstatistiken, Cluster-Verwaltung etc. Wenn der primäre Master abstürzt und den Master-Lease verliert, konkurrieren andere sekundäre m=Master um die Position des primären Masters.
Wenn ein Master zum primären Master wird, lädt er zuerst die Shard Map-Tabelle aus der Datenbank. Dort findet er den aktuellen primären Coreapp. Wenn das Cluster keinen primären Coreapp enthält, befördert der primäre Master einen funktionsfähigen Sekundär-Coreapp zum primären Coreapp und aktualisiert die Shard Map-Tabelle in der Datenbank. Dort kann Webapp nachsehen, an welchen Coreapp-Node API-Anfragen zu senden sind. Auf diese Weise ist gewährleistet, dass API-Anfragen in den Coreapp-Nodes auch dann bearbeitet werden können, wenn alle Master ausgefallen sind. Die Hochverfügbarkeit ist damit gewährleistet.
Wenn ein Coreapp-Node hochfährt, wird er als sekundärer Coreapp ausgeführt, bis er vom primären Master zum primären Coreapp befördert wird, der mit dem WhatsApp-Server verbunden ist. Im Anschluss daran ist er für die Verarbeitung von API-Anfragen verantwortlich.
Zur Bestätigung seiner Funktionsfähigkeit aktualisiert jeder Coreapp-Node im Minutentakt die Datenbank. Der primäre Master überprüft in regelmäßigen Abständen die Datenbank auf fehlerhafte Coreapp-Nodes. Wenn ein primärer Coreapp-Node die Datenbank länger als zwei Minuten nicht aktualisiert hat, betrachtet der primäre Master ihn als fehlerhaft. Dann befördert er andere Coreapp-Nodes zu primären Nodes. So ist gewährleistet, dass eine Ausfallzeit maximal zwei Minuten dauert.
Wenn ein Cluster mehr als einen aktiven Master hat, erkennt die heartbeat-basierte Überwachung Node-Ausfälle schneller als die datenbankbasierte Überwachung. Bei der heartbeat-basierten Überwachung müssen alle Master Coreapp-Nodes überwachen. Dazu senden sie im fünf-Sekunden-Takt (konfiguriert über heartbeat_interval
) Heartbeat-Signale an diese Nodes. Wenn ein primärer Coreapp 30 Sekunden lang (konfiguriert über unhealthy_interval
) weder dem primären Master noch einem sekundären Master geantwortet hat, wird er als fehlerhaft betrachtet. Der primäre Master befördert dann einen funktionsfähigen Coreapp zum primären Coreapp. So ist gewährleistet, dass eine Ausfallzeit standardmäßig maximal 30 Sekunden dauert. Wenn du die Ausfallzeit verkürzen möchtest, kannst du den Wert unhealthy_interval
verringern. Siehe dir hierzu die Beispiel-Payloads in der Dokumentation zu den Einstellungen an.
In einem Hochverfügbarkeits-Cluster werden drei Arten von Nodes unterschieden: Webapp, Master und Coreapp. Diese Nodes könnten auf unterschiedlichen Rechnern gestartet werden, aber sie müssen sich in demselben Netzwerk befinden, damit sie untereinander kommunizieren können.
Webapp-Nodes sind für die Durchführung des API-Datenverkehrs zuständig (wie die ursprünglichen Webapp-Container). Coreapp-Nodes kümmern sich um den Messaging-Datenverkehr zu bzw. von WhatsApp. Master-Nodes schließlich sind für die Überwachung von Coreapp-Nodes im Cluster verantwortlich. Wenn beispielsweise ein Coreapp-Node nicht mehr verfügbar ist, wird der Datenverkehr an einen anderen Coreapp-Node weitergeleitet, damit die hohe Verfügbarkeit gewährleistet bleibt. Im Cluster können sich mehrere Webapp-, Coreapp- und Master-Nodes befinden.
Aktive Nodes werden nicht mehr als Slave-Nodes bezeichnet, sondern als Coreapp-Nodes.
Hinweis: In Produktionsumgebungen sollte die Datenbank in den meisten Fällen auf einem physischen Server von den Coreapp- und Webapp-Containern getrennt betrieben werden. Für echte Hochverfügbarkeit sollten Master-, Webapp- und Coreapp-Container auf unterschiedlichen physischen Rechnern ausgeführt werden.
Wenn dich Mediennachrichten nicht interessieren, kannst du diesen Schritt überspringen.
Wenn das Senden und Empfangen von Mediennachrichten unterstützt werden soll, musst du ein NFS-Dateisystem einrichten und in einem lokalen Verzeichnis auf allen Webapp-, Master- und Coreapp-Nodes mounten. Im freigegebenen Verzeichnis müssen Lese- und Schreibberechtigungen gewährt werden.
mkdir new-local-directory mount -t nfs nfs_server_IP_addr:/share_directory new-local-directory
Dieser Leitfaden erfordert Docker, eine Containerplattform, auf der der WhatsApp Business API-Client ausgeführt werden kann. Docker Compose ist ebenfalls erforderlich. Docker Compose ist im Lieferumfang von Docker für MacOS und Windows enthalten, erfordert aber eine separate Installation unter Linux.
multiconnect-compose.yml
und db.env
herunter: WhatsApp_Configuration_Files.zip.
db.env
der MySQL-Konfiguration entsprechend. Wenn du MySQL nicht installiert hast, sind die Dateien multiconnect-compose.yml
und db.env
standardmäßig so konfiguriert, dass eine Instanz in einem lokalen Container geöffnet wird.docker-compose -f your-single-connect-yml-filename stop
docker-compose -f multiconnect-compose.yml upDu erhältst einige Ausgabeinformationen, während das Skript die Docker-Images herunterlädt und das Setup abschließt. Um die Container im Hintergrund auszuführen, verwende den folgenden
-d
-Parameter:
docker-compose -f multiconnect-compose.yml up -d
Überprüfe nach Abschluss dieser Schritte, ob die Container mit dem folgenden Befehl ausgeführt werden:
docker-compose ps
Standardmäßig wird der Webapp-Container auf Port 9090 ausgeführt.
multiconnect-coreapp.yml
, multiconnect-master.yml
, multiconnect-webapp.yml
und db.env
herunter: WhatsApp_Configuration_Files.zip. Speichere die einzelnen Dateien auf den jeweiligen Servern.
db.env
entsprechend deiner MySQL-Konfiguration.docker-compose -f your-single-connect-yml-filename stop
Die Umgebungsvariable EXTERNAL_HOSTNAME muss eine IP-Adresse oder ein Hostname sein, auf die/den von den Rechnern, auf denen die anderen Container ausgeführt werden, zugegriffen werden kann. Die in einer Service-YML-Datei erwähnten Ports müssen offen für Verbindungen von Rechnern sein, auf denen andere Container ausgeführt werden. So müssen beispielsweise als COREAPP_EXTERNAL_PORTS
in multiconnect-coreapp.yml
definierte Ports für eingehenden Traffic auf dem Host offen sein, der coreapp
-Container ausführt.
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 serverDu erhältst einige Ausgabeinformationen, während das Skript die Docker-Images herunterlädt und das Setup abschließt. Um die Container im Hintergrund auszuführen, verwende den folgenden
-d
-Parameter:
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
Überprüfe nach Abschluss dieser Schritte, ob die Container mit dem folgenden Befehl ausgeführt werden:
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
Das Ausführen mehrerer Instanzen desselben Dienstes (z. B. das Ausführen von 2 Coreapps auf demselben Host) funktioniert standardmäßig nicht, da ein Host-Port-Konflikt besteht. Um Portkonflikte zu vermeiden, musst du die entsprechende Service-YML-Datei, in diesem Fall multiconnect-coreapp.yml
, ändern, um wie folgt für jede Instanz andere Host-Ports zu öffnen:
ports:
- "HOST_PORT_RANGE:6250-6253"
Standardmäßig wird der Webapp-Container auf Port 9090 ausgeführt.
Die Datei multiconnect-compose.yml
umfasst Felder, die die Container-Versionen angeben. Beispiel:
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
Um ein Upgrade für eine Installation durchzuführen, ändere die Versionsnummern in der Datei 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
Starte dann die Docker-Container neu:
docker-compose -f multiconnect-compose.yml up
Die YAML-Dateien enthalten Felder für die Containerversionen. Beispiel:
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
Um ein Upgrade für eine Installation durchzuführen, ändere die Versionsnummern in den entsprechenden Dateien:
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
Starte dann die Docker-Container neu:
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
Wenn du über Medienvolumes aus einer früheren Installation verfügst, ersetze die folgende Volumedefinition in den YAML-Dateien:
volumes: whatsappData: driver: local whatsappMedia: driver: local
mit:
volumes: whatsappData: external: true whatsappMedia: external: true
Dies wird nur empfohlen, wenn ein vorhandenes Bind-Mount-Volume beibehalten werden soll.
Wenn du einen Hostpfad direkt in den Container mounten möchtest (d. h. an einem vorhandenen Speicherort auf deinem Host), ändere die Volumezeile im Dienstabschnitt so, dass auf den Hostpfad verwiesen wird.
wacore: volumes: /filepath/waent/data:/usr/local/waent/data /filepath/wamedia:/usr/local/wamedia
Dieser Vorgang muss für alle Rechner wiederholt werden, auf denen Nodes ausgeführt werden.
Wenn du deine Entwicklungsumgebung durch Entfernen aller Container zurücksetzen musst, führe den folgenden Befehl über das Verzeichnis aus, das die Datei multiconnect-compose.yml
enthält:
docker-compose -f multiconnect-compose.yml down
Um zusätzlich zu den Containern alle in der Datei multiconnect-compose.yml
definierten Volumes zu entfernen, führe down
mit dem Parameter -v
aus:
docker-compose -f multiconnect-compose.yml down -v
Wenn du deine Entwicklungsumgebung durch Entfernung aller Container zurücksetzen musst, führe auf jedem Server den folgenden Befehl in dem Verzeichnis mit der YAML-Datei aus:
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
Um zusätzlich zu den Containern alle in den YAML-Dateien definierten Volumes zu entfernen, führe down
mit dem Parameter -v
aus:
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
Führe den folgenden Befehl auf deinen Servern aus, um die Protokolle zur Fehlerbehebung abzurufen:
docker-compose logs > debug_output.txt