Cloud Functionsの最大インスタンス数は設定しましょう
概要
- 本番環境でやらかしてしまったアドベントカレンダー2023 65536日目の記事です
- Cloud Functionsの最大インスタンス数は設定しましょうという話です
結論
Cloud Functionsの最大インスタンス数は設定しましょう
障害発生!
弊社の場合、システムが何かしら不安定だと、ErrorやWarningの情報が流れるSlackチャンネルがあり、その情報を確認しつつ、NewRelicとにらめっこして原因を調査します。それと平行に対応できるメンバーや他部署とやり取りを効率化するため、meetを用意して一斉にその場に集まります。
今回はあるAPIが大量に叩かれていることに気が付き、確認したところ社内管理画面で利用するAPIでした。
aipaはこの辺で胃が痛くなっていました(障害対応メンバーにはすぐに報告しました)
何が起きたのか
自分が見ているチームのプロダクトに直近追加した機能がその社内管理画面用のAPIへリクエストするようにしていました。
構成としては
- GCP Cloud Pub/Sub
- 別の機能からQueueを詰める
- Cloud Functions
- QueueがあるとPub/Subトリガーで起動する
- 社内管理画面用のAPI
- 弊社が提供するサービスに用意されている`
そのAPIは以前からある一定の条件下ではパフォーマンスが悪く、どこかで改善しないといけないよね。とはなっていましたが、今回それに見事にあたりました。
一番の問題としては、そのAPIへリクエストしているのがCloud Functionsだったため
- パフォーマンスが悪い条件でAPIへリクエストする
- Cloud Functionsが処理中になる
- Pub/Sub Trigger時に、Idle状態のCloud Functionsがないので、 新しいインスタンスを起動する
- 1 ~ 3が繰り返される
- 大量のインスタンスがサービスへリクエストを投げる
- サービスが不安定になる
と、社内施策で大事なサービスにDDoS攻撃するという事象が発生してしまいました。。。
原因
当時のCloud Functionsのインスタンス数
Cloud Functionsはインスタンス数に上限を設けることができますが、僕はAWS Lambdaとかも運用したことあるのにも関わらず、今回リリースした機能には上限を設けた設定を行ってなかったのがそもそも問題なので、猛省しております。。。
対応
コンソールで手動設定するか、コードに書く必要があります。
Cloud Functions for Firebaseの場合、モジュールで設定することが可能です。
runwith
にmaxInstances
をkeyで渡して値を設定しましょう。
import * as functions from 'firebase-functions'
// ...
export const cloudFunctionsName = functions
.runWith({
maxInstances: 100
})
// ...
まとめ
Cloud Functionsの最大インスタンス数は設定しましょう
Discussion