ITシステム(サービス, アプリケーション)の開発を行っていると、設計してコード書いてテストしてリリースするという流れになり、 このリリースというのがゴールという感覚に陥る場合があります。
実際は、システム(サービス)は運用が開始されてからがスタートだと言っていいと思います。
が、私含めた開発者というのは往々にして運用フェーズに対して意識がいきにくい気がします。
(DevOpsが広まった世の中ではそんなことないんですかね?私の感覚が古すぎ?)
これまでの経験から、運用観点でシステムがどうあるべきか、開発者が何を意識しておくべきなのか を書きました。
(思いっきり個人的な見解なので、システムやサービスやビジネスモデルによって当てはまったり当てはまらなかったりだと思います)
実行環境
- 実環境とQA環境は一致していない
- 開発環境やQA(品質保証)環境が実際のサービスが動作する環境と(スペックやリクエスト量が)同等になっている状況はほとんどありません。
自分の開発環境やQAチームの環境で問題が出なくても、実環境では問題が出ます。
- 開発環境やQA(品質保証)環境が実際のサービスが動作する環境と(スペックやリクエスト量が)同等になっている状況はほとんどありません。
- ハードウェア
- ITシステムは当然ですが、ソフトウェアだけではなくハードウェアがあることで成り立っています。
クラウドになろうが仮想化されようがその下支えとしてハードウェアが存在する事実は変わりありません、ハードウェアは経年劣化したり破損したりが当然のようにあります。
ファンが故障したり、ディスクが読めなくなったり、マシンの電源が入らなくなったり。
ハードウェアの影響を受けて性能が上手く出せない、予期せぬシャットダウンを余儀なくされる等の試練をソフトウェアは受けることになります。
- ITシステムは当然ですが、ソフトウェアだけではなくハードウェアがあることで成り立っています。
- 実環境とステージング環境を区別できるように
- コンソールでステージング環境(テスト環境)に接続して作業しているつもりが、実際には実環境(本番環境)につないでました。というケースがあります。
そうならないためにも、実環境とステージング環境では接続までのステップを変える。接続した際のターミナルの背景を異なる色で表示する等、明確にどこにつないでいるかが分かるようにした方が良いです。
- コンソールでステージング環境(テスト環境)に接続して作業しているつもりが、実際には実環境(本番環境)につないでました。というケースがあります。
- ネットワーク機器
- 実環境では、開発環境やQA環境には存在していなかった負荷散装置やファイアウォール等のネットワーク機器が介在していることが多々あります。
ユーザ
- 大事なお客様は攻撃者
- システム(サービス)は利用ユーザが存在して(お金を払ってくれるから)こそ存続することができます。
しかし、ユーザは意図せずシステムへの攻撃者ともなります。大量のリクエストを投げてきたり、思いもよらない巨大なデータのダウンロードをしたり...
とにかく、この意図しない負荷にシステムは耐える必要があります。
- システム(サービス)は利用ユーザが存在して(お金を払ってくれるから)こそ存続することができます。
- やらかしているユーザを特定できるようにする
- 上に書いた通り、ユーザは意図しないにせよ意図したものであるにせよシステムに対して負荷をかけてくる場合があります。
そういったユーザに対しては何らかの対処が必要になり、対象のユーザを把握する必要があります。
そのためにも対象のユーザのユーザIDや送信元のIP等がログに記録されている必要があります。
- 上に書いた通り、ユーザは意図しないにせよ意図したものであるにせよシステムに対して負荷をかけてくる場合があります。
- ユーザIDを共有させない
- いくら対象ユーザを特定しようとしても複数ユーザ間で1つのユーザIDが共有されていると特定が困難になります。BtoBのシステムでこの状況に陥る場合があります。
必ず個人単位に割り当てられたユーザIDのみが利用されるシステムである必要があります。
- いくら対象ユーザを特定しようとしても複数ユーザ間で1つのユーザIDが共有されていると特定が困難になります。BtoBのシステムでこの状況に陥る場合があります。
- 優先すべきユーザ
- 多くの代金を支払っていたり紐づく実利用者が多い等のビッグユーザも存在すれば、そうではないユーザもいます。やはり、ビッグユーザの方がサービス運営には大きなインパクトがあります。
規模の小さなユーザを軽んじるという意味ではないですが、サービスを運用・開発する側としてはユーザ対応に関して戦略的な優先度付けは必要になります。
- 多くの代金を支払っていたり紐づく実利用者が多い等のビッグユーザも存在すれば、そうではないユーザもいます。やはり、ビッグユーザの方がサービス運営には大きなインパクトがあります。
- ITリテラシーは人それぞれ
- サービスの利用者はITリテラシーが高い人だけとは限りません。色々な人が使うことを理解したうえで、ユーザのサポートをする必要があります
- ユーザの無効化
- システムを利用しなくなったユーザを削除または無効化するための仕組みは必須です
現場での障害・エラー
現場(実環境)では、実装やユニットテスト時には想定しにくいエラーパターン(障害パターン)が存在しています。
アプリケーションレベルでは対応できないものも含まれますが、システム全体としては考慮しておいても良いと思います。
- ディスクフルになって書き込みができない
- ディスクがunmountされている
- inodeが枯渇
- ファイルシステムが破損
- ファイルシステムがreadonlyになった
- スレッドが枯渇
- メモリの枯渇(OutOfMemory)
- 他システムから仕様に違反した電文が送られてきた
- リクエスト先が無応答
- 無限や非数を表す数値データが送られてきた
- レプリケーションしているDB間に差分がある
- データベースに仕様と異なるデータが混入している
- 証明書の期限が切れた
- JavaVMがクラッシュ
- 設定ファイルに書かれた設定内容の整合性が取れていない
- (機器の不具合で)稼働後に一定日数経つと機器が勝手に再起動する
- bindしたいポートが重複
- システム日時がずれている
- シーケンス番号がオーバーフロー
- DBのMAXコネクション数を超えた接続要求があった
- 通信量が多すぎてインターネットプロバイダに通信速度を制限される
- (毎月第2火曜日の)Windows Updateの配信によりインターネット回線の遅延が発生した
- メールの宛先や文面に対するチェックでメールが到達しない
- メールを監視するシステムが別に存在していて、メールの宛先が不適切だったりメールの文面に入れてはいけない単語が入っていたりするとそのシステムがメールを弾く場合があります
ログ
- ログが頼り
- ログを出力しないアプリケーションも存在しますが、基本的にシステムの状況を知るための入口となるのはログです。
エラーが発生した状況などではとにかくログが手掛かりですので詳細な状況を記録する必要があります。
- ログを出力しないアプリケーションも存在しますが、基本的にシステムの状況を知るための入口となるのはログです。
- 整形
- 基本的に同一システム内では統一されたフォーマットでログを出力したほうが良いです。フォーマットが異なるとログを解析する労力が大きくなりやすいです
- コンテキスト(文脈)を出力
- エラーをログに記録する場合は、発生したエラー内容だけではなく、その現象を取り巻くコンテキストの情報についても出力するべきです。(いつ、誰の操作で、どんなイベントやデータが関連しているかetc)
そうした情報がある方が、原因を追いやすくなります。
- エラーをログに記録する場合は、発生したエラー内容だけではなく、その現象を取り巻くコンテキストの情報についても出力するべきです。(いつ、誰の操作で、どんなイベントやデータが関連しているかetc)
- 単位も出力
- 何らかの数値をログなどに出す際は単位も出力するべきです。単位がbyteなのかMBなのかで話は大きく変わってきます。
- 個人情報
- システムの特性にもよりますが基本的にログに個人情報は出力するべきではありません。出力するにしてもマスク処理等は必須です。
- Diskを消費する
- ファイルにログを出力しているとすれば、出力すればするほどDisk容量を食うことになります。ログもリソースを消費することは意識しておいたが方が良いです。
- パフォーマンスの劣化
- 非同期型ではなく同期型のロギングを行っている場合は特に、ログを出力すればするほとアプリケーションの性能劣化につながる場合があります。ログの出力し過ぎが害になる場合があります。
- エラーは記録した、でも誰も気づかない
- アプリケーションでエラーが発生して、ログファイルに記録した。が、誰もこのエラーに気づいていない。
この状態は最悪で、何の意味もありません。
エラーが書かれたことを監視する仕組みや通知する仕組みなど必須です。
誰の目にも触れないものは存在していないのとほとんど同じです。
- アプリケーションでエラーが発生して、ログファイルに記録した。が、誰もこのエラーに気づいていない。
画面
- ユーザが一番触る場所
- システムが提供する画面は、ユーザが最も頻繁に触れる場所となります。ということは、ここを通じて何らかのエラーが発生することになります。
画面そのものがおかしな動作をする場合もあれば、バックエンドの仕組みに悪影響を与えることがあります。
- システムが提供する画面は、ユーザが最も頻繁に触れる場所となります。ということは、ここを通じて何らかのエラーが発生することになります。
- 画面はシステムの顔
- システムは画面だけではなくグラフィカルなUIを持たないバックエンドのサービスや色んな物の組み合わせで成り立っています。画面はシステムの一部でしかありません。
が、ユーザが直接見るのは基本的に画面です。そのためユーザは画面の操作性やカッコよさ(or ダサさ)を通じてシステムの良し悪しを判断することがあります。
- システムは画面だけではなくグラフィカルなUIを持たないバックエンドのサービスや色んな物の組み合わせで成り立っています。画面はシステムの一部でしかありません。
分散
- 相関ID
- 複数のサブシステムやサービスに分かれてシステムが成り立っている場合、特定のリクエストに対する各サービスの一連の処理を串刺しで確認したい場合があります。そのために、リクエストID(correlationId)等を発行してそのIDを各サービスに引き渡した方が良いです。
各サービスはそのIDをログに出力します。そうすることで繋がりを把握することができます。
- 複数のサブシステムやサービスに分かれてシステムが成り立っている場合、特定のリクエストに対する各サービスの一連の処理を串刺しで確認したい場合があります。そのために、リクエストID(correlationId)等を発行してそのIDを各サービスに引き渡した方が良いです。
- オフラインでも動作してほしい
- 分散したサービスが協調している場合、リクエスト先のサービスが落ちていることも十分にあります。相手先が落ちている状態でも自分自身のサービスは正常に動作し続けるべきです。
- 処理のブロッキング
- 意識してプログラムを書かない限りほとんどの場合は処理をブロックするコードを書くことになります。
分散して非同期で動作して協調するシステムの場合ブロッキングされている箇所は、ボトルネックになり問題を引き越す箇所になりやすいです。
- 意識してプログラムを書かない限りほとんどの場合は処理をブロックするコードを書くことになります。
- 物理的な距離
- データセンターを複数個所においてレプリケーションしている場合に、データセンターの物理的な距離に応じてデータが書かれてから冗長性が本当に確保されるまでに時間がかかることがあります。
- 障害の発生個所と原因箇所
- システムが複数のサービスに分割している状況では、障害が発生する(目に見える形でエラーが発生する)箇所と原因箇所は離れていることが往々にしてあります。
障害発生個所周辺だけを追っても原因にたどり着かないことがあります。
- システムが複数のサービスに分割している状況では、障害が発生する(目に見える形でエラーが発生する)箇所と原因箇所は離れていることが往々にしてあります。
バグのないシステムは無い
アプリケーションにバグがあるのは当然ですが、OS(カーネル)やミドルウェアやその他ファームウェアにも当然のようにバグはあります。
それらに対してどう付き合っていくかは当初から計画しておくべきです。
ネットワーク
- ボトルネックになる
- システム内で最もボトルネックになりやすい場所かもしれません。他の場所で性能が出ていてもネットワーク起因で上手く性能が出せないことは多々あります。
- 信頼してはいけない
- ネットワークはシステム内で最も信頼してはいけない場所です。運用中に何らかの通信が失敗する状況は必ずやってきます。
- リモート呼び出しとローカル呼び出しは別物
- リモート呼び出しでは、ローカル呼び出しになかった障害パターンが現れます。同じ機能を呼び出す場合もローカルで行うのかネットワーク越しなのかで考慮することは全く変わってきます。
データベース
- ボトルネックになる
- データベースは基本的にボトルネックになりやすい場所です。
- トリガー
- 開発者が把握していないトリガーを運用チームなどがDBにしかけてしまうと予期せぬ動きをすることがあります。把握していないトリガーが存在していると相当な混乱を生みます。
- データ量
- テーブルのレコード数が極端に増えた場合にSQLの実行計画が全く意図しないものになる場合があり、突然性能劣化する場合があります。
- 遅いクエリを監視する
- 遅いSQLがあると、システム全体がその遅さに引っ張られる場合があります。もともと問題なかったSQLがデータ量の増加などによって遅くなることがあります。遅いSQLが実行されていないか監視すべきです。
- インデックスが破損する
- インデックスが壊れる場合があります。インデックスの再構築が必要となります。
できるだけ自動化
- 可能な限り変更操作のSQLを直接実行させない
- データのメンテナンスが必要で、運用チームが手動でSQLを実行するケースがあります。
ただし、人間が介在すれば当然操作を誤る場合もあります。アプリケーションとしてのデータの整合性がとれない状況も発生します。
可能な限りアプリケーション側でデータメンテナンスの仕組みやツールを提供するべきです。
- データのメンテナンスが必要で、運用チームが手動でSQLを実行するケースがあります。
- 手動の作業はスケールしない
- 人の手が必要な作業はスケールしません。システムが大規模化していくと人手がかかる作業は漏れていく場合があります。
- 一度限りと思っていた作業も
- "こういうデータを抽出したい"という運用観点での要望が良くあります。一度限りならその場限りのSQLを組み立てたり、手動でデータを整形したりでも良いでしょう。
同じ依頼が再度来たらシステム化またはツール化することを検討した方が良いです。3度目4度目の依頼が来るのは確定です。
最低限でも手順化して、他の人にも任せられるようにした方が良いです。
- "こういうデータを抽出したい"という運用観点での要望が良くあります。一度限りならその場限りのSQLを組み立てたり、手動でデータを整形したりでも良いでしょう。
エラーコード・メッセージID
エラーや障害があった場合に、そのエラーを一意に特定するエラーコードやメッセージIDをログや画面に表示するべきです。
詳細なエラー内容やメッセージの文面しかないと担当者間で誤った伝言ゲームが発生して状況が正しく伝わらない場合があります。
状況を一意に示すID等があった方が伝達はしやすいです。また、国際化対応しているシステムの場合にもIDやコードだけ分かれば状況を把握しやすくなります。
データ
- 稼働当初が一番データが少ない
- ほとんどのシステムがシステム内に蓄えられるデータは増加していきます。稼働当初が最もデータが少なかったという状態が普通です。
当初のデータ量なら動いていても、1年後5年後のデータ量では性能が出なくなることもあります。
- ほとんどのシステムがシステム内に蓄えられるデータは増加していきます。稼働当初が最もデータが少なかったという状態が普通です。
- データの増加傾向を監視する
- 定期的に日単位、月単位、年単位でデータの増加量を把握するべきです。ディスクの残容量との兼ね合いもありますし、意図しない怪しい増加が無いかを確認しておくことも重要です。
- 削除する仕組み
- データを保管するというのもタダではありません。扱っているデータのサイズが巨大化した場合に必要のないデータを削除して、取り扱う量を減らす仕組みを検討すべきです
仮に削除しないにしても、アクセス頻度の低いデータは安価な保管手段に変更するなどの検討をする必要があります。
- データを保管するというのもタダではありません。扱っているデータのサイズが巨大化した場合に必要のないデータを削除して、取り扱う量を減らす仕組みを検討すべきです
- 去っていくユーザのデータの取扱い
- 提供しているサービスに不満がありユーザが契約を切る(契約を更新しない)場合もあります。そうしたケースにおいてシステム内に蓄積された対象ユーザのデータをどう扱うのかは当初から取り決めておく必要があります。
- テストデータ
- 運用時は利用しないが、運用前の試験時に負荷をかける目的などでテストデータを用意する場合があります。
このテストデータが誤って運用中のシステム内に送られてしまうケースがあります。できれば、データのID等(テストデータと識別できる情報)でフィルタリングできる仕組みなどを設けておいた方が安全です。
- 運用時は利用しないが、運用前の試験時に負荷をかける目的などでテストデータを用意する場合があります。
データ移行
完全に新規のシステムやサービスで無ければ基本的に何らかのデータ移行が発生します。
移行のパターンとして以下のようなものが考えられます。
- 他システムからの移行
- 他システムへの移行
- 既存システムから新システムへの移行
データ移行に関しては、移行元のデータをどのように受け取るのかとどう出力するのかのインターフェースが重要です。
また、インターフェース以外にも以下の点についても考慮が必要です。
- データ移行にかかる費用。その費用を誰が負担するのか
- データ移行にかかる期間
- データ移行がシステムへどのような負荷をかけるか
- データ移行時にシステム停止が伴うか?
- データ移行が正常に完了したこと(移行元と移行先で不整合になっていないか)をどのようにチェックするのか?
結合・接続部分
他社サービス、他システムや他プロダクトとの結合点・接続部分は色々と考慮してもしきれません
- 絶対に問題が発生する場所
- 他システム・他サービスなどと連携している箇所は運用後に絶対にエラーが発生します。結合部分でのエラー処理は必須です
- 意図しないエラー
- 他システムとは取り決められたインターフェースでやり取りします。決められたエラーコードなどに基づいたエラーハンドリングも組み込むでしょう。
が、運用後には取り決めに無かったエラーが突然返ってきます。それにもアプリケーションは対処できる必要があります。
- 他システムとは取り決められたインターフェースでやり取りします。決められたエラーコードなどに基づいたエラーハンドリングも組み込むでしょう。
- 耐えられない量のリクエスト
- 誤って大量のリクエストを投げる場合もあります。リクエストを受ける側は何らかの流量制御して自分自身がダウンしないようにする必要があります。
- タイムアウト
- リクエスト先からエラーが即時に返ってくれば良いですが、場合によってはいつまでたっても応答が無い場合もあります。必ずタイムアウトできる仕組みを入れるべきです。
そうしなければスレッド全部を使い切ってサービスがダウンすることにもつながります。
- リクエスト先からエラーが即時に返ってくれば良いですが、場合によってはいつまでたっても応答が無い場合もあります。必ずタイムアウトできる仕組みを入れるべきです。
- リクエストしすぎて攻撃とみなされる
- 他社サービスに短時間に大量のリクエストを投げたことによって、相手側に攻撃とみなされ、リクエストの受け付けが拒否されてしまう場合があります。
リトライ
- 短い間隔で無限リトライすると攻撃と同じ
- リクエストを受ける側のサービスがダウンしている場合に、クライアント側はリトライすることでしょう。
しかし、短い間隔で無限にリトライを繰り返すとシステム全体への負荷になり、場合によってはシステムをダウンさせる原因にもなります。
- リクエストを受ける側のサービスがダウンしている場合に、クライアント側はリトライすることでしょう。
- べき等性
- 何らかの理由でクライアント側が全く同じリクエストを複数回送信してくることがあります。リクエストを受けた側はそれでも正常に動作して同じ結果を生み出すべきです。
監視・復旧
- システムの負荷の周期性
- 基本的にはシステムにかかる負荷(CPU負荷、ネットワークトラフィック、メモリの使用量・・etc)には、一定の周期があります。(平日のこの時間帯はCPU負荷が高い、夜間の特定時間帯はネットワークトラフィックが多い 等)
その周期性から外れた予想外の負荷状況が発生していないかを日単位、週単位、月単位で確認した方が良いです。
- 基本的にはシステムにかかる負荷(CPU負荷、ネットワークトラフィック、メモリの使用量・・etc)には、一定の周期があります。(平日のこの時間帯はCPU負荷が高い、夜間の特定時間帯はネットワークトラフィックが多い 等)
- 自動復旧
- よほど単純なサービスやアプリケーションでなければ、長期間稼働する中でダウンする時はダウンします。
重要なサービスであれば、対象のサービスのプロセスを監視して、ダウンしていれば自動復旧させるなどの仕組みを検討した方が良いです。
- よほど単純なサービスやアプリケーションでなければ、長期間稼働する中でダウンする時はダウンします。
- ユーザより先に気づく方が良い
- 監視の仕組みでシステムの障害予兆を把握できた方が、ユーザから連絡により障害を気づいた場合よりも対処のコストは圧倒的に下がります。
- 監視サービス自体がダウンしないように
- システムを監視する側のサービスがダウンしてしまうと、システムが本当に正常に稼働しているのかどうか分からなくなります。
監視サービス自体がダウンしない(ダウンしても自動復旧する)ような仕組みが必要です。
- システムを監視する側のサービスがダウンしてしまうと、システムが本当に正常に稼働しているのかどうか分からなくなります。
アプリケーションの実行状況把握
- ヘルスチェック
- アプリケーションが正常に稼働しているかどうかをチェックするための口を設けた方が良いです。監視サービスから定期的にそのヘルスチェックを実行するのも一つの監視となります。
- 処理の進捗状況
- 時間のかかる処理や、大量のリクエストを扱う処理などは、その処理の進捗状況(処理が詰まっていないか)が分かる仕組みがあると良いです。
キューの残数、ダウンロード状況など。
- 時間のかかる処理や、大量のリクエストを扱う処理などは、その処理の進捗状況(処理が詰まっていないか)が分かる仕組みがあると良いです。
- アプリケーションのバージョン
- 実際にシステムにデプロイ(インストール)されているアプリケーションのバージョンがいくつなのかを把握できるようにすべきです。
アプリケーション(サービス)に問いかけると自身のバージョンを応答してくれるようになっていると扱いやすいです。
- 実際にシステムにデプロイ(インストール)されているアプリケーションのバージョンがいくつなのかを把握できるようにすべきです。
システムは安定稼働している?
システムが安定稼働しているように見えるが本当にそうなのか?
システムの現在の状況は以下のいずれの状態なのか?
- システムは安定稼働しており、負荷についても余裕がある。ユーザも何の問題も無く利用できている。
- 現状は正常に稼働している、しかし実は後わずかで負荷が閾値を超えてシステムが正常ではない状態に陥ろうとしている。
- システムに遅延が発生しているが、運用側で設定した閾値は超えていない。しかし実は、ユーザ(利用者)はシステムの遅さに苦痛を感じている。
- 自システムは正常に稼働している、が、連携する他システムが障害を起こしている。ユーザは、私たちのシステムを通じてエラーを体験している。
- 異常が発生しており、監視サービスにより通知もされている。が、運用側の人間がエラーを無視している。
- 監視の仕組みの漏れにより、異常が起こっていることに気付けていない(エラーが埋もれている)。
バックアップ
- リストアできないと意味が無い
- 定期的なバックアップはシステムにとって必須です。バックアップはできている(はず)だが、そのバックアップしたデータでリストアはできますか?
もしくはリストアするのにどれだけの時間を要しますか?リストア中に発生した整合性の取れていないデータを整合が取れる状態にできますか?
- 定期的なバックアップはシステムにとって必須です。バックアップはできている(はず)だが、そのバックアップしたデータでリストアはできますか?
- バックアップ処理による負荷
- システムによってはバックアップするデータのサイズが巨大化する場合があります。バックアップ処理そのものがシステムに負荷をかける場合もあります。
単一障害点
その一箇所が動かなくなるとシステム全体がダウンするような単一障害点(Single Point of Failure)は当然ない方が良いです。冗長化するなど何らかの方策が必要です。
この点はシステム上の話だけではなく、人にもいえます。対象のサブシステムについて詳しい人が一人しかいない場合、その人が長期休暇を取るのが危険という場合があります。
日ごろから人間側の冗長性も確保すべきです。
スケール・国際化
- 最初からスケールする仕組みを組み込む
- システムのスケールについては当初から計画しておく必要があります。後付けでのスケールはかなり難しくなります
1000リクエストに対応できていたサービスにおいて、(後付けで)サービスが稼働するサーバの台数を単純に増やしても1000万リクエストには耐えられない場合があります。
- システムのスケールについては当初から計画しておく必要があります。後付けでのスケールはかなり難しくなります
- グローバルにやる予定なら
- 対象のサービスをグローバルに展開する予定があるのなら最初から国際化の対応をしておくべきです。後付けで国際化しようとするのは結構な労力になります
- 展開する地域が増えたときのリクエスト量の増加
- サービスを展開する国や地域が追加された時に、リクエストの増加がそれまでの伸びとは関係なく激増する場合があります。
例えば中国などの人口の多い地域に展開した際にはそのような可能性があります。
- サービスを展開する国や地域が追加された時に、リクエストの増加がそれまでの伸びとは関係なく激増する場合があります。
- 小規模ユーザーに対して提供できるか
- (主にBtoBのサービスにおいて、)サービスの初期ターゲットが大規模ユーザであった場合でも、サービス拡大とともに小規模ユーザへのサービス提供も必要になってくるケースがあります。
この際に、サービスのビジネス的な設計がうまくいっていないと、小規模ユーザへのサービス提供が金額的な面などで折り合わないことがあります。
小⇒大のスケールだけではなく、大⇒小のスケールのさせ方も考慮しておくべきです。
- (主にBtoBのサービスにおいて、)サービスの初期ターゲットが大規模ユーザであった場合でも、サービス拡大とともに小規模ユーザへのサービス提供も必要になってくるケースがあります。
法的要求事項・ガイドライン/監査
- 要求事項
- システムによっては法的な要求事項や国が定めたガイドラインに準拠しなければならない場合があります。
これらの内容も年々変わっていく場合があり、追従していく必要があります。
- システムによっては法的な要求事項や国が定めたガイドラインに準拠しなければならない場合があります。
- IaaS系クラウドサービスの利用
- クラウドサービスによっては、物理的なサーバが隠蔽されているだけではなくそのサーバが存在するデータセンターの所在が非公開になっている場合があります。
通常は特に問題になりませんが、データセンターの監査を受ける必要が出てきた時にこれではNGとなる場合があります(所在不明のため監査ができない)
- クラウドサービスによっては、物理的なサーバが隠蔽されているだけではなくそのサーバが存在するデータセンターの所在が非公開になっている場合があります。
- 法によるデータの存在場所のしばり
- システムにかかわる法律やガイドラインによって、データを管理してよい場所(国)が限られる場合があります(例えば、日本にしかデータを置いてはいけない等)
このような状況では例えば、クラウドでアメリカなどのリージョンを指定できないことになります。
- システムにかかわる法律やガイドラインによって、データを管理してよい場所(国)が限られる場合があります(例えば、日本にしかデータを置いてはいけない等)
- 監査ログ
- ユーザ操作を監査ログとして永続化して通常のアプリケーションログとは別に管理する場合があります。監査ログを追うことでユーザが何をしていたのかが明らかになります。
- 法定停電
- ビルなどは点検のために定期的に停電する日が必ず来ます。ユーザー環境にシステムに関する機器があるなら、電源が落ちる日が定期的に来ます。
改善したら悪くなった
システム(サービス)を良かれと思って改善したら結果的にユーザにとっては改悪になってしまったという場合もあります
- バグによる挙動を改修したが、ユーザにとってはそれが既に仕様となっていてやりたいことができなくなってしまった。
- デフォルトの挙動をより良いと思うものに変えた、ユーザにとっては動きが勝手に変わってしまって業務効率が落ちた。
- 速度に問題の合った箇所を改善したら別の場所が改善後の速度に耐えられずハングした。
知識の共有
- リリースした機能を共有する
- 開発チームと運用チームが分かれている場合に、新しくリリースされたアプリケーションの変化を運用チームが把握できない場合があります。
定期的にチームを超えて情報を共有する場を設けるべきです。
- 開発チームと運用チームが分かれている場合に、新しくリリースされたアプリケーションの変化を運用チームが把握できない場合があります。
- 暗黙知を無くす
- サービス稼働後に走りながら障害対応やデータメンテナンス等を行っていくと暗黙知が溜まっていきます。暗黙知が当然の状態になってしまうと、チームに新しい人が加わっても上手くパフォーマンスが発揮できません。
得られた知見はドキュメト化してチーム内に共有する必要があります。
- サービス稼働後に走りながら障害対応やデータメンテナンス等を行っていくと暗黙知が溜まっていきます。暗黙知が当然の状態になってしまうと、チームに新しい人が加わっても上手くパフォーマンスが発揮できません。
- 現場の対応をドキュメント化
- 運用中に緊急でその場限りの対応(設定を変更した、再起動のcronを仕掛けたetc)をする場合がありますが、そのような対応が結果的に恒久策になっている場合があります。
ただ、これらの対応がドキュメント化されていないと後の運用・保守において混乱を招くことになります。
- 運用中に緊急でその場限りの対応(設定を変更した、再起動のcronを仕掛けたetc)をする場合がありますが、そのような対応が結果的に恒久策になっている場合があります。
競合
- 参入障壁が低いと
- 構築したサービスの参入障壁が低いとすぐに競合サービスが出現します。他社サービスの状況を観察する必要がでてきます
- 競合サービスがダウンした際の自サービスへの影響
- BtoCのサービスにおいてシェアが同規模の競合サービスが存在する場合に、何らかの理由で競合サービスのシステムがダウンすると、一気に自サービスにユーザが流入してくる場合があります。
その際には予定しない負荷がかかることになります。
- BtoCのサービスにおいてシェアが同規模の競合サービスが存在する場合に、何らかの理由で競合サービスのシステムがダウンすると、一気に自サービスにユーザが流入してくる場合があります。
コスト
- 運用にかかったコスト
- クラウドのサービスに払った費用だけではなく、パッチを当てる対応や障害時の対応等にどれだけの人的リソースが投入されたかも把握しておくべきです。
- サービスによってコストが違う
- IaaS系クラウドサービス等は、サービスごとに発生する費用のモデルが違います。CPUの使用時間、データの蓄積量、通信量など何に対して課金されるのかが異なってきます。
提供するビジネスモデルに応じてコスト計算しなければ、とんでもない費用を払わなければならない事態になる場合もあり得ます。
- IaaS系クラウドサービス等は、サービスごとに発生する費用のモデルが違います。CPUの使用時間、データの蓄積量、通信量など何に対して課金されるのかが異なってきます。
システムへ影響を与えるシステム外のイベント
アプリケーションやシステムそのものではどうにも対処しきれないが、場合によってはシステムに悪影響を及ぼすものがあります。
- 落雷
- 停電
- 地震
- 洪水
- 火災
- 空調の故障による温度異常
- ネットワークケーブルが切断
- 電圧降下
必ずしも悪影響を与えるわけではないが、念頭に置いておいた方が良いものとして以外
- うるう年
- うるう秒
- うるう秒挿入時にOSが暴走するケースなどもあります
- 年号が変わる
- サマータイム
- 日本ではほぼ無縁ですが、これが絡んでバグを発生させるライブラリが存在したりします。
まとめ
ユーザの要求を満たす機能を提供するプログラムを書くだけでは、システムを作り上げて運用に耐えられるということにはなりません。
もう少し高い位置からの視点が必要になりますね。
色々雑多な感じで書きましたが、ものによってはシステム稼働後に追加で対応できるものもあります。しかし、稼働前から考慮しておかないと厳しいものもあります。