本番障害発生時に元請けSIerで発生する作業とその影響

社会インフラを支えるシステム、例えば金融システムや公共システムについては、高い信頼性が求められます。
このようなシステムの本番運用で障害が発生した場合、その結果は重大なものになります。
一般的なイメージとして、その「重大なもの」として、以下のようなものをイメージすると思います。

  • 信頼が失墜する(最悪の場合は報道される)
  • 経営者がお客様に怒られて、責任者が経営者に怒られて、技術者が責任者に怒られる
  • 技術者や責任者が缶詰になる

この記事では、本番運用で障害が発生した場合に、元請けSIerで一体何が発生するのか、元請けSIerのプロパーであった私の経験を交えて、より具体的に書いていこうと思います。
そして、具体的に何が起こるのかを知ることで、品質向上の意識を高めていただければと思います。


【障害の検知】

障害を検知する契機として、「お客様に指摘される」という契機で見つかるのは最悪です。
事前にSIer側で障害を発見できなかったためにお客様の心象が悪くなることで、その後の要求(障害対応、再発防止、補償)が厳しいものになるためです。
また、お客様に指摘されているということは、既にデータが作成されて、「画面」「帳票」といった形でお客様の目に触れているので、そのデータを補正しなければならないということで障害対応の作業内容の難易度も上がります。

そのため、お客様に見つかる前に障害を検知する努力を惜しまず行うべきです。
異常なデータが発生した時点でその箇所の処理を停止させれば、運用作業でその箇所だけ補正して対応することができます。
エラーハンドルが重要であるとされるのはこのような理由からです。
また、この運用作業は人手で行うこととなりミスが発生しやすいので、システムを構築する場合は、運用作業を予め計画して手順化することでミスの発生を抑える努力も重要になります。
システム改修直後は障害が発生する可能性が高いので、すぐに障害対応できるように、改修直後の監視体制を敷くことも重要です。

なお、システム改修の結果、思いもよらぬ箇所に影響が発生し、重点的に監視していない箇所で障害が発生しお客様に指摘されるというのも良くあることです。
影響調査を抜け漏れなく行うことも重要になります。

【障害の対応方針の検討】

障害が発生した場合、どのような障害が発生したのか、その事象内容と原因をお客様に報告する必要があります。
そして、システムの都合の観点と、お客様の業務の継続の観点から、対応方針をすり合わせることになります。
検討している間にも障害は発生し続けているので、検討は迅速に行う必要があります。

システムの都合の観点で言うと、障害対応でプログラム作成が必要なのであればその期間を見る必要がありますし、プログラムを実行・リリースするタイミングも計る必要があります(サービス停止日にしか実行・リリースできないことも多いです)。
それまでの間の暫定対応(運用作業)の計画も立てる必要があります。
そして、暫定対応はお客様の業務を継続する上で必要なレベルを満たす必要がありますし、恒久対応では元々求められていたレベルに戻す必要があります。暫定対応中に制約や機能制限が発生するのであれば、そのことについてもお客様の了承を得る必要があります。

なお、この時点で明らかに対応するべきことがあれば、責任者の許可を取った上で、技術者は検討中にも対応し続ける必要があります。
手順書に書かれた作業や、その他常識的に行うべき作業(例えばディスク容量オーバーでシステムが落ちたのであれば不要データの削除とシステム再起動)がそれに該当します。

【暫定対応の実施】

検討された方針に従って、暫定対応を行います。
この作業は基本的に手作業での運用になることが多いため、運用担当者を立てて体制を整える必要がありますし、運用作業でのミスが無いように手順書や簡易ツールを作成する必要もあります。
また、暫定対応中に制約や機能制限が発生するのであれば、そのことを説明する文書の作成と周知という事務作業も発生します。

【恒久対応の実施】

プログラムの作成が必要なのであれば、それを作成する担当者を用意して工数を割り振る必要があります。
そして、プログラムの本番環境での実行・リリースに向けた準備(手順書作成、社内手続き等)も必要になり、また実行・リリースに向けた出社体制を整える必要も出てきます。
お客様の立ち合いが必要なのであれば、お客様にも立ち合いを依頼する必要があります。

【再発防止策策定】

恒久対応が完了した後、お客様へ恒久対応完了の報告を行います。
しかしそこで終わりではなく、今後同じようなことが起こらないように、障害が発生した要因の報告と、再発防止策の策定を求められることが多いです。
社内での再発防止策の検討、そして再発防止策の説明にまた工数を取られることになります。
また、再発防止策は、チェック体制の強化に繋がることも多いので、それが積み重なると開発スピードの低下にも繋がりかねません。
(多くの開発者にとってストレスになるであろう、重厚長大なチェックリスト、煩雑な承認体制、頻繁なダブルチェック・トリプルチェックは、再発防止策が積み重なって出来上がるものです)

