Uniforceのインフラ担当のニシです。

この記事を書いている頃は、おいももなかと焼いもアイスにハマっています(甘い飲み物、食べ物、好き🤤)。

さて、今回はAPI Gatewayの統合のタイムアウト制限を緩和したときにハマったときのお話です。

API Gatewayの統合のタイムアウト制限

つい最近までAPI Gatewayの統合のタイムアウトは 50ミリ秒~29秒でした。

この制限により29秒を超える同期的な処理を実行することは困難でした。

29秒の壁を攻略するために非同期で処理を実行し、実行が完了しているかをポーリングして確認する方法を取ることも多かったのではないかと思います。

そのように工夫を凝らしている中で、2024年6月にAPI Gatewayの統合のタイムアウト制限を29秒から引き上げることができるアップデートがありました。

Amazon API Gateway integration timeout limit increase beyond 29 seconds - AWS

Amazon API Gateway では、お客様が統合タイムアウトを以前の上限の 29 秒から引き上げられるようになりました。この設定は、統合からのレスポンスが完了するまで API Gateway が待機する最大時間を表します。リージョン REST APIとプライベート REST API の統合タイムアウトを 29 秒から引き上げることができますが、アカウントレベルのスロットルクォータ制限の引き下げが必要になる場合があります。今回のリリースにより、大規模言語モデル (LLM) を使用した生成 AI のユースケースなど、より長いタイムアウトを必要とするワークロードがあるお客様が API Gateway を利用できるようになります。

こちらのアップデートにより、上限緩和を申請し受理されれば29秒を超えた同期的な処理を実行することが可能となりました。

API Gatewayの統合のタイムアウトを緩和してみるがうまくいかず

UniforceのアーキテクチャではバックエンドにAPI Gatewayを使用しています。

※UniforceのアーキテクチャについてはCTOの東川が執筆したSaaSプロダクトのインフラアーキテクチャをご参照ください。

稀にですが同期的な処理でAPI Gatewayの29秒のタイムアウトを超えるケースが出てきたため、タイムアウトの上限緩和を申請しました。

参考までにAPI Gatewayの統合のタイムアウト制限を緩和するにあたってサポートから質問された項目を載せておきます。

However, before the Service team can proceed to review and process this request for you, they requested that you kindly share the information below:

  1. What RPS do you expect to reach on the integrations requiring longer timeouts?
  2. What RPS do you expect across your entire account?
  3. What are the expected p50, p90, and p99 latency of your calls?
  4. What is the expected payload size of your requests?
  5. What is the use case that requires longer timeouts?

CloudWatchのメトリクス情報などを見ながら、これらの質問に返答しました。

その後、無事に受理されタイムアウトの上限を増やすことができました。

ちなみに、申請が受理されてから上限が緩和されるまでは3~4日ぐらいでした。

いざ、API Gatewayの統合のタイムアウトを増やして29秒のタイムアウトを超えていたAPIにテストリクエストを投げてみると、、、30秒ほどでリクエストタイムアウトに …ナンデェェ。( ;∀;)・。ェ

なぜ30秒でタイムアウトしてしまうのか探究する

API Gatewayの統合のタイムアウトを伸ばしたはずなのに、何故かAPIへのリクエストが30秒ほどでタイムアウトしてしまいましたので、各要素を調べてみることにしました。

今回の構成を表すと、こちらのようになります。

まず、紐づいているLambdaの実行ログを確認してみました。

Lambdaのログを見てみると受け取ったリクエストに紐づいて処理を正常に完了していることがわかりました。

つまり、API GatewayはタイムアウトしてClientにエラーを返していますが、Lambdaは問題ないことがわかりました。

ClientとAPI Gateway間の問題であることが想像できましたので、API Gatewayに割り当たっているカスタムドメインとAPI Gatewayにデフォルトで割り当てられるドメインへそれぞれリクエストを送信してみることにしました。

ここでは仮にカスタムドメインをapi.example.com、API Gatewayデフォルトドメインをapi-id.execute-api.region.amazonaws.comとします。

カスタムドメインへのリクエスト:

$ curl <https://api>.[example.com](<http://example.com/>)/ -o /dev/null -w '%{http_code}\\n' -s
504

API Gatewayデフォルトドメインへのリクエスト:

