サービス障害とその対策についてのTech talk

f:id:corp_monoxer:20211119154643p:plain

自己紹介

皆様はじめまして。ソフトウエアエンジニアの加藤です。

今回はサービスの障害についてとそれに対する弊社での取り組みについて書いていきたいと思います。

不具合の原因について

利用者から「サービスを利用しようとしたけどログインできない。」と言われた場合、原因として考えられることは一体何でしょうか?

例えば、ログインの画面が表示されないといったことやIDとパスワードが入力できたとしても、アプリケーションの処理に問題があってログインできないかもしれません。このようにサービス側に何らかの問題があるケースが主に考えられます。

一方、IDとパスワードの組み合わせが違っていたやインターネットに接続されていないといったような利用者やその環境が起因のケースが考えられます。 この場合は、利用者側の環境で問題があることに気づいてもらって解決してもらうか、 必要があればパスワードリセットのような解決するための機能が必要になるでしょう。 f:id:corp_monoxer:20211126131805p:plain

ここではサービスが原因の不具合(サービスの障害)について詳しく話を進めていきたいと思います。

サービスの障害が発生する原因

それではサービスの障害がなぜ発生するのでしょうか? その主な原因はサービスを変化させるときに発生するものです。

サービスを変化させるというのは、以下のようなことが該当します。

・新しい機能をリリースする

・サービスの内部で利用しているソフトウェアを変更する

・使わなくなった機能を取り除く

・DBのデータ操作やアプリケーションに関するコマンドの実行

このときに何らかのミスをすると不具合が発生する場合があります。

また、障害発生の原因は他にも以下のようなものがあります。

・ハードウェアの破損

・利用しているサービスの停止

・想定以上のアクセスによって処理が詰まってしまう

前者については、Webアプリやスマホアプリのような頻度高く更新が行われる開発では根本的な解決は難しいと考えられます。

後者については、適切なインフラ設計やパフォーマンスの改善などで一定数発生を防ぐことができます。

ではサービスの障害を減らすことや、起きたときに影響を小さくするためにはどのようなことをすればよいのでしょうか?

サービスの障害の予防・抑制

ここからは障害の予防の観点と障害への対応という観点から話をします。

障害の予防のためには、開発時にミスを起こりにくくし、リリースまでにミスを検知できる状態にすることが大事になります。 具体的には以下のような方法が考えられます。

QAや受け入れテストの強化

・受け入れテストを開発プロセスに組み込んだり、専属のQAエンジニアを設けるなどが考えられます。

CIを使った自動テストやリントチェックの導入する

・コンパイルエラーを始めとしたケアレスミスを防ぐ

・自動テストで期待と異なる処理が発生している箇所を特定する

クリティカルな操作の制限

・例えば、サーバの停止ボタンやルート権限などを誰もが利用できる状況をなくすといったことです。セキュリティの観点からも重要ですが、内部の人間が間違って押してしまったやコマンド実行できたなどの危険を事前に減らすことができます。

オートスケーリングの導入

・1台あたりのサーバに対する負荷が増えたら、自動でその負荷を減らすように新しいサーバを追加する機能があります。これにより負荷にによるサービス不全を防ぐことが可能になります。

続いて障害への対応についてです。 具体的には障害が起きた際にその影響を最小限に抑えることについてです。

障害の影響は復旧までの時間と対象の機能を利用するユーザー数が大きいほど大きくなります。 影響を小さくするには「障害を早く発見すること」と「発見した障害に早く対処すること」が重要になります。

障害を発見する方法

主に自動で検知するケースと利用ユーザーから連絡が来るケースがあります。 自動で検知できる仕組みがあると、問題に気づくのがより早くなります。

異常な状態のスパイクを検知

・エラーログが通常よりも増えている ・CPUの負荷がしきい値を超えている

顧客からの連絡

・問い合わせフォーム

・CSへの連絡

発見した障害への対処

発見した障害を解決するには、障害の原因特定と原因への対処が必要です。 原因を特定するためには具体的な状況を知る必要があります。

エラーログの情報

・どのような処理でエラーが発生したかわかる。 ・ログのカスタマイズ次第では対象のユーザーなどの詳細な情報も知ることが可能。

発見したユーザーからの情報

・使用デバイスやバージョン、時刻、再現方法など。

このようにユーザーやログから情報を集めて、原因の特定を行います。原因の特定ができたら複数の部署が連携して対応をします。

・ソフトウェアエンジニアが原因を特定し、問題を解決する。

・必要に応じてですが障害の状況を外部へ発信します。

弊社での取り組み

ここまでは一般的なサービスの障害とそれに対する対策について説明してきました。 最後に弊社でどのようなことに取り組んでいるかについて簡単にお話をしたいと思います。

自動テスト・自動Lintチェック

・github上でリモートのブランチを更新したタイミングで実行されるようになっており、チェックをが通らないとリリースブランチにはマージできない仕組みになっています。 f:id:corp_monoxer:20211124091020p:plain

異常の検知

・CPU利用率などがしきい値を超えたらslack上にアラートが出るようにしています。 f:id:corp_monoxer:20211124091110p:plain

ログの整備

・GCPのログやCrashlyticsを利用して、エラーログや処理が遅いリクエストを閲覧できるようにしています。

最後に

今回はサービスの障害の原因や対策について簡単に説明をさせていただきました。

サービスの障害への対策はプロダクトの価値を高めることに直接的には繋がらないですが、 サービスが問題なく安定して稼働することは利用者にとって重要なことです。 さらには従業員にとっても安心して通常の業務に集中できるようになるなど大事なことになります。

この記事を読みサービスの障害について少しでも知識が増え、関心を持っていただければ幸いです。 最後まで読んでいただきありがとうございます。

モノグサ株式会社では一緒に働く仲間を募集しています。

少しでも興味を持っていただけた方はぜひお話しましょう!

careers.monoxer.com