【障害に対する金銭的な補償】

障害が発生した場合、SIer側が金銭的な補償をしなければならない場合もあります。
システムのSLA(サービス内容に関する合意文書)に補償に関する項目があるなら、それに従って補償をしなければなりません。
重大な障害である場合は、裁判で損害賠償請求されることもあります。

仮に、直接的な補償がなかったとしても、障害を発生させたことでその後の交渉でSIer側が不利になり、システム継続利用時に値下げ要求をのまざるを得なくなることも少なくありません。
ニュースで報道された場合は、直接被害が発生していないお客様との交渉でも不利になりやすくなります。
当然、競合システムに離反されることもあり、この場合も収益の低下に繋がります。


以上のように、本番障害を発生させることで、SIer側には以下のような損害が発生します。

  • 障害対応や再発防止策のための工数の発生
  • 再発防止策による開発スピードの低下
  • 障害に伴う金銭的な補償

本番障害が頻発する現場では、不定期に発生する障害対応・再発防止策の工数と開発スピードの低下が原因で、次のシステム開発にも支障が発生し、QCD(品質・コスト・納期)のバランスを取ることが困難になります。
障害に伴う補償をしただけでなく次のシステム開発も予定通りに進めることができなくなるため、収益力が低下することになります。
頑張って長時間働いても、それに見合う収益を得ることができなくなってしまいます。

このように、本番障害を発生させることによる損害は誰にとっても大きいため、本番障害を発生させないように一人一人が意識する必要があります。
障害を発生させた経験から学ぶという姿勢ではなく、社内外の過去の障害事例から学ぶ姿勢が重要になります。


いかがでしたでしょうか。

2次請け以降の立場で案件に参画していると、本番障害発生時に何をしているのか伺い知れない所が出てきます。
この記事により、その情報を上手く共有できれば幸いです。

来年も、この調子でブログを更新していこうと思います。
では、良いお年を!

データレコードの種類を増やして拡張性を持たせる

以前に書いた「ヘッダレコード・データレコード・トレーラレコードとは」の続きです。


企業間でやりとりするファイルでよく見かけるフォーマットとして、レコードが「ヘッダレコード」「データレコード」「トレーラレコード」に分かれているフォーマットがあります。
簡単に言うと、それぞれのレコードの説明は以下のようになります。

【それぞれのレコードの説明】

・ヘッダレコード

ファイルの1レコード目のレコード。
一般的には、そのファイルが何日のデータなのかが記述される。

・データレコード

ファイルの中間レコード。
実際にやりとりするデータの中身が記述される。

・トレーラレコード

ファイルの最終レコード。
一般的には、そのファイルのデータレコード件数が記述される。


ここで、拡張性を確保するために、データレコードの種類を増やすという手段が有効になることがあります。
種類が異なるデータレコードをファイルに含める場合、データレコードのフォーマットを変えてしまうと、フォーマットが複雑になることで書き込み・読み込み処理が複雑になったり、フォーマット変更時の影響が全種類のデータレコードに出てしまったりします。
しかし、種類毎にデータレコードを用意することで、1つ1つのフォーマットが複雑になることを防いだり、フォーマット変更の影響が当該種類内のデータレコードに限定させることができます。

フォーマットと処理の例としては以下の通りです。
商品の種類毎にデータレコードの種類を変えることで、データ体系の違いを吸収している所がポイントです。
(1つのデータレコードにしてしまうと、1つのデータレコードに「食品商品コード」と「玩具商品コード」が含まれることになり、どちらを書き込むか・読みこむかの判断が必要になってしまいます。また、食品若しくは玩具にだけ新たな項目を追加する時に、追加が必要無い方の種類の商品の考慮も必要になってしまいます。)

【フォーマット例】

取扱商品ファイルを想定した例を記載します。
可変長のCSVファイルを想定します。
(固定長の場合も多いです。固定長の場合は、カンマ区切りではなくバイト数で区切ることになります。)

・ヘッダレコード

1項目目:ファイル区分(1がセットされる)
2項目目:ファイル作成日付(YYYYMMDD)

・食品データレコード

1項目目:ファイル区分(2がセットされる)
2項目目:食品商品コード(7桁の数値)
3項目目:商品名(全角文字)
4項目目:値段(数値)

・玩具データレコード

1項目目:ファイル区分(2がセットされる)
2項目目:玩具商品コード(6桁の数値)
3項目目:商品名(全角文字)
4項目目:値段(数値)

・トレーラレコード

1項目目:ファイル区分(9がセットされる)
2項目目:データレコードの件数(数値)

