
通知の有効期限と速度制限はどのように動作しますか
BoltzEngine へのリクエストは、1秒あたりの通知速度を制御する機能と、通知の有効期限を設定することが可能です。gRPCの場合は、以下のフィールドが該当します。
フィールド名 | 意味 |
---|---|
Expiration | 通知の有効期限をUnix timeで設定する |
BandWidth | 1秒あたりの最大通知件数を調整する |
net/rpcをお使いの場合も、およそ同じ意味のフィールドが存在します。
BoltzEngineのスケジューラについて
前提として、BoltzEngineがどのようにクライアントからのリクエストを処理するか説明します。
gRPCでBoltzEngineのSend
メソッドを実行した場合、マスターノードは1回の呼び出しを1つのリクエストとして受け付けます。v3.1では、1つのリクエストで複数のプラットフォーム(APNs/FCM/WebPush/ADM)への通知を含めることが可能になっているため、リクエスト受信のタイミングで
- 必要なフィールドは設定されているか検証
- リクエストを個別のプラットフォーム単位に分割
- 通知対象端末が多い場合はさらに複数のリクエストへ分割
などを行い、マスターノード内部の通知キューへ登録します。全体としては下記のようになります。
通知キューに登録された、細分化されたリクエストは、有効期限に従って期限の近いものから順にスレーブノードへ渡され、最終的に端末へ通知が届きます。
各フィールドの動作
Expiration は有効期限を表し、通知キューから取り出した時点で期限を超えていた、または最初から期限切れだった場合はエラーをレスポンスで返します。通知キュー取り出しの時に有効だった場合は、そのままAPNs/FCMなどの通知サーバへ送られ、それぞれのプラットフォームで定義された動作を行います。例えばAPNsの場合は apns-expiration ヘッダに該当し、期限以内まではプラットフォーム側で端末へ再配送を行います。また、期限が0の場合は一度のみ通知を行い、再送しません。
スレーブノードへ処理が渡された後は Expiration の影響を受けません。そのため、各プラットフォームの通知サービスへ送信する前に期限が切れた場合は、少なくとも1度は通知を行います。ただし、リトライ回数は有効期限によって制御されるので、結果としてリトライは行いません。
BandWidth はBoltzEngineで通知件数の秒間最大速度を調整するフィールドです。複数のスレーブを使って分散通知する場合でも、BoltzEngineはリクエスト全体で最大速度を超えないように調整します。この値は最大速度のため、設定通りの通知を行うものではありません。また、細分化される前のリクエスト単位で制限を行うため、同時に複数のリクエストが行われた場合は、それぞれのリクエストは個別に制限を行います。例えば 秒間1万件 の通知が同時に2つ実行された場合、BoltzEngine全体では 秒間2万件 の速度で処理を行うことになります。
有効期限と速度制限を同時に設定した場合
有効期限付きの通知で速度制限を行なった場合、通知量によっては送り切るよりも前に期限が切れてしまうケースが発生します。例えば 秒間10件 で3万デバイスへ通知を行うと、全体で最低でも1000秒が必要になりますが、期限がこれよりも短い場合は途中で有効期限が切れてしまうでしょう。
上記以外にも、BoltzEngineスレーブは1台あたりの最大同時リクエスト数(boltz slave -n
オプション)を定めているため、マスターノードはスレーブがすべて使われている場合、空くまで待ってから分散することもあります。この場合も同様に、分散処理をする前に有効期限が切れてしまう可能性があります。
これらを解決するため、BoltzEngineは有効期限に到達するまでリクエストを通知キューの中に保留し、実行可能になった時点で通知キューから取り出します。従って、最悪のケースでは期限に到達するまでずっとリクエストが完了しない状況が発生しますので、クライアント側のタイムアウト設定は、十分な値を設定しなければなりません。