標準のWhatsApp Business APIクライアントのソリューションは、単一のDockerコンテナ上で動作します。複数のDockerコンテナを実行すると、問題が発生してアカウントが一時的に使用禁止になります。このガイドでは、高可用性を設定することにより、主要Dockerコンテナがダウンした場合に備えて複数のDockerコンテナをスタンバイさせておく方法について説明します。
この高可用性ソリューションでは、既存のWhatsApp Business APIクライアントの単一インスタンスインストールを追加実行する必要があります。WhatsApp Business APIクライアントの電話番号をまだ設定していない場合は、このソリューションに進む前に、インストールに関するドキュメントを確認してください。
ハイアベイラビリティクラスタを構成するには、次の図に示すようにマスターノード2台以上、コアアプリノード2台以上が必要です。
ノードはすべて異なるマシンまたはラックで運用することが推奨されます。1台のマシンまたはラックで障害が発生した場合、同時に複数のノードに影響が及ぶのを避けるためです。
クラスタが起動すると、すべてのマスターノードがプライマリマスターになるためのマスターリースを獲得しようとします。1台のみがマスターリースを獲得し、残りはセカンダリマスターとなります。クラスタ内のマスターノードの数をNとしたとき、プライマリマスターは1台、セカンダリマスターはN-1台となります。プライマリマスターは、登録、データベーススキーマのアップグレード、構成変更の配信開始、データベース統計のレポーティング、クラスタ管理などの役割を担います。プライマリマスターがダウンしてマスターリースを失うと、その他のセカンダリm = マスターがプライマリマスターの立場を引き継ごうとします。
そのうちの1台がプライマリマスターになると、最初にデータベースからシャードマップテーブルを読み込んで現在のプライマリコアアプリがどれかを学習します。クラスタ内に1台もプライマリコアアプリがない場合、ウェブアプリがどのコアアプリノードにAPIリクエストを送信すべきか検索できるよう、プライマリマスターが正常に動作しているセカンダリコアアプリ1台をプライマリコアアプリにプロモートし、データベースのシャードマップテーブルをアップデートします。これにより、たとえすべてのマスターがダウンしてもコアアプリノードでAPIリクエストを処理し、高可用性を実現できます。
コアアプリノードは起動するとセカンダリコアアプリとして動作し、プライマリマスターによってプロモートされて初めてWhatsAppサーバーに接続するためのプライマリコアアプリとなります。プライマリコアアプリになると、APIリクエスト処理の役割を担います。
各コアアプリノードは毎分データベースをアップデートすることで動作中であることを示します。プライマリマスターは定期的にデータベースをチェックして障害が発生しているコアアプリノードを検出します。プライマリコアアプリによりデータベースのアップデートが行われない時間が2分を超えた場合、プライマリマスターは障害が発生していると見なし、他のコアアプリノードをプライマリにプロモートします。これにより、ダウンタイムは約2分となります。
クラスタ内に動作中のマスターが複数ある場合、ハートビートに基づくモニタリングにより、データベースに基づくモニタリングよりも短時間でノード障害を検出できます。ハートビートに基づくモニタリングでは、すべてのマスターがコアアプリノードに5秒間隔で(heartbeat_interval
により設定)ハートビートを送信することでコアアプリノードをモニタリングします。プライマリコアアプリからプライマリマスターとセカンダリマスター1台への応答が30秒間(unhealthy_interval
により設定)途絶えた場合、障害が発生していると見なし、プライマリマスターは正常に動作しているセカンダリコアアプリ1台をプライマリコアアプリにプロモートします。これにより、ダウンタイムはデフォルトで約30秒となります。ダウンタイムの短縮が望ましい場合には、unhealthy_interval
値を下げることができます。ペイロードの例については、設定のドキュメントをご覧ください。
ハイアベイラビリティクラスタには、Webapp、Master、Coreappの3種類のノードがあります。それらは、別々のマシンで別個に起動可能ですが、互いにやり取りするためには同じネットワーク内になければなりません。
Webappノードは、オリジナルのWebappコンテナなどのAPIトラフィックの処理を担当します。Coreappノードは、WhatsAppとの間のメッセージングトラフィックの処理を担当します。最後のMasterノードは、クラスタ内のCoreappノードのモニタリングを担当します。あるCoreappノードが死んだら、トラフィックを別のCoreappノードにリダイレクトして高可用性を確保します。クラスタ内に複数のWebappノード、Coreappノード、Masterノードが存在する場合もあります。
アクティブノードを、スレーブノードとは呼ばなくなりました。それらはCoreappノードと呼ばれます。
注: 多くの場合、本番環境では、CoreappコンテナやWebappコンテナとは別の物理サーバーでデータベースを稼働するべきです。真の高可用性実現のため、Master、Webapp、およびCoreappの各コンテナをそれぞれ別個の物理マシン上で実行することをおすすめします。
メディアメッセージを扱うことがない場合、この手順はスキップしてください。
メディアメッセージの送受信をサポートするためには、NFSファイルシステムを設定し、それをWebapp、Master、Coreappの各ノードのローカルディレクトリにマウントすることが必要です。その共有ディレクトリの読み取り/書き込みアクセス許可が付与されていることを確認してください。
mkdir new-local-directory mount -t nfs nfs_server_IP_addr:/share_directory new-local-directory
このガイドでは、WhatsApp Business APIクライアントを実行するためのコンテナプラットフォームとなるDockerが必要になります。さらに、Docker Composeも必要です。Docker Composeは、macOSやWindowsの場合はDockerとバンドルになっていますが、Linuxの場合は別途インストールする必要があります。
multiconnect-compose.yml
およびdb.env
の構成ファイルWhatsApp_Configuration_Files.zipをダウンロードします。
db.env
ファイルの値を変更します。MySQLをインストールしていない場合、multiconnect-compose.yml
ファイルとdb.env
ファイルはデフォルトの構成であり、ローカルコンテナでインスタンスを起動します。docker-compose -f your-single-connect-yml-filename stop
docker-compose -f multiconnect-compose.yml upスクリプトによってDockerイメージがダウンロードされすべてが設定されている間に、出力が得られます。コンテナをバックグラウンドで実行するには、
-d
パラメーターを指定します。
docker-compose -f multiconnect-compose.yml up -d
これらのステップを実行したら、以下のコマンドを使用してコンテナが実行されていることを確認します。
docker-compose ps
デフォルトでは、Webappコンテナはポート9090で実行されます。
multiconnect-coreapp.yml
、multiconnect-master.yml
、multiconnect-webapp.yml
、およびdb.env
構成ファイルであるWhatsApp_Configuration_Files.zipをダウンロードし、それぞれを対応するサーバーに保存します。
db.env
ファイルの値を変更します。docker-compose -f your-single-connect-yml-filename stop
環境変数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つのCoreappsが実行されている場合)、ホストポートの競合によりデフォルトのままでは動作しません。ポートの競合を回避するには、各サービスの YML ファイル(この場合はmulticonnect-coreapp.yml
)を変更して、インスタンスごとに異なるホストポートを次のように公開する必要があります。
ports:
- "HOST_PORT_RANGE:6250-6253"
デフォルトでは、Webappコンテナはポート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
ファイル内に定義されているすべてのボリュームも削除する場合は、-v
パラメーターを指定してdown
を実行します。
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ファイル内に定義されているすべてのボリュームも削除する場合は、-v
パラメーターを指定してdown
を実行します。
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