设置高可用性

标准 WhatsApp Business API 客户端解决方案在单个 Docker 容器上运行。运行多个 Docker 容器会造成问题,并导致您的帐户遭到暂时禁用。本指南会向您介绍如何设置高可用性,这样您可以让 Docker 容器处于待命状态,以防主 Docker 容器停止工作。

如要在现有 WhatsApp Business API 客户端上运行此高可用性解决方案,则需在此客户端上安装单实例。如果您尚未设置 WhatsApp Business API 客户端的电话号码,请查看安装文档后再继续执行此解决方案。

概览

如下图所示,高可用性集群需要至少两个 Master 节点和两个核心应用节点:

高可用性集群

建议所有节点都在不同的机器/机架上运行,以避免单个机器/机架故障同时影响多个节点。

启动

当集群启动时,所有 Master 节点都会争相抢占主租约,以成为主 Master 节点。只有一个节点会成功,其他节点会成为辅助 Master 节点。如果集群中有 N 个 Master 节点,则会有一个主 Master 节点和 N-1 个辅助 Master 节点。主 Master 节点负责注册、数据库架构升级、配置更改群发、报告数据库状态和集群管理等。如果主 Master 节点出现故障并失去主租约,则其他辅助 m=Master 会竞争接替主 Master 的位置。

当某个 Master 成为主 Master 时,它首先会从数据库加载分片映射表,以了解哪个应用是当前的主核心应用。如果集群中没有主核心应用,则主 Master 节点会将某个状态良好的辅助核心应用提升为主核心应用,并在数据库中更新分片映射表,以便网页应用可以查找要向哪个核心应用节点发送 API 请求。这样,即便所有 Master 节点都出现故障,它仍然可以在核心应用节点中提供 API 请求,从而实现高可用性。

当核心应用节点启动时,它会以辅助核心应用的身份运行,直到主 Master 将其提升为主核心应用,连接到 WhatsApp 服务器。之后,它会负责处理 API 请求。

基于数据库的监控

每个核心应用节点每分钟更新一次数据库,以声明其活跃性。主 Master 会定期检查数据库,以检测状态不佳的核心应用节点。如果主核心应用节点未在 2 分钟内更新数据库,则主 Master 会视其为状态不佳,并会将其他核心应用节点提升为主核心应用节点。这样,故障时间大约为 2 分钟。

基于心跳的监控

如果一个集群有多个正在运行的 Master 节点,则基于心跳的监控要比基于数据库的监控更快监测到节点故障。在基于心跳的监控中,所有 Master 都负责监控核心应用节点,方法是每隔 5 秒向核心应用节点发送一次心跳消息(由 heartbeat_interval 配置)。如果主核心应用在 30 秒内未响应主 Master 和一个辅助 Master(由 unhealthy_interval 配置),则主 Master 会视其为状态不佳,并会将某个状态良好的辅助核心应用提升为主核心应用。这样,默认情况下的故障时间大约为 30 秒。如果想要缩短故障时间,您可以降低 unhealthy_interval 的值。请查看设置文档,了解示例负载。

初始设置

高可用性集群中存在三种节点:网页应用、Master 和核心应用。您可以在不同的机器上分别启用这三种节点,但它们必须处于同一网络,以便能够相互通信。

网页应用节点负责处理类似原始网页应用容器的 API 流量。核心应用节点负责处理发送到和来自 WhatsApp 的消息流量。最后,Master 节点负责监控集群中的核心应用节点,因此如果某个核心应用节点故障,Master 节点会将流量重新定向到另一个核心应用节点,以确保高可用性。集群中可能存在多个网页应用节点、核心应用节点和 Master 节点。

我们不再将主动节点称为从属节点,而是将其称为核心应用节点。

注意:对于生产环境,在大多数情况下,您应该在与核心应用和网页应用容器分离的物理服务器上运行数据库。为实现真正的高可用性,我们建议您在不同的物理机器上运行 Master、网页应用和核心应用容器。

为媒体消息设置共享文件系统

如果媒体消息对您并不重要,请跳过此步骤。

要支持发送/接收媒体消息,需要设置一个 NFS 文件系统,然后将该系统挂载到所有网页应用、Master 和核心应用节点上的本地目录。请确保在共享目录上授予读取/写入权限。

NFS 挂载命令示例:

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

使用 Docker Compose 进行安装

本指南需要用到 Docker,这是一个支持您运行 WhatsApp Business API 客户端的容器平台。另外,还需要 Docker Compose。Docker Compose 会与 macOS 版 Docker 及 Windows 版 Docker 捆绑安装,但在 Linux 系统上需要单独安装。

