技術系(Tips)
PR

【解決】Google Play Billing で 409 エラー!acknowledge 失敗を防ぐ AWS SQS 活用術

saratogax
記事内に商品プロモーションを含む場合があります

Google Play Billing を導入している Android アプリのバックエンド運用において、最近まで安定していた acknowledge(承認)処理で、突如として 409 Conflict エラーが目立つようになりました。

今回は、その原因の考察と、AWS SQS を活用してスマートに解決した方法をシェアします。

Google Play Billing で発生した 409 エラーの正体

今回遭遇したエラーメッセージは以下の通りです。

The operation could not be performed since the object was already in the process of being updated.

ユーザーがサブスクリプションを購入し、バックエンド側で purchaseToken のステータスが ACTIVE であることを確認してから acknowledge を実行しているにもかかわらず、Google の API から「オブジェクトは更新処理中のため操作を完了できません」と突き返されてしまう現象です。

以前はほとんど発生していなかったのですが、システムのレスポンス向上や Google 側の内部処理の変化により、「早すぎる承認リクエスト」がエラーを引き起こすようになったと考えられます。

なぜリクエストが 1 つでも 409 が発生するのか?

一見すると、自分のサーバーから二重にリクエストを送っていない限り 409(競合)は起きないように思えます。しかし、分散システムである Google Play の裏側では以下のような挙動が発生しています(してそうです)

1. Google 内部ステータスの伝搬ラグ

ユーザーが端末で購入を完了した直後、Google のサーバー内では購入情報の確定や各ノードへのデータ同期が行われます。

この「書き込み処理」が終わる前にバックエンドから acknowledge を叩くと、Google 内部でロックの競合が発生し、409 が返されます。

2. インフラの高速化による「デッドヒート」

サーバーのスペック向上やネットワークの低遅延化により、アプリからの通知を受けてバックエンドが処理を開始するまでの時間が短縮されました。

その結果、Google 側の準備が整う前にこちらがリクエストを送り届けてしまう、皮肉な「早すぎることによる弊害」が起きていたのです。

既存の構成:AWS SQS によるリトライ

私の運用環境では、Google Play からの購入通知やアプリからのリクエストをトリガーに、AWS SQS(Simple Queue Service) を介して acknowledge 処理を実行しています。

  • これまでの仕組み: 409 エラーが発生した場合、メッセージを削除せずに終了。
  • リトライ戦略: SQS の「可視性タイムアウト(Visibility Timeout)」を 2 分 に設定していたため、エラー発生から 2 分後に自動的に再実行される。

この仕組みにより、2 分後のリトライ時には Google 側の更新も完了しており、実運用上の不整合(承認漏れ)は防げていました。

しかし、エラーログに 409 が残るため、運用監視においてノイズになっていたのが課題でした。

解決策:SQS の「配信遅延(DelaySeconds)」を設定

「早すぎて失敗するなら、少しだけ待ってから実行すればいい」という結論に至り、SQS の配信遅延(DelaySeconds) を活用することにしました。

10 秒のディレイがもたらす安定感

当初は 5 秒程度の待機も検討しましたが、ネットワークの揺らぎや Google 側の高負荷時を考慮し、10 秒 のディレイを設定しました。

  1. アプリから購入通知を受信
  2. 購入トークンからサブスクリプションの状態を確認
  3. SQS キューにメッセージを投入(ここで 10 秒の配信遅延を設定)
  4. 10 秒後、キュートリガーで acknowledge を実行

この 10 秒という「タメ」を作ることで、Google 側の内部処理が完全に落ち着いた状態で承認リクエストを送ることが可能になります。

設定後の効果

配信遅延を導入してから数時間、これまで頻発していた 409 エラーはピタリと止まりました。

もし仮に 10 秒で解決しないほど Google 側が混雑していたとしても、既存の「2 分後の可視性タイムアウトによるリトライ」がセーフティネットとして機能するため、非常に堅牢な 2 段構えの構成となっています。

まとめ:Google Play Billing 運用における「待ち」の重要性

分散システムとの API 連携において、「即座に実行する」ことが必ずしも正解ではないという好例でした。

  • 409 エラーは「早すぎる」のサイン
  • 配信遅延(DelaySeconds)で 10 秒ほど待機させるのがベストプラクティス
  • リトライ機構(可視性タイムアウト)を組み合わせて二段構えにする

同じようなエラーログに悩まされている方は、ぜひメッセージの投入タイミングに少しの「余裕」を持たせてみてください。

ABOUT ME
saratoga
saratoga
フリーランスエンジニア
仕事にも趣味にも IT を駆使するフリーランスエンジニア。技術的な TIPS や日々の生活の中で深堀りしてみたくなったことを備忘録として残していきます。
記事URLをコピーしました