現象
私の環境では、2021年9月中旬あたりからFirebase CloudFunctionsで以下のエラーが頻発するようになりました。
Error: The request was aborted because there was no available instance
onRequest
、onCall
、リージョン変更など試しましたが規則性や条件はなくほぼ全てのfunctionsで発生しました。
頻度が極めて高く、レスポンスすらクライアント側に返ってこない(そもそもFunctionが発火してすらいない)という状況で、かなり困りました。
原因
どうやら米国時間の2021年8月31日に施されたップデートが原因のようです。
この新機能では、需要が低い期間にオンライン状態にしておくアプリケーションのインスタンスの最小数を指定することで、サーバーレスのアプリケーションとワークフローのパフォーマンスを劇的に改善し、コールドスタートを最小限に抑えることができます。
要約すると、
- FaaSの課題として、長時間リクエストがないとインスタンスが閉じられてしまって、再度リクエストが発生した時にインスタンスの生成などの予備動作から始まるために余計に時間がかかってしまう(コールドスタート)というものがある
- 解決するためにGoogleは、最小インスタンス機能をアップデートした
- 最小インスタンスに設定した数のインスタンスは維持されるようになった
というものです。
以前はコールドスタートに数秒かかっても大丈夫だったが、アプデ以降は1秒ほど待ってインスタンスが立ち上がらなかった場合にエラーをスローしてFunctionの発火すらしなくなったという報告がGitHubのIssueに上がっています。
アプデの影響であると断定はできませんが、GitHubにIssueが立ちはじめたタイミングと重なっているので確率は高いでしょう。
対応策
至ってシンプルです。タイトルにも書きましたが、「強引な方法」であって根本解決ではないです。
最小インスタンスを設定し、金を払う(〜数十万円/月)
以上です。
設定方法
// index.ts
export const api = functions
.region('asia-northeast1', 'us-central1')
.runWith({minInstances: 1}) // この行を追加
.https.onRequest(server)
3行目のように、fuictionsの定義に.runWith({minInstances: 1})
を追加するだけです。
値は1以上の任意の値にしてください。(私はケチなので1にしました)
こうするとインスタンスが閉じなくなり、エラーが出ることもなくなりました。
課金形態
1ファンクションごとに、$6/月です。
"1プロジェクトごと"ではありません。上記の場合、onRequest
が2リージョン分ありますから、$12/月になります。
一般的なプロジェクトでは数10個のファンクションがあるでしょうから、だいたい月数万〜数十万になるのではないかと思います。
色々調べましたが、どうやら現状これしか解決がなさそうです。(2021年9月21日)
いやぁ、やってくれましたねぇ。
予算に余裕がありエラーを早急に解決したい担当者は、怒りを覚えながらGoogleに金を払いましょう。
予算に余裕がない担当者は、怒りを覚えながら寝ましょう。
今後
ビジネス的に儲けるために設計されたエラーなのか、Googleも予期せぬ不具合なのかは分かりません。
一応、公式に対応していると発表はされていて、IsuueTrackerにも上がってますが...どこまで対応してくれるのか...
どうしても金を払って解決したくない人は以下のページをウォッチして状況を監視しておくのが良いでしょう。
【蛇足】