Webサービスにおける可用性の算出法
SRE本は完全に名著なのだけど、中でも際立って自分に影響を与えたのが、正確な可用性の算出方法であった
可用性(=Availability)というのはITサービスの文脈においてはサービスが実時間に対してどれくらいちゃんと使えているかを表す指標である
しかし、一言で表せる割には可用性はその計測方法はたいてい適当である
「ダウンタイム」とか「障害」とか言われる現象が起こると、当然サービスの可用性は落ちるわけだが、具体的にどんな数値がどう変わったのか?という測定方法については自分はよくわからなかったし、大きなサービス会社で働いているときも、自分の組織にはそういったしっかりした数値指標というものは存在しなかった
SRE本には可用性の算出法が明確に書いてあって、それは次のとおりである
可用性 = リクエスト成功率
自分はこのシンプルさに衝撃を受けたわけだが、その理由を書いていこうと思う
まず、リクエスト成功率の定義はWebサービスに限定すれば、全リクエストに対してWebサーバーが5xxエラーを返した数の割合である
$ Availability = \frac{RequestCount}{RequestCount + 5xxCount}
RequestCount=0, 5xxCount=0の場合はN/A、別に1でもいいけど
一般的にもう一つの可用性の算出方法があり、それは時間による算出である
期間内におけるサービスが落ちていなかった時間の割合を可用性とする方法である
しかしこれには問題がある
GoogleもSRE本で時間で可用性を測っていないと明言している
その理由としては、現代のWebサービスは昔と違って同じ内容のサービスであっても地理分散・マシン分散・サービス分散が進んでいて計測対象のサービスの機能すべてが一度に落ちることはほぼありえないからである
リクエスト成功率の場合は、落ちている/落ちていないという判断はせず、サービスが適切にエラーを返した場合でも可用性が低下していると判断する点にある
マトモに作られたWebサービスであれば、検査例外でサービス自体が落ちることにはなっていない
しかしそういう5xxエラーになる場合はユーザにとってはサービスが落ちていることと同義であり、サービスの信頼は落ちている
もう一つ重要なのは、リクエスト成功率の場合は、エラーの性質や種類や原因を加味しないという点である
サービスが適切に5xxエラーを返すという前提に立って、どのようなエラーが起きたとしてもそれを可用性に反映させるのは潔さがあると思う
一方で、サービスを実装する側は正常系で5xxエラーを返さないという原則を守る必要も出てくるわけだが
さてこのように可用性=リクエスト成功率の良さを語ってきたわけだが、一つの大きな問題が出てくる
どうやって正確なリクエスト数とエラー数を計測するのか?
その答えは、実際無いと言っていい
現実的にはリバースプロキシを置いて、リクエスト数とプロキシターゲットから返ってきたスタータスコードを記録しておけばいい
が、リバースプロキシ自体の可用性は誰が測るのか?という問題が残る
リバースプロキシの可用性はリバースプロキシ自体しか測ることができない
リバースプロキシが起こしたエラーも、ユーザからしてみれば同じエラーである
クライアント側から可用性を算出することも無理である
なので、現実的にはある程度信頼できる信頼できるリバースプロキシを置いて、その可用性の範囲内で実際のサービスの可用性を測るべきだろう
実際、製品化されているリバースプロキシの信頼性は高い
問題はリバースプロキシが動くPaaSがより複雑なシステムになっているという点なのだが…
PaaS、特にAWSに置いてはALBとCloudWatchがその役割を担ってくれるので楽ちんであるのだが