La solución estándar de cliente de la API de WhatsApp Business se ejecuta en un solo contenedor de Docker. Tener varios contenedores de Docker en ejecución genera problemas y puede provocar la prohibición temporal de la cuenta. En esta guía te orientaremos en la configuración de la alta disponibilidad, lo que te permitirá tener contenedores de Docker suspendidos por si el contenedor de Docker principal sufre una interrupción.
Esta solución de alta disponibilidad requiere una instalación de instancia única del cliente de la API de WhatsApp Business existente que se ejecute sobre esta. Si aún no has configurado el número de teléfono del cliente de la API de WhatsApp Business, revisa la documentación de instalación antes de continuar con la solución.
Un clúster de alta disponibilidad requiere, como mínimo, dos nodos maestros y dos nodos de aplicación principal, como se puede apreciar en el diagrama siguiente:
Se recomienda que todos los nodos se ejecuten en equipos o bastidores diferentes para evitar que errores de un equipo o bastidor afecten a varios nodos al mismo tiempo.
Al poner en marcha un clúster, todos los nodos maestros competirán para hacerse con el arrendamiento maestro y convertirse en el principal. Solo un nodo lo conseguirá y los demás serán maestros secundarios. Si existe un número N de nodos maestros en el clúster, habrá un maestro principal y N-1 maestros secundarios. El objeto maestro principal es responsable del registro, la actualización del esquema de base de datos, la transmisión de cambios de configuración, las estadísticas de la base de datos de informes, la administración de clústeres, etc. Si el objeto maestro principal muere y pierde el arrendamiento maestro, otros m=maestros secundarios competirán para ocupar la posición del objeto maestro principal.
Si un objeto maestro se convierte en principal, cargará primero la tabla del mapa de particiones de la base de datos para saber cuál es el nodo de aplicación principal primario actual. Si no existe ningún nodo de aplicación principal en el clúster, el objeto maestro principal promocionará un nodo de aplicación principal secundario en buen estado al nodo de aplicación primario y actualizará la tabla del mapa de particiones en la base de datos para que el nodo de aplicación web pueda buscar el nodo de aplicación principal al que enviará las solicitudes de API. De este modo, aunque todos los nodos maestros estén inactivos, se podrán atender las solicitudes de API en los nodos de aplicación principal para lograr una alta disponibilidad.
Cuando un nodo de aplicación principal se inicia, se ejecuta como un nodo de aplicación principal secundario hasta que el objeto maestro principal lo promociona para que sea el nodo de aplicación principal primario que se conectará al servidor de WhatsApp. Después de eso, será responsable de gestionar las solicitudes de la API.
Cada uno de los nodos de aplicación principal actualizará la base de datos cada minuto para reclamar su ejecución. El objeto maestro principal comprobará la base de datos regularmente para detectar nodos de aplicación principal en mal estado. Si un nodo de aplicación principal primario no actualiza la base de datos durante más de 2 minutos, el objeto maestro principal considera que está en mal estado y promociona otros nodos de aplicación principal para que sean el primario. De este modo, el tiempo de inactividad es de unos 2 minutos.
Si un clúster tiene más de un objeto maestro en ejecución, la supervisión basada en latidos detecta errores de nodos más rápido que la supervisión basada en base de datos. En la supervisión basada en latidos, todos los maestros son responsables de supervisar los nodos de aplicación principal, para lo cual deben enviarles latidos cada 5 segundos (configurado mediante heartbeat_interval
). Si un nodo de aplicación principal primario no ha respondido al maestro principal y a un maestro secundario en 30 segundos (configurado mediante unhealthy_interval
), se considera en mal estado. En este caso, el maestro principal promocionará un nodo de aplicación principal secundario en buen estado para que sea el nodo de aplicación principal primario. De este modo, el tiempo de inactividad es de unos 30 segundos de forma predeterminada. Puedes reducir el valor de unhealthy_interval
si prefieres un tiempo de inactividad menor. Consulta la documentación de configuración para ver cargas útiles de ejemplo.
En un clúster de alta disponibilidad, existen tres tipos de nodos: aplicación web, maestro y aplicación principal. Se pueden iniciar por separado en máquinas distintas, pero deben estar en la misma red para poder comunicarse entre sí.
Un nodo de la aplicación web es el responsable de gestionar el tráfico de la API como el contenedor de la aplicación web original. Un nodo de la aplicación principal es el responsable de gestionar el tráfico de mensajería de y hacia WhatsApp. Finalmente, un nodo maestro es el responsable de supervisar los nodos de la aplicación principal del clúster, de modo que, si uno de los nodos de la aplicación principal falla, se redirija el tráfico a otro nodo de la aplicación principal y, así, conseguir una alta disponibilidad. Puede haber varios nodos de aplicación web, aplicación principal y maestros en el clúster.
Ya no se hace referencia a los nodos activos como nodos esclavos. Ahora se llaman nodos de la aplicación principal.
Nota: En la mayoría de los casos, para los entornos de producción, la base de datos debe ejecutarse en un servidor físico aparte desde los contenedores de aplicación principal y aplicación web. Para conseguir alta disponibilidad real, es recomendable ejecutar los contenedores maestros, de aplicación web y de aplicación principal en distintas máquinas físicas.
Si no te interesan los mensajes multimedia, puedes omitir este paso.
Para admitir el envío y recepción de mensajes multimedia, es necesario configurar un sistema de archivos NFS y montarlo en un directorio local en todos los nodos de la aplicación web, la aplicación principal y objetos maestros. Asegúrate de que el directorio compartido tenga permisos de lectura/escritura.
mkdir new-local-directory mount -t nfs nfs_server_IP_addr:/share_directory new-local-directory
Esta guía requiere Docker, una plataforma de contenedor que te permite ejecutar el cliente de la API de WhatsApp Business. Docker Compose también es necesario. Docker Compose se incluye con Docker para macOS y Windows, pero requiere una instalación independiente en Linux.
multiconnect-compose.yml
y db.env
: WhatsApp_Configuration_Files.zip.
db.env
para que reflejen tu configuración de MySQL. Si no tienes MySQL instalado, los archivos multiconnect-compose.yml
y db.env
tienen una configuración predeterminada para mostrar una instancia en un contenedor local.docker-compose -f your-single-connect-yml-filename stop
docker-compose -f multiconnect-compose.yml upObtendrás alguna salida mientras el script descarga las imágenes de Docker y lo configura todo. Para ejecutar los contenedores en segundo plano, utiliza el parámetro
-d
:
docker-compose -f multiconnect-compose.yml up -d
Una vez completados estos pasos, asegúrate de que todos los contenedores se ejecuten mediante el comando siguiente:
docker-compose ps
De forma predeterminada, el contenedor de la aplicación web se ejecutará en el puerto 9090.
multiconnect-coreapp.yml
, multiconnect-master.yml
, multiconnect-webapp.yml
y db.env
: WhatsApp_Configuration_Files.zip. Guarda cada uno de estos archivos en el servidor respectivo.
db.env
para que reflejen tu configuración de MySQL.docker-compose -f your-single-connect-yml-filename stop
La variable de entorno EXTERNAL_HOSTNAME debería ser una dirección IP o un nombre de host que sea accesible desde las máquinas que ejecutan otros contenedores. Los puertos expuestos en un archivo YML de servicio deben estar abiertos a conexiones de máquinas que ejecutan otros contenedores. Por ejemplo, los puertos definidos como COREAPP_EXTERNAL_PORTS
en multiconnect-coreapp.yml
deben estar abiertos para el tráfico entrante en el host que ejecuta los contenedores de 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 serverObtendrás alguna salida mientras el script descarga las imágenes de Docker y lo configura todo. Para ejecutar los contenedores en segundo plano, utiliza el parámetro
-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 vez completados estos pasos, asegúrate de que todos los contenedores se ejecuten mediante el comando siguiente:
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
De forma predeterminada, no podrás ejecutar varias instancias del mismo servicio (por ejemplo, 2 aplicaciones principales en el mismo host) debido a un conflicto de puertos del host. Para evitar un conflicto de puertos, debes modificar el archivo YML de servicio respectivo, en este caso multiconnect-coreapp.yml
, para mostrar distintos puertos de host para cada instancia como se muestra a continuación:
ports:
- "HOST_PORT_RANGE:6250-6253"
De forma predeterminada, el contenedor de la aplicación web se ejecutará en el puerto 9090.
El archivo multiconnect-compose.yml
tiene campos que indican las versiones del contenedor. Por ejemplo:
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
Para actualizar una instalación, cambia los números de versión en el archivo 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
A continuación, reinicia los contenedores de Docker:
docker-compose -f multiconnect-compose.yml up
Los archivos YAML tienen campos que indican las versiones de los contenedores. Por ejemplo:
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
Para actualizar una instalación, cambia los números de versión en los archivos correspondientes:
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
A continuación, reinicia los contenedores de 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
Si tienes volúmenes multimedia de una instalación anterior, reemplaza la definición de volumen siguiente en los archivos YAML:
volumes: whatsappData: driver: local whatsappMedia: driver: local
por:
volumes: whatsappData: external: true whatsappMedia: external: true
Solo se recomienda esta opción si quieres mantener un volumen de montaje de enlace existente.
Si quieres montar una ruta de host directamente (una ubicación existente del host) en el contenedor, puedes hacerlo cambiando la línea del volumen dentro de la sección del servicio para que apunte a la ruta del host.
wacore: volumes: /filepath/waent/data:/usr/local/waent/data /filepath/wamedia:/usr/local/wamedia
Tendrás que repetirlo para todas las máquinas en las que tengas nodos en ejecución.
Si necesitas restablecer tu entorno de desarrollo mediante la eliminación de todos los contenedores, ejecuta el siguiente comando desde el directorio que contiene el archivo multiconnect-compose.yml
:
docker-compose -f multiconnect-compose.yml down
Para deshacerte de todos los volúmenes definidos en el archivo multiconnect-compose.yml
, además de los contenedores, ejecuta down
con el parámetro -v
:
docker-compose -f multiconnect-compose.yml down -v
Si necesitas restablecer tu entorno de desarrollo mediante la eliminación de todos los contenedores, ejecuta el siguiente comando desde el directorio que contiene el archivo YAML en cada servidor:
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
Para deshacerte de todos los volúmenes definidos en los archivos YAML, además de los contenedores, ejecuta down
con el parámetro -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
Para obtener registros de solución de problemas, ejecuta este comando en tus servidores:
docker-compose logs > debug_output.txt