La solución estándar del cliente de la API de WhatsApp Business funciona en un único contenedor de Docker. Si se ejecutan varios contenedores de Docker, se generarán problemas que provocarán que se prohíba la cuenta de manera temporal. Esta guía te orientará en la configuración de alta disponibilidad, que permite tener contenedores de Docker en espera en caso de que el contenedor de Docker principal quede inactivo.
Esta solución de alta disponibilidad requiere que la instalación de instancia única existente del cliente de la API de WhatsApp Business se ejecute en ella. Si no configuraste aún el número de teléfono del cliente de la API de WhatsApp Business, consulta la documentación de instalación antes de intentar poner en práctica esta solución.
Un clúster de alta disponibilidad requiere al menos dos nodos maestros y dos nodos de la aplicación principal, como se muestra en el siguiente diagrama:
Se recomienda que todos los nodos se ejecuten en máquinas o racks diferentes para evitar que, si se produce una falla en una sola máquina o rack, esto no afecte a varios nodos al mismo tiempo.
Cuando se inicia un clúster, todos los nodos maestros compiten para obtener la asignación principal y convertirse en primarios. Solo un nodo lo logrará, y los demás se volverán nodos maestros secundarios. Si el clúster posee un número N de nodos maestros, habrá un nodo maestro primario y N-1 nodos maestros secundarios. El nodo maestro primario es responsable de las acciones de registro, actualización de esquema de base de datos, transmisión de cambios de configuración, estadísticas de bases de datos de informes, administración de clústeres, etc. Si el nodo maestro muere y pierde la asignación principal, otros m=nodos maestros secundarios competirán para asumir el lugar de nodo maestro primario.
Cuando un nodo maestro se convierte en primario, en primer lugar cargará la tabla del mapa de fragmentos de la base de datos para aprender cuál es la aplicación principal primaria actual. Si en el clúster no hay una aplicación principal primaria, el nodo maestro primario promoverá una aplicación principal secundaria saludable al lugar de aplicación principal primaria y actualizará la tabla del mapa de fragmentos en la base de datos, de modo que la aplicación web podrá buscar a qué nodo de la aplicación principal debe enviar las solicitudes de la API. De esta forma, incluso si fallan todos los nodos maestros, aún se podrían mostrar las solicitudes de la API en los nodos de la aplicación principal para lograr alta disponibilidad.
Cuando se inicia un nodo de la aplicación principal, se ejecuta como aplicación principal secundaria hasta que el nodo maestro primario la promueve a aplicación principal primaria para conectarse con el servidor de WhatsApp. Después de eso, es responsable de manejar las solicitudes de la API.
Cada nodo de la aplicación principal actualizará la base de datos a cada minuto para mostrarse activo. El nodo maestro primario verificará periódicamente la base de datos para detectar nodos de la aplicación principal no saludables. Si un nodo de la aplicación principal primaria no actualizó la base de datos por más de dos minutos, el nodo maestro primario considerará que no es saludable y promoverá al lugar de primarios a otros nodos de la aplicación principal. De esta manera, el tiempo de inactividad será de aproximadamente dos minutos.
Si en un clúster se ejecuta más de un nodo maestro, la supervisión basada en latidos detecta las fallas de los nodos más rápidamente que la supervisión basada en base de datos. En la supervisión basada en latidos, todos los nodos maestros son responsables de supervisar a los nodos de la aplicación principal enviándoles latidos cada cinco segundos (se configura en heartbeat_interval
). Si una aplicación principal primaria no le respondió al nodo maestro primario y a un nodo maestro secundario durante 30 segundos (se configura en unhealthy_interval
), se considera no saludable. En este caso, el nodo maestro primario promoverá una aplicación principal secundaria saludable a aplicación principal primaria. De esta manera, y de forma predeterminada, el tiempo de inactividad será de aproximadamente 30 segundos. Si prefieres un tiempo de inactividad menor, puedes reducir el valor unhealthy_interval
. Consulta la documentación sobre configuración para obtener ejemplos de cargas.
En un clúster de alta disponibilidad, hay tres tipos de nodos: app web, maestro y app principal. Pueden iniciarse por separado en diferentes máquinas, pero deben estar en la misma red para que se puedan comunicar entre sí.
Un nodo de app web es responsable de tratar el tráfico de la API como el contenedor de app web original. Un nodo de aplicación principal es responsable de manejar el tráfico de mensajes hacia y desde WhatsApp. Por último, un nodo maestro es responsable de supervisar nodos de aplicación principal en el clúster, de modo que si un nodo de aplicación principal queda inactivo, el tráfico se redirigirá a otro nodo de aplicación principal para proporcionar alta disponibilidad. Puede haber varios nodos de app web, nodos de app principal y nodos maestros en el clúster.
No se refieren más a los nodos activos como "nodos esclavos". Se los denomina "nodos de app principal".
Nota: En la mayoría de los casos, debe ejecutarse la base de datos en un servidor físico separado de los contenedores de la aplicación principal y de la aplicación web para los entornos de producción. Para lograr una alta disponibilidad real, se recomienda ejecutar los contenedores maestros, de app web y de app principal en diferentes máquinas físicas.
Si no te interesan los mensajes con contenido multimedia, omite este paso.
Con el fin de lograr la compatibilidad de enviar y recibir mensajes con contenido multimedia, es necesario configurar un sistema de archivos NFS y montarlo en un directorio local en todos los nodos de app web, maestros y de app principal. Asegúrate de que se hayan otorgado permisos de lectura y escritura en el directorio compartido.
mkdir new-local-directory mount -t nfs nfs_server_IP_addr:/share_directory new-local-directory
Para usar esta guía, debes tener Docker, una plataforma de contenedor que permite ejecutar el cliente de la API de WhatsApp Business. También debes tener Docker Compose. Docker Compose ya viene incorporado en Docker para macOS y Windows, pero debe instalarse por separado en Linux.
multiconnect-compose.yml
y db.env
: Archivos_de_configuración_de_WhatsApp.zip.
db.env
para que coincidan con tu configuración de MySQL. En caso contrario, los archivos multiconnect-compose.yml
y db.env
tienen una configuración predeterminada que genera una instancia en un contenedor local.docker-compose -f your-single-connect-yml-filename stop
docker-compose -f multiconnect-compose.yml upRecibirás salidas mientras el script descargue las imágenes de Docker y configure todo. Para ejecutar los contenedores en segundo plano, utiliza el parámetro
-d
:
docker-compose -f multiconnect-compose.yml up -d
Cuando hayas terminado, usa el siguiente comando para verificar que los contenedores estén funcionando:
docker-compose ps
De manera 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 y guárdalos en los servidores respectivos.
db.env
para que coincidan con tu configuración de MySQL.docker-compose -f your-single-connect-yml-filename stop
La variable de entorno EXTERNAL_HOSTNAME debe ser una dirección IP o nombre de host que sea accesible desde las máquinas que ejecutan otros contenedores. Los puertos expuestos en un archivo YML de servicio deberían estar abiertos a las conexiones de las máquinas que ejecutan otros contenedores. Por ejemplo, los puertos definidos como COREAPP_EXTERNAL_PORTS
en multiconnect-coreapp.yml
requieren estar abiertos al tráfico de entrada en el host que ejecuta los contenedores 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 serverRecibirás salidas mientras el script descargue las imágenes de Docker y configure 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
Cuando hayas terminado, usa el siguiente comando para verificar que los contenedores estén funcionando:
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
Si se ejecutan instancias múltiples del mismo servicio (por ejemplo, ejecutar 2 app principales en el mismo host), no funcionará de forma predeterminada porque existe un conflicto con el puerto del host. Para evitar este conflicto, es necesario que modifiques el archivo YML de servicio correspondiente, en este caso multiconnect-coreapp.yml
, para exponer los diferentes puertos host para cada instancia como se muestra a continuación:
ports:
- "HOST_PORT_RANGE:6250-6253"
De manera 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 de los contenedores. 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 versiones del 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
Luego, 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 versiones de 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
Luego, 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 de contenido multimedia de una instalación anterior, reemplaza la definición del siguiente volumen en los archivos YAML:
volumes: whatsappData: driver: local whatsappMedia: driver: local
por:
volumes: whatsappData: external: true whatsappMedia: external: true
Solo se recomienda si deseas mantener el volumen de montaje de enlace actual.
Si quieres montar directamente una ruta de acceso del host (una ubicación existente en tu host) en el contenedor, puedes hacerlo cambiando la línea del volumen en el interior de la sección de servicio para que se dirija a la ruta de acceso del host.
wacore: volumes: /filepath/waent/data:/usr/local/waent/data /filepath/wamedia:/usr/local/wamedia
Debes repetirlo para todas las máquinas en las que ejecutes nodos.
Si debes eliminar todos los contenedores para restablecer el entorno de desarrollo, ejecuta el siguiente comando desde el directorio que contiene el archivo multiconnect-compose.yml
:
docker-compose -f multiconnect-compose.yml down
Si, además de los contenedores, quieres eliminar todos los volúmenes definidos en el archivo multiconnect-compose.yml
, ejecuta down
con el parámetro -v
:
docker-compose -f multiconnect-compose.yml down -v
Si debes eliminar todos los contenedores para restablecer el entorno de desarrollo, 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
Si, además de los contenedores, quieres eliminar todos los volúmenes definidos en los archivos YAML, 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
Si deseas obtener registros para solucionar problemas, ejecuta el siguiente comando en los servidores:
docker-compose logs > debug_output.txt