使用单个服务器进行开发者设置

  1. 在您的系统上安装 Docker。
  2. 如果 Docker Compose 未与 Docker 捆绑安装,请自行安装
  3. 下载 multiconnect-compose.ymldb.env 配置文件:WhatsApp_Configuration_Files.zip
  4. 打开控制台并导航到保存已下载文件的目录。
  5. 如果您正在运行 MySQL 安装程序,请更改 db.env 文件中的值,以反映您的 MySQL 配置。如果您尚未安装 MySQL,则 multiconnect-compose.ymldb.env 文件的其中一个默认配置可以在本地容器中显示实例。
  6. 在为实现高可用性启用多个容器前,请确保没有正在运行的单一连接容器:
      docker-compose -f your-single-connect-yml-filename stop
    
  7. 在控制台运行以下命令:
    docker-compose -f multiconnect-compose.yml up
    当脚本下载 Docker 图像和设置所有项目时,您会获得一些输出信息。如要在后台运行容器,需要使用 -d 参数:
    docker-compose -f multiconnect-compose.yml up -d

完成这些步骤后,请确保容器正在运行以下命令:

docker-compose ps

默认情况下,网页应用容器会在 9090 端口上运行。

使用多个服务器为每个容器进行生产环境设置

  1. 在您的系统上安装 Docker。
  2. 如果 Docker Compose 未与 Docker 捆绑安装,请自行安装
  3. 下载 multiconnect-coreapp.ymlmulticonnect-master.ymlmulticonnect-webapp.ymldb.env 配置文件:WhatsApp_Configuration_Files.zip,然后将每个文件保存到其各自的服务器。
  4. 在每个服务器上,打开控制台并导航到保存已下载文件的目录。
  5. 在生产设置中,我们强烈建议您使用独立的 MySQL 实例。在您获得该实例后,请更改 db.env 文件中的值,以反映您的 MySQL 配置。
  6. 在为实现高可用性启用多个容器前,请确保没有正在运行的单一连接容器:
    docker-compose -f your-single-connect-yml-filename stop
    
  7. 在控制台为每台相应的服务器运行以下命令:

    环境变量 EXTERNAL_HOSTNAME 应为可以从正在运行其他容器的服务器上访问的 IP 地址或主机名。服务 YML 文件中使用的端口应该对正在运行其他容器的机器上的连接开放。例如,在 multiconnect-coreapp.yml 中定义为 COREAPP_EXTERNAL_PORTS 的端口需要对运行 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
    当脚本下载 Docker 图像和设置所有项目时,您会获得一些输出信息。如要在后台运行容器,需要使用 -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

完成这些步骤后,请确保容器正在运行以下命令:

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

由于主机端口冲突,运行同一服务的多个实例(例如,在同一主机上运行 2 个核心应用)默认情况下将无法正常运行。要避免端口冲突,您需要修改相应的服务 YML 文件(在本例中,需要修改的是 multiconnect-coreapp.yml),以按照下列指令为每个实例开放不同的主机端口:

ports:
- "HOST_PORT_RANGE:6250-6253"

默认情况下,网页应用容器会在 9090 端口上运行。

升级

使用单个服务器进行开发者设置

multiconnect-compose.yml 文件有提示容器版本的字段。例如:

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

要升级安装程序,请更改 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

然后,重启 Docker 容器:

docker-compose -f multiconnect-compose.yml up

使用多个服务器为每个容器进行生产环境设置

YAML 文件有提示容器版本的字段。例如:

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

要升级安装程序,请更改相应文件中的版本号:

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

然后,重启 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

附加现有的卷

如果您有之前安装操作中的媒体卷,请在 YAML 文件中替换以下卷定义:

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

替换为:

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

绑定挂载

仅当您要维护现有绑定挂载卷时,才建议进行此操作。

如果想要直接将主机路径(您主机上的现有位置)挂载到容器中,您可以将服务区段内的卷行更改为指向主机路径。

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

卸载

使用单个服务器进行开发者设置

您需要为所有正在运行节点的服务器重复此操作。

如果您需要通过移除所有容器来重置开发环境,请在包含 multiconnect-compose.yml 文件的目录中运行以下命令:

docker-compose -f multiconnect-compose.yml down

如果除容器外还要移除 multiconnect-compose.yml 文件中定义的所有卷,请在运行 down 时加入 -v 参数:

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

使用多个服务器为每个容器进行生产环境设置

如果您需要通过移除所有容器来重置开发环境,请在每个服务器上从包含 YAML 文件的目录中运行以下命令:

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

如果除容器外还要移除 YAML 文件中定义的所有卷,请在运行 down 时加入 -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

问题解决日志

如要获取问题解决日志,需要在您的服务器上运行以下命令:

  docker-compose logs > debug_output.txt