$ curl https://[api-id.execute-api.region.amazonaws.com](<http://api-id.execute-api.region.amazonaws.com/>)/ -o /dev/null -w '%{http_code}\\n' -s
200

カスタムドメインへのリクエストはエラーとなり、API Gatewayデフォルトドメインへのリクエストは正常終了していましたので、カスタムドメインへのアクセスが怪しいことがわかりました。

また、同時並行でフロントからバックエンドへのリクエストをデベロッパーツールで確認してみていると、レスポンスヘッダーに X-Cache: Error from cloudfront と記録されていることを発見しました。

APIのエンドポイントタイプはRegionalを使用しているはずなのにcloudfrontのエラーが記録されるのは変だと思いました。

API Gateway周りの設定を再度チェックしてみると、API GatewayのAPIエンドポイントタイプはRegionalなもののカスタムドメインのタイプはEdgeであることがわかりました。

そのとき、アップデート情報のことを思い出して再度確認をしてみると、

“リージョン REST APIとプライベート REST API の統合タイムアウトを 29 秒から引き上げることができます” の文言があることに気づきました。

このことから、もしかしたらカスタムドメインのエンドポイントタイプもRegionalである必要があるのではないかと考えました。


補足情報となりますが、カスタムドメインのエンドポイントタイプがEdgeの場合はAmazon CloudFront、Regionalの場合はApplication Load Balancerが裏で作成されます.裏で、というのは自身のアカウントが所有しているリソースではないためです。これらの情報はAWS re:Postで公開されています。

ACM 証明書エラー「証明書は使用中」の解決

エッジに最適化された API エンドポイントをデプロイすると、Amazon API Gateway によって Amazon CloudFront ディストリビューションが作成されます。リージョン API エンドポイントをデプロイすると、API ゲートウェイ によって Application Load Balancer が作成されます。CloudFront ディストリビューションまたは Application Load Balancer は、アカウントではなく API ゲートウェイ が所有しています。API ゲートウェイ をデプロイするために提供される ACM 証明書は、CloudFront ディストリビューションまたは Application Load Balancer に関連付けられています。

カスタムドメインのエンドポイントタイプをRegionalに変更しトライする

どうやら、カスタムドメインのエンドポイントタイプがEdgeであることが問題であることがわかりました。

そこで、カスタムドメインのエンドポイントタイプをRegionalに変えてみることにしました。

カスタムドメインのエンドポイントタイプを別のエンドポイントタイプに変更する手順はAWSのドキュメントに記載があります。

API Gateway でカスタムドメイン名を別の API エンドポイントタイプに移行する - Amazon API Gateway

こちらのドキュメントを参考にRegionalタイプのエンドポイントに切り替え、再度カスタムドメインへリクエストを送信してみました。

カスタムドメインへのリクエスト:

$ curl <https://api>.[example.com](<http://example.com/>)/ -o /dev/null -w '%{http_code}\\n' -s
200

今度はリクエストが29秒を超えて正常に処理されました!

また、フロントからバックエンドへのリクエストも正常に処理がなされることを確認しました。

これにより、カスタムドメインのエンドポイントタイプがEdgeであることが原因であることが明らかになりました。

念のためサポートにも状況をお伝えしたところ、予想通りの回答を得ることができました。

API Gateway のエッジ最適化カスタムドメインは、前段に CloudFront を利用いたしますが、CloudFront のリードタイムアウトの制限により、30秒で接続が切断されることが原因となっております。 誠に恐縮ながら、現時点におきましてエッジ最適化カスタムドメインで使用される CloudFront のリードタイムアウトの制限を緩和することができかねます。 そのため、カスタムドメインのタイプをエッジ最適化からリージョン別に変更いただけますようお願い申し上げます。

まとめ

今回はAPI Gatewayの統合のタイムアウト制限を緩和したときにハマったときのお話を記事にしてみました。

API GatewayがRegionalタイプでタイムアウトの上限緩和の申請が通った後に、まさかカスタムドメインのエンドポイントタイプが原因で詰まることなるとは思いもしませんでした。

実際、カスタムドメインを設定するときにエンドポイントタイプまで意識することはなかなかないのでは?、と思いましたので、こちらの記事が誰かの役に立つと嬉しいです。

本日の記事はここまでとなります。

最後まで読んでいただきありがとうございました🙌