😱

よく起きる本番障害とそれを防ぐ対策をまとめてみた

2021/02/21に公開

はじめに

私は今まで、15年ほどSier系の企業でエンジニアとして開発業務をしてきました。その中で、複数の開発現場で、本番障害を担当することが多くありました。

本番障害とは、言葉の通り、実際に動いていてユーザが使用している環境で発生する障害です。テストを行う環境を「テスト環境」、実際にユーザが使う環境を「本番環境」と分けることが多いため、本番環境で発生した障害は「本番障害」と呼ぶことが多いです。

本番障害は、大小様々ですがユーザ業務に影響を与えるため、基本的には発生しては行けないものです。しかし、新しいシステムや機能を作る上で、どうしても発生しててしまうことはあります。

本番障害が発生する理由は様々なものがあります。開発現場によって発生頻度や特徴は様々ですが、複数の現場で共通して発生しやすい障害があります。今回は、本番障害が発生する理由として、私の経験上よくある原因とそれを防ぐ対応案を解説していきたいと思います。

1. レアケース・異常系の考慮不足

まず、最初にあげられるのはレアケース・異常系の考慮不足です。

実は、基本的な操作パターンによるケースは、きちんとテストしていればある程度防ぐことができます。しかし、不特定多数のユーザが使うシステムにおいては、開発側が想定していないようなオペレーションをされることがあります。その結果、想定していないパターンのデータが発生したり、誤った情報を表示してしまうなどの障害が発生することがあります。

このケースの対策は非常に困難ではありますが、以下のような対策が考えられます。

設計段階で運用パターンを整理する

最も月並な方法ですが、設計段階から運用パターンは整理する必要があります。頭の中だけで整理するのは難しいので、表などの形式で整理して、そのパターンが正しく設計(実装)できていることを確認します。

整理の方法は様々ですが、私がよく使う方法は以下のようなものがあります。

マトリックス

マトリックスは、行・列にそれぞれ条件や状態を記載し、重なった部分に結果を記載することで、複数の条件や状態ごとのパターンの組み合わせを整理するものです。

下記の表は、行部分に機能名、列部分にシステムの状態を表しております。目的としては、それぞれの状態ごとに、各機能が使用可能かどうかを整理するものです。⭕が使用可能、❌が使用不可であることを表しています。

このマトリックスから、以下のことが読み取れます。

  • ログイン画面、ユーザ登録画面は、未ログインのときのみ使用できる
  • 投稿、フォロー機能は、ログイン中のみ使用できる
  • タイムラインは、ログイン状況に関わらず使用できる
  • メンテナンス中、システム停止の状態では、全機能が使用できない

また、今回は使用可否を示す⭕、❌のみで表記していますが、もう少し細かい結果を記載することもあります。

デシジョン表

デシジョン表は、複数の条件を記載し、その条件に該当するかどうかを、Yes,Noなどで整理し、パターンを整理していくものです。

下記の表は、青い網掛け部分が条件、赤い網掛け部分が結果をあらわあしています。条件に該当する場合はY、該当しない場合はN、無関係の場合は-としています。結果の部分は、複数の予測結果を書いており、その様になる場合は⭕を記載するようにしています。

上の表から、以下のようなことがわかります。

  • すべての入力項目が正しく入力されていたら、ユーザ登録を完了し、次の画面へ遷移する
  • 自己紹介については、入力されていなくても問題ない
  • パスワードが8桁より少ない場合は、ワーニングを表示するが、ユーザ登録は完了し次の画面へ遷移する
  • 自己紹介以外の項目が未入力の場合や、メールアドレス、年齢の形式がおかしい場合は、エラーメッセージを表示し、現在の画面にとどまる

デシジョン表の書き方は様々なものがありますので、上記の書き方は1例と捉えていただければと思います。

複数の人からレビューを受ける

パターンの整理を慎重に行っても、レアケースや異常系のパターンは抜けてしまうことがあります。

そのために重要なのが、第3者のレビューとなります。ただし、レビューはどちらかというと、抜け・漏れを気づく最後の砦のようなものであり、あくまでも実際の成果物に対する考慮が漏れていないかどうかは、作成者の段階で十分に考慮しておく必要があります。

レビューを依頼する対象として、以下のパターンが考えられます。

チームメンバー

チーム内のメンバー(場合によってはリーダー)がレビューをすることです。最も一般的なレビューはこれになります。

ソースコードや設計書をピア・レビューという形でチェックしたりします。観点についてはチームによって異なりますが、基本的には様々な観点から「内容に問題がないこと」を確認することになります。

設計書やソースコード、テスト観点など様々なものが対象になります。

有識者

システムや技術の有識者がレビューをすることがあります。

システム有識者のレビューの場合、基本的に新しい仕様などがシステム全体に見たときに不整合がないかという点を見ることが多いです。