【ファイルのレコード例】

【ファイル受信時の処理例】

ヘッダレコードやトレーラレコードは、受信側のチェック処理に利用できます。
以下、ファイルを1レコード目から順番に読む場合の処理例について記載します。

・ファイル区分が1の時

1レコード目がファイル区分1でなければ異常終了。
(送信側が中間ファイル等誤ったファイルを送信することを想定)
バッチ日付と比較し一致しなければ異常終了。
(送信側が誤って過去ファイルを送信することを想定)

・ファイル区分が2の時

業務上必要な食品向けの処理を実行。

・ファイル区分が3の時

業務上必要な玩具向けの処理を実行。

・ファイル区分が9の時

最終レコードのファイル区分が9でなければ異常終了。
(ファイルを全件受信できていないことを想定)
件数がファイル区分2~3のレコード数と一致しなければ異常終了。
(ファイルを全件受信できていないことを想定)


いかがでしたでしょうか。

このテクニックは、レガシーなシステムでは良く使われるテクニックです。
レガシーなシステムの設計をする場合に、もしかしたら役に立つことがあるかもしれません。

システムの概要を示す設計書が本当に必要な設計書である

表題の通りですが、システム開発で本当に必要な設計書は、システムの概要を示す設計書です。
そのような設計書があれば、実装を知らない立場の人(例えば要件定義担当や上位の設計者)との意思疎通がスムーズになりますし、開発者を新たに向かい入れる時にも実装の内容をスムーズに理解してもらえるようになります。


例として、在庫確認モジュールを開発しているとします。
具体的な実装としては以下のイメージとします。
実際には、「:」の箇所に数行~数十行のコードが書かれているイメージです。

【実装イメージ】


良くない設計書の例としては、以下のようなものがあります。
(残念ながら、実務でも見かけることがあります)

・ソースコードと1対1対応の設計書

ソースコードを1行1行日本語に訳したような設計書は良くありません。
そのような設計書は記述量が多くなり、作成するのも大変ですし、それを読んで内容を理解するのも大変です。
また、日本語(自然言語)は意味が曖昧になりがちなので内容も不正確になります。
更に、ソースコードに些末な変更を行う度に、設計書の更新も必要になるという問題もあります。
(設計書の更新を忘れると、設計書を信用できなくなる)

・見た目だけで内容に乏しい設計書

経験が浅く見様見真似で設計業務に当たっている場合、以下の絵のような見た目だけで内容に乏しい設計書を作成しがちです。
(この例の絵は少し誇張しすぎですが)

しかし、設計書はかっこ良く見せる資料ではなく、実装に直接的・間接的に関わる人と意思疎通を取るための資料なので、実装内容が早く正確に伝わればそれで良いです。
どのような設計書を作れば良いかイメージが付きにくい場合は、現現場の既存の設計書や他現場の設計書を参考にしたり、先輩社員に聞いたりすると良いでしょう。


システムの概要が早く正確に伝わる設計書が良い設計書です。
例えば、以下のような処理概要を掴めるフローチャートは良い設計書です。

このような設計書があれば、要件定義担当や上位の設計者が全体像をつかみやすくなり、レビュー(要件や全体の設計の観点から見て問題がないことの確認)が捗ります。
また、新たに開発者を向かい入れる場合にも、モジュールの全体像を掴んでもらってから、必要に応じて細かい箇所を確認してもらうことができるようになります。


いかがでしたでしょうか。

良い設計書を書けるようになることが、PGからSEへのステップアップの鍵です。
システムの概要を示すことを意識することが重要で、それを意識しながら実務にあたると、自ずと良い設計書が書けるようになるでしょう。

JavaScript:オブジェクト型の定数値にはObject.freeze()を使う

プリミティブ型(Number型やString型等)の変数は、constで定義することで変更不可にできます。
これを利用して、定数値を定義することができます。

【サンプルコード】

【ChromeのデベロッパーツールのConsoleで実行】


しかし、オブジェクト型の場合、constで保持されるのは変数が指し示すアドレスであり、値は変更可能です。
そのため、定数値を定義するには適していません。

【サンプルコード】

【ChromeのデベロッパーツールのConsoleで実行】


オブジェクト型で定数値を定義したい場合は、Object.freeze()を使う必要があります。
これを使うことで、オブジェクト型の変数が指し示す値を変更不可にすることができます。

【サンプルコード】

【ChromeのデベロッパーツールのConsoleで実行】


いかがでしたでしょうか。

コーディングミスがない限りは定数値を書き変えることはないためお作法的なものに近いのですが、覚えておいて損はない内容でしょう。

来週以降は、コーディングからは一旦離れて、暗黙知的なものや経験則的なものを記事にしていきたいと思います!