救急室(3)-プログラム構造

ログ解析の話まで、してきましたが、ログの出力元であるプログラムの概要について話します。

プログラムにできる事は、情報を蓄える事と分類する事、そして見せる事です。

昔の機能設計書は、

  1. Input
  2. Function
  3. Output

上記のように書かれていました。入力したものをどう処理して、出力するのか。現代のシステムではもっと複雑になっているように感じるかもしれません。先日のdocomoの障害も、スマートフォンからいろいろな種類の通信が同じ回線上に流れ、それを分類する機器で障害になったり分類した機器の処理性能がパンクして障害が起きています。
発生原因は分岐であったり、ぶん回す際の処理性能と難しいものではありません。また通信機器にもプログラムは内在しています。

話をもどして複雑に感じるのはIn,Func,Outを一つの処理とした場合、複数の処理をまとめたものが誰かにより提供され、その提供されたものをさらにまとめているからです。昔はCPUやメモリを意識してプログラミングしてきましたが、今は気にしません。足りなければCPUやメモリを増やせば良くて、まとめる事による無駄な部分は放置されてきました。放置というと乱暴ですね。見れる人が少なくなってきたという事と見れる人とそれを使用している人とのコミュニケーションがとりづらくなってきたというべきでしょう。

最近も、主流になっているjavaのエラーは20行ほど、出力されます。20行は同じ階層にあるわけではなく、各階層毎に1行でていますので、javaアプリの中だけでも20階層になっている事になります。全て違う人が書いている可能性はなくはないので、20人のプログラマーが悲鳴を上げた事になります。そして20人の人達が、書いているのは、その階層における In,Func,Out になります。

In,Func,Outをもう少し詳しくいうと、Inは無条件にかき集め、目的であるOutに向けて形成し出力します。あえて無条件と書いたのは、以外とInに条件がついている事が多いからです。きちんと形成されたInを渡すようにとなるのですが、ここでコミュニケーションの問題があります。Inを無条件にするには、まず補足する必要があります。これが初期値というものです。Inに含まれていなければ、自身が想定した値を使用するというやり方ですが、同様にコミュニケーションの問題があります。

Funcで、できる事は昔も今も変わらなく入門でで習う、分岐と繰り返しです。分岐はInがAだったら10にしてBだったら20にするというものですが、じゃあCだったら?わからないとなったり、CもDもA、B以外だったら100だ!という書かれ方が多いです。障害は当然、C、Dがきた場合になります。
繰り返しは、ときにエラーではなくシステム停止になる場合があります。肝心なのは何回繰り返すのかなのです。固定であればいいかというと、例えば10件のInに対し20件分繰り返すのは、止まってしまうか一番最後の1件を10件分繰り返していたりします。繰り返し回数を可変にするには、まず分岐により何回繰り返すかを決めて、それから繰り返す事になりますが、分岐で判断ミスすると無限ループになる事があります。無限ループは高速でCPUをぶん回しますので、他の処理を全てとめてそのうちサーバも停止します。停止できない事もあり、その時は電源を抜くしかありません。
Funcでは情報量の問題もあります。10文字分のデータをFuncでは100倍の1000文字分に変換する。ユーザIDにユーザの名前情報を付加したり、そんな処理です。画面など人が入力する機能で使用される分にはたいした問題はありませんが、夜間のバッチ処理といった集計処理で何万件も扱うところで使用するとメモリがなくなり、システムは停止します。かといって、最大1000件までと初期値に設定されて採用されてしまうとその処理は問題なくても、まとめた上位の処理ではエラーでもなくやけに少ないという違う問題に発展します。

単純な事を組み合わせて複雑な処理実現しているのですが、ログは複雑な事を考慮する事はできず、単純な機能で、値C、Dは知らないとか、1000件超えてますよと、ぶっきらぼうに表現しています。一方、複雑なところでのログはよく、嘘をつきます。Inを与えた側の人はそのInに問題があると認めたがらないので、エラーになったのはあんたなんだからといった攻めるようなエラーになっていたり、まじめに考えず、他のエラーと同じものとして扱っていたりします。

プログラマーは徹夜が多いので、ついやってしまう事があります。開発中は許されないのですが、障害を考える場合は、そういう状況下で作られた事を理解するべきと思います。