技術的な有識者のレビューは、例えば新しい技術や特殊な技術を利用する場合に、その技術に詳しい人がレビューに入って内容を確認する形です

どちらのケースも基本的には毎回実施するというより、必要に応じて実施するケースが多いです。また、状況にもよりますが成果物のレビューというより、計画段階で入ったもらったほうが効果的であることが多いです。

品質担当者

品質担当と言う立場の扱いはプロジェクトによって異なりますが、

  • QAエンジニア(quality assurance engineer)
  • PMO(Project Management Office)
  • 社内監査役

のような役割が存在し、品質が担保されているかレビューすることがあります。

この場合は細かい内容をチェックするというより、

  • 正しいプロセスを通して開発しているか
  • 仕様の検討やテスト観点に漏れがないか
  • 過去に障害を起こした箇所が改善されているか

といった観点で、どちらかと言うと「やり方が正しいか」を見て行くような形です。

ユーザ

ユーザがレビューするのは、ソースコードや設計書というより、「仕様」の部分になります。プロジェクトによっては「テスト観点」もレビューすることがあります。

また、実際に早いタイミングで動作環境を用意してユーザに使ってもらい、問題を早期に検知することも有効です。書面上で整理しても気が付かない点が、実際に使ってみると気がつくということは本当に多いです。

2.テストデータとの不整合

テスト環境でテストをする場合、データを手作成することが多いです。手作成ではなくシステムからの入力を使う場合も、限られたパターンしか存在せず、バリエーションが不足することがあります。

完全な新規システムであればよいのですが、現在では、すでに動作しているシステムに対する機能拡張であったり、既存システムの再構築(リプレイス)も多く、その場合は「既存データ」が存在することになります。

この既存データに想定外のパターンがあって障害が発生することが多くあります

例えば、以下のようなパターンが考えられます。

これらを防ぐためには、以下のような対応が考えられます。

本番相当のデータを使ってテストする

もっとも有効な対策は、本番データを使用してのテストを行うことです。

とはいえ、状況にもよりますが、本番データをそのまま使用することができないこともあります。(セキュリティ、個人情報保護の観点から)

本番データを使ってテストするためには下記のような手順を踏む必要があることが多いです。

方法は様々なものがありますが、個人情報を含む本番データの扱いは、事前ルールなどに定められていることが多いです。そのルールを破ることはかなりのセキュリティ違反となりますので、要注意です。

もしご自身がルールを作る立場であれば、個人情報に関するルールは絶対に決めておいたほうが良いです。個人情報の流出は、会社を潰しかねないほどのリスクがあります。

システムから作成したデータを使用する

企業のルールによっては、マスクやセキュリティ対策を行っても、本番データを持ってきたり参照ができない場合があります。

そのような場合であっても、なるべく本番に近いデータを利用できるようにすることが理想です。例えば、システムから実際に登録したデータを使うことで、本番データに近いデータを作れる可能性が高くなります。

しかし、数件であれば入力できますが、本番データは数千件にも及ぶこともあり、その件数を手で打鍵することは不可能に近いです。

そこで活用できるのが自動打鍵です。例えばSeleniumというツールを使用すると、スクリプトを作成することで何回でも自動実行ができます。

実行時間はそれなりに掛かるかもしれませんが、空いているPCで流しっぱなしにするなどすれば、大量の件数を作成することができます。

3.デグレード(デグレ)

デグレードとは、デグレとも呼ばれますが、プログラムの修正に対して、本来の目的とは異なる箇所に悪影響うことです。

具体的な内容として、以下のようなものがあります。

これらを防ぐためには以下のような対策が必要です。

ソース管理ツールを導入する

ソース管理ツールとしては、GitやSVNなどが有名ですが、現在ではGitのシェアがかなり大きくなっています。案件に参画する条件として「Gitでソース管理していること」を挙げるエンジニアも少なくありません。

ソース管理ツールを使うことで、以下のようなメリットがあります。

ソース管理ツールを使うことで、「資材管理ミス」、「修正ミス」による障害の防止に大きく貢献します。ソース管理ツールは必須の知識と考えて差し支え無いと思われます。

回帰テストを行う

回帰テストとは、改修を行った部分が他の既存機能に影響を与えていないことを確認するテストです。

方法はプロジェクトによって様々ですが、システムごとに基本となる回帰テストケースが用意されており、リリース前にそのケースが正常終了することを確認するという形です。これにより、既存機能への予期せぬ影響を検知できる可能性があります。

回帰テストを手動で行うのはコストが大きいため、テスト自動化と組み合わせると効果的です。

CI/CD環境を構築する

CI/CDは、Continuous Integration/Continuous Deliveryの略であり、継続的インティグレーション/継続的デリバリーとも表現されます。

方法は様々ですが、以下のようなイメージです。

  1. ソースコードの変更を検知する
  2. コードの静的解析を行い、コードの誤りを検知する
  3. テストを自動で行い、問題がないことを確認する
  4. 動作環境に反映させる

CI/CDにより以下のメリットがあります。

4.環境差分

テスト環境と本番環境で設定値等に想定外の差分があり、障害となるケースです。

設定値の差分は、以下のような理由で発生することがあります。

message:::
環境差分が発生する原因

  • 単純作業ミス
  • サーバの細かいバージョンやリビジョンの違い
  • 設定値を管理する資料と、実際の設定値に差がある
  • テスト環境で設定した内容を失念している
    :::

環境差分による障害は、ものによっては何も影響ない場合もありますが、システム停止や、結果の不整合など、重大なトラブルに成ることがあります。リリース直後に気がつけば問題にならないこともありますが、内容によってはすぐに気が付かないこともあります。すぐに気がついたとしても、対応二時間がかかってリリース失敗などの自体もあります。

環境差分を防ぐには、以下の方法があります。

インフラをコード化する

インフラのコード化は、通常手動で行う環境構築を、コード化して行うことです。通常のプログラミングと同じように、環境構築を行うためのコードを書き、それをツールを使って実行することで、環境構築を行います。インフラのコード化ツールで有名なものとしては、Terraformなどがあります。

インフラをコード化することで、以下のようなメリットがあります。

コンテナ化する

コンテナ化とは、サーバを構成する環境(ミドルウェア、アプリケーション)をすべてコンテナという形にまとめて管理し、それを開発環境、テスト環境、本番環境に適用することで、環境構築を行うものです。

コンテナ化のツールとしては、Dockerが有名です。Dockerの場合、環境の設定をDockerファイルにまとめて、配布することができます。

コンテナ化のメリットについては以下となります。

テストした環境をそのまま本番へ持っていける

コンテナ基盤上で構築した環境を、そのまま別の環境にコピーすることができます。この仕組を利用することで、テストした環境をそのまま本番環境へ持っていくことができます。

環境の差分を吸収してくれる

実行するOSが異なっても、その違いをコンテナ基盤が吸収してくれるため、異なるOS上でも動かすことができます。

テスト環境と本番環境でOSの違いがあることは望ましくはないですが、予算の都合などで同じものが用意できない可能性もあります。

また、通常本番環境はLinux系のサーバですが、各個人の開発環境はMacやWindowsであることが多いです。コンテナがOSの差を吸収してくれるので、個人の開発環境上で本番と同じ構成の環境を用意することもできます。

気軽にテストできる環境を用意する

コンテナ化により、コンピュータ内に容量があればいくらでも環境を作ることができます。同じ環境のコピーも作れるので、問題があったときに「壊して作り直す」ということが容易にできます。

物理的なコンピュータが1台しかない状態ではなかなか試せないことが、コンテナを利用することでいくらでも試すことができるようになります。この「壊して作り直す」は非常に有効で、環境起因の障害を出さないために必要になります。

5.性能が出ない

テスト環境では問題なく動作していたものが、本番では性能が発揮できないということがよくあります。

上記でも記載したような「データの差分」や「環境差分」が原因であることも多いですが、テスト環境にはかかっていなかった「負荷」が本番では発生するため、それに耐えられる作りになっておらず障害となることがあります。

性能起因の障害を防止するためには、以下のような対策があります。

負荷テストを行う

負荷テストは、ツールを使ってシステムに負荷をかけた状態でテストを行うものです。

例えばApache JMeterと言うは、性能テストを行うためにシステムに負荷をかけることができるツールになります。

http://jmeter.apache.org/

管理画面の操作で細かい部分まで負荷をかけることができ、無料で使用できるため性能テストを試してみたい場合に使ってみるのも良いかと思います。

負荷分散を行う

そもそもの仕組みとして、負荷が一定箇所に集中しないようにしておくことも必要です。

ある程度アクセス数のあるシステムであれば、一つのサーバだけではなく複数のサーバで処理するという冗長化校正も必要になってきます。ロードバランサーという機能を使うと、アクセスを各サーバに負荷分散し、1台あたりの負荷を軽減できるため、レスポンスの向上などが期待できます。

また、1台のサーバが壊れても、他のサーバで処理を継続できるというメリットもあります。(サーバが物理的に壊れるというのは、本当に発生します)

性能に関するトラブルは開発段階では検知しにくいですが、本番で発生すると非常に厄介なトラブルになります。

最後に

本番障害がの理由として様々なケースを挙げて説明致しました。

もちろん、これ以外にも本番障害となり得るものはありますし、上記の対策も完璧ではなく、他にも有効な対策があります。

また、どんなに対策をしても障害が起きることがありますので、障害が起きたあとのリカバリをどうするか、ということも重要です。

Discussion