スポンサーサイト

一定期間更新がないため広告を表示しています

| - | - | - |

Apache Struts2脆弱性事件のこと(S2-045, S2-046)

事象

3/6に脆弱性S2-045 (CVE-2017-5638)が公表されて以来、3/10に公表されたGMOペイメントゲートウェイ (GMOPG)を皮切りに、複数の企業・団体で、情報漏洩が発覚した。

日本語情報として、以下が掲載されたのが3/8〜3/9で、GMOPGが調査を開始して、Web Application Firewall (WAF)での不正リクエストの遮断および、システムを全停止してネットワーク未接続状態にあったバックアップシステムへの切替えを行ったのは、3/9夜から3/10未明とのことなので、対応は極めて迅速だったと思われるだけに、被害が出てしまったことは残念に思われる。

他の企業・団体では、概ね一週間程度で対策完了した様子である(LAC)。比較的速やかに対策が進んだのは、以下の事情があったためと思われる。

GMOPGが、速やかにセキュリティインシデント発生を外部に公開したことは、被害の拡大防止に大きな効果があったことだと思う。しかし、対策着手から実施までに数週間掛かってしまい、事故を起こしてしまった事例(JINS)もあったことから、いかに早急に本番適用できるかが重要であったかがわかる。

脆弱性S2-045とStruts2について

この事象S2-045は、リモートコード実行(RCE)に分類される脆弱性で、リクエストヘッダの'Content-Type'に仕込まれたコードがそのまま実行されてしまうというものだ。その後、'Content-Dispostion' / 'Content-Length'でも同様の事象が発生することが報告された(S2-046)。通常、Javaの場合はコンパイル型言語なので、この手の脆弱性が顕在化することは少ないのだが、Strutsの場合は、Object-Graph Navigation Language (OGNL)という式言語が導入されており、インタープリタ型言語のように記述されたコードを動的に実行できて、これが脆弱性の温床になっているらしい。

そもそも、Struts2は、J2EE時代にデファクトスタンダード的な位置づけであったStrutsが古びてきたことから、最新のJavaEE仕様を活用して、生産性を高めることを目的として開発しなおされたものであるが、以下のような理由で、Struts 1.x系ほどには普及しなかった。

  • Struts 1.x系と互換性が無かったこと
  • JavaEE自身がフレームワークとして充実してきたこと
  • Spring MVCをはじめとしたモダンなフレームワークが多く登場したこと
  • 脆弱性が多かったこと

上記のようなことから、2017年現在では、システム開発に当たってStruts 2.x系を敢えて選択することはまず無いと思われるが、2007年2月のStruts 2.x系初版GA以降、2013年4月にStruts 1.x系がサポート終了(EOL)する前後の時期までに開発されたシステムでは、Strutsの名前を継承したフレームワークであったこともあり、採用されることがそれなりにあった。

この事件の教訓

適切な技術・製品を選択すること

結果だけ見ると、当時、Struts2を選択したことは、最良の判断ではなかったと言って良いと思う。もちろん、それは結果論・後知恵であるし、Struts2に限らず、なんの製品・技術についても、そして誰しもが遭遇し得ることである。

しかし、なるべくこのようなことにならないように、何らかの技術・製品を採用するときには、機能要件を満たすかどうかだけではなく、「製品ドキュメンテーション・サポートは十分か」、「十分に枯れていて安定しているか」、「ユーザーグループは活発か」、「業界トレンドに沿っているか」、といった評価・判断が必要であると云える。

セキュリティ・インシデント発生時に速やかに対応するための能力

そして、何を選択するにしても、脆弱性は日々発見されているわけであるから、今回の、脆弱性情報の公開から最初の大規模被害が報じられるまでの時間の短さを鑑みるに、少なくともインターネットに公開されたシステムを持つ企業では、以下の能力が必要だと云える。

  1. 自システムを知っていること
    • 各システムで使われている製品・バージョンを把握しておくこと
    • 各システム・各製品のサポート担当者を明確にしておくこと
  2. 脆弱性情報をタイムリーに知れること
    • 当該製品の脆弱性情報をタイムリーに入手できること
    • 脆弱性情報の深刻度・優先度を正しく判断できること
  3. 脆弱性情報に対して、該当するかどうかの調査・判断を迅速に行えること
  4. 暫定対応策を速やかに本番適用できること
    • コードの変更・ビルド・リリースを迅速に行えること
    • 変更後のテストを迅速に行えること
  5. 最悪の場合は、システムを停止する判断を迅速に行えること

速やかに対応するために必要なこと

上記の能力を実現するためには、「システム部に必要な能力を持つ要員を必要な量だけアサインすること」、「システム変更・システム停止を含む判断を迅速に行える権限を与えること」が必要になる。

特に権限については重要で、通常の、「書類を作って、エビデンスを添付して、承認印を回して、会議して」、といったプロセスを何週間も経ているようでは間に合わない。できるだけシステム稼働させたいユーザ部と、情報漏洩するくらいならシステム停止したい経営側との要求が競合するため、システム部が板挟みになって機能不全に陥らないように、必要な権限を与える必要がある。システム部としては、重責を負うことになるので、組織的に速やかな判断を下せるように、セキュリティインシデント発生時に適用する緊急プロセスを設ける必要がある。

速やかな本番適用を実現するためには、システム的な機能として、以下のようなものが必要になる。

  • コードリポジトリ変更、ビルド、リリース・デプロイを迅速に行うDevOps環境
  • システムのリグレッションテストを迅速に行うテストツール実行環境
  • 論理障害・改竄後の復旧に備えたシステムバックアップ
  • できれば、サービス提供を代行可能なバックアップシステム

「脆弱性が多い・評判が悪い製品は他の製品へ変更する」、「セキュリティパッチをタイムリーに適用する」、「外部からの入力文字列を複雑な処理系へサイニタイズ・妥当性検証せずに渡さない」、「アプリケーションサーバ起動ユーザの実行権限を絞る」、「データは階層化して必要な場所に適切な権限で必要な期間しか保存しない」、「WAF・FW・IPS・IDSといったソリューションを適用して検知・防御する」、といった基本的な取り組みは重要であるし、教育、施錠管理・入退室管理、監査ログの取得と保護、データや通信経路の暗号化といったベタなものと合わせて実施するべきである。

しかし、今般のような緊急性が高い事象については、上記のような基本的なお作法・ガイドラインへの準拠に加えて、「緊急性が高いことを認識する能力」と、「最低限度の暫定対応策を迅速に実現する能力」が求められる。

(参考)基本的な取り組みについてのガイドライン

| 日記 | comments(0) | trackbacks(0) |

業務システム、またはSoRとSoEについて

業務システムのことを、Systems of Record (SoR)と呼ぶことがある。これは、Systems of Engagement (SoE)に対する対比として作られた用語だ。

初出は、書籍『キャズム』の著者として有名なジェフリー・ムーア氏(Geoffrey Moore, 1946-)による、"Systems of Engagement and the Future of Enterprise IT" (AIIM.org, 2011)による。

業務システムは、一般に、入力されたデータを加工して保存し、次の入力のために保存されたデータを出力するという意味で、レコーダーの役割を主とする。そのためのデータ永続化機構がDBであり、DBに保管されたデータを読み込み、処理し、またDBへ保管するのがアプリケーションの主な役割になる。業務システムで最も重要視されるのは、データ・インテグリティ、つまりデータの整合性だ。

入力と出力の間で各種の変換処理が発生し、複数の永続化機構(主にDB)にデータを格納し、また複数の永続化機構からデータを読み出して変換するシステムにおいて、複数の永続化機構の間でデータの整合性が確保されていることは、最も重要なことだ。

一度データ整合性が破損すると、破損したデータを読み込んで変換した結果データが他の永続化機構に保存され、それがまた読み込まれて誤ったデータを出力して、また別の永続化機構に保管され、といった具合に、誤ったデータが次々に伝播し、正しいデータと誤ったデータを区別することができなくなってしまう。こうなってしまったら、データ破損前に取得したバックアップまで巻き戻って、業務をやり直す他はない。

社内業務であれば、最悪の場合、前日取得時のバックアップまで巻き戻ってやり直すこともできるだろうが、社外に提供したり受領したりするデータについては、そうそうやり直すことはできない。例えば、銀行業務の場合、ATMやネットバンクでの、銀行の顧客による入出金処理をやり直してもらうことは、ほぼ不可能だ。

これらの業務システムは、業務の必要に応じて構築するものであり、業態によっては競争力の源泉になるが、マーケティングの観点では、差別化の取り組みが必要になる。その重要な要素のひとつが「コミュニケーション」である。コミュニケーションベース、コラボレーションベースの動的な基盤を提供するシステムのことを"Systems of Engagement"と呼び、従来の、静的なデータ変換器・データ保管機構である"Systems of Record"と区別することが提唱された。

このような意味では、既存の業務システムにおいても、SoR的な機能とSoE的な機能とが、混在しているのが現状である。SoRとSoEという用語の強みは以下にあると思われる。

  • 既存のシステムが保管するデータに対して、SoE的なインタフェースを抽出して外部に公開する。
  • これらの機能を峻別して、各々の機能を、適したアジリティとSLAで実装できるようにする。

SoRに分類される機能は、データインテグリティとセキュリティを最上位の価値として、業務品質と業務効率とを向上させるように実装すべきだ。また、「一度作ったら十年塩漬け」といったものにしないために、業務継続性の根幹となる普遍的な部分と、大規模改修・フルスクラッチをせずとも、ある程度は柔軟に変更できる可変部分を含むアーキテクチャを採用すべきである。

SoEに分類される機能も、データインテグリティとセキュリティに気を配る必要があるが、コラボレーションしやすく、プライバシーを保護できるようにすることに注力する必要がある。そのためには、事業の継続に必要となるような、データインテグリティとセキュリティが必要な基幹的なデータは、SoEで扱うにしても、短時間にとどめて永続化せず、必要であれば別のSoRのシステムへ移動してしまうのが良い。

SoRは堅牢であることが必要であり、SoEは高いアジリティが必要である。SoRはEAに基づいて、Web ServiceベースのSOAを指向したが、SoEは、REST原則に基づいて実装されるマイクロサービスを指向する。そのための開発プロセスやメソドロジーは、必要に応じて別のものを採用する必要があるだろう。

| 日記 | comments(0) | trackbacks(0) |

ITシステムにおける性能試験について

はじめに

ITシステムは、単に動くだけではなく、本業務のピーク時に、目標の応答時間や単位時間当たりの業務処理量を達成する必要がある。また、初期構築から、次回のシステム更改時までのデータ保持量や、ログメンテナンスサイクル内でのログ量などの、キャパシティを満たす必要もある。

そのために実施するのが、性能試験だ。性能試験には、おおよそ、次の種類がある。

  • 単体性能試験
  • オンライン負荷試験
  • バッチ走行試験
  • ロングラン試験

テスト環境とテストデータについて

大前提として、性能評価のためには、基盤環境、業務アプリ、データを、本番相当にすることが必要だ。新規構築やシステム更改案件なら、構築中の本番化予定の環境で試験すべきである。

フェーズが早い、もしくは変更案件で本番環境は本業務サービス提供中で使えないなどの理由で、本番環境・本番化予定環境でテストができない場合は、ハードウェアとソフトウェアの技術的構成要素が、出来る限り本番環境と近しいテスト環境を、ステージング環境として用意する必要がある。

テストデータの観点では、レコード数、カーディナリティ、比率が、最も重要な要素となる。まれに、レコード数だけを本番相当にして満足している場合があるが、レコード数は一定量を超えたらあまり影響しなくなるので、特にカーディナリティと比率が重要だ。

品質の良いテストデータを生成することは非常に難しい営みとなる。単純な場合は、テストデータ生成プログラムを開発することが多いが、本番データをマスキングしてテストデータを生成することもある。

DBが複数存在するような大規模で複雑な場合は、本番データの中で大元になるデータをマスキングし、バッチを走行させて、各DBへバッチ処理後のデータを行き渡らせ、この処理で行き渡らない個別データは、ターゲットDBにて個別にマスキングすることになる。このデータを準本データと呼ぶことがあり、保守・運用サイクルの中では、定期的に準本データを最新化する必要がある。

データマスキングツールには色々あるが、複数のデータベース間で、識別子の一意性を保ってマスキングすることは難しいことから、このような営みが必要となる。

これは、かなり大規模な営みであり、高度に管理されたテスト環境が必要となることから、代替策として、本業務環境の統計情報をエクスポートして、テスト環境にインポートするだけのこともある。但し、テーブルレイアウトやインデックス有無などが変更される場合は、この方法は使えない。

単体性能試験

まず、単体性能試験は、SQLやトランザクションの単体試験の一環として実施する。機能確認試験に加えて、応答時間、メモリ使用量、アクセスパスなどを単体レベルで検証する。この試験では、網羅性目標を設けて、その目標を満たすようにケースを策定するほか、データを本番相当にすることが重要だ。

単体試験には、多くの開発者・開発チームが、各々独立して取り組むことになるので、UT完了のクライテリアとなるように開発規約に組み込むと共に、簡単かつ同じ品質で実施できるように、ツールを開発して提供することが望ましい(開発者の各々に、ログを見て評価してもらうことは、事実上できない)。

SQLについては、データを用意した上で、アクセスパス、読み込み量、応答時間などを評価することになるが、評価対象指標に閾値を設けて、超過したものだけ詳細に評価するプロセスが望ましい。ここでも、簡略化するためのツールの提供が望ましい。

オンライン負荷試験

次に、オンライン性能試験を、ITbのフェーズで実施することになる。概ねのスケジュールとしては、数週間テストケーススクリプトを作成・検証し、テストを一週間程度実施し、数週間、結果評価・チューニングした後、リトライして検証することになる。開発規模・変更規模に応じて、このサイクルを、何度か繰り返すことになる。

本業務サービス提供済みのシステムなら、次の2つの何れかの方針で、ベース負荷をかけることになる。これを実現するためには、何らかのツールの適用が必要になる。

  • ログからテストケーススクリプトのスケルトンを生成して、バインド値などを作りこむ。
  • 本業務サービス提供中のパケットをキャプチャして再生する。このためには、キャプチャ開始時のデータのバックアップを、テスト環境にロードする必要がある。

前者の場合は、ログから負荷ツール用のスクリプトを生成するプログラムの開発が必要になる。バインド値の設定など、人手の対応が多いので、100%再現することはできないため、「本業務サービス時の80%のリクエストを再現する、実行件数の多い上位20%の画面を再現する。全体の件数が100%となるように、全体を80%で割る(1.25倍する)」などの方針を設けて取り組むことになる。

後者の方が簡単そうに感じられるかもしれないが、本業務のパケットをキャプチャして再送する場合でも、リクエスト・レスポンス毎に動的に変動するパラメータ(カンバセーションIDなど)などの取り扱いに人手の対応が必要になり、本業務のデータをテスト環境にロードすることも、規模が大きくなるほど困難になる。

なお、本業務サービス提供時の振る舞いを再現するに当たっては、当該トランザクション実行時に同時に実行される予定の、オン中バッチについても、走行させることが必要だ。

上記のように、本業務サービス時のトランザクションミックス・負荷状況を再現できたら、次に、テスト対象のアプリ・時期による変動分を、作り込んで行く。たとえば、来年4月に本番化されるアプリの試験であれば、以下の対応が必要となる。

  • テスト環境に、来年4月リリース予定のアプリをデプロイする
  • 背景負荷となる本業務相当トランザクションミックスから、来年4月以降に追加・削除・変動する見込みのトランザクションを取り除く
  • 追加・削除・変動分のトランザクションを、負荷スクリプトとして開発して追加する

テストのやり方としては、まず、変更前のアプリに本業務サービス相当の負荷を掛けて、本業務サービス提供時の振る舞いを、ある程度満足できるだけ再現できることを確認してから、変更後のアプリをデプロイして、リリース後の本業務サービス提供時の見込みの負荷を掛けて、パフォーマンスとスループットを評価することになる。

本業務サービス提供中のシステムで、新規トランザクション追加・既存トランザクション変更が、少数である場合は、最初からトランザクションミックスの負荷を掛けずに、まず、追加・変更予定のトランザクション単体の負荷試験を実施して、当該トランザクション単独負荷でのパフォーマンス&スループットを評価することが望ましい。

バッチ走行試験

夜間バッチの場合は、オンライントランザクションよりも単純だ。業務処理量のピーク時相当のデータで、本業務サービス提供時と同じ種類のバッチを、同じ順序で、同じ多重度で走行させて、スループットとキャパシティを評価すればよい。

この際、データによって、個々のジョブユニットの走行時間や多重度が変動する可能性がある場合は、いくつかのデータのバリエーションで、走行試験を実施することが望ましい。

ロングラン試験

ロングラン試験は、長時間サービス提供を継続することで、メモリやファイルシステムが単調増加することがないかどうかを評価するために行う。

理想的には、日次・週次・月次のジョブおよび、オンライン負荷を、本番サービスイン後想定となるように、走行させることであるが、現実的には難しい、もしくはできないことが多い。

そのため、検証できる内容に制約が設けられることにはなるが、例えば、以下の方針で試験を実施することになる。

  • ジョブについては、データの繰り回しを含んだ機能確認試験の観点で、一週間程度、繰り回し試験を行う。
  • また、データの繰り回しを含まない空回しを、本番サービスイン前の1, 2ヶ月間以上、ST・運用試験として走行させる。
  • オンライン負荷については、参照系のトランザクションミックスを、数日から一週間程度、継続的に掛け続ける。

おわりに

開発工程標準の一部として、上記のような営みを定義することとあわせて、各工程で、品質と効率を向上させるためのツール適用、ツールと環境の結合・自動化が必要となる。

ツールの適用に当たっては、ツールと環境が利用できるようになっていれば良い、というものではなく、「使われているか、プロセスは遵守されているか」、「利用に当たって困難はないか」、「次のプロジェクトで再利用可能なアセットを抽出できないか」といった、技術的なサポートを提供する体制とセットで考える必要がある(参考)。

また、別の観点として、システムをテストしやすく作るということが挙げられる。テストは、テスト範囲が広ければ広いほど、幾何級数的に準備と結果検証の負担が高まる。一方、ハードウェアと、ソフトウエアの観点で共有するコンポーネントがない部分は、各々を独立してテストすることができる。

昔から、巨大なシステムは、手頃な範囲にサブシステム分割し、サブシステム間は互いに疎になるように結合することが推奨されてきた。現状においても、Systems of Record (SoR)かSystems of Engagement (SoE)か、SoRであればマスターデータのフローやクライアントチャネル、SoEであればAPI単位などに注目して、管理できる程度のサイズまで細かく、そして逆に細かくなり過ぎないように、分割することが必要だ。なお、API単位まで分割する場合は、人手で個別に管理することは困難になるので、テストを完全に自動化すべきだ。

性能試験は、一回、二回という単位で数えられるイベントではなく、数週間単位を何度か繰り返す、フェーズとして計画する必要がある。そして、性能試験を実施できるように、巨大なシステムは、凝集度が高くなるようにサブシステム分割し、サブシステム間の連携は、結合が疎になる方式で標準化すべきである。

| 日記 | comments(0) | trackbacks(0) |

Javaヒープサイズのチューニングについて(世代別の場合)

はじめに

Javaオブジェクトが使うメモリ領域のことをJavaヒープと呼ぶ。

Javaアプリケーション実行時は、Javaオブジェクトを大量に生成・破棄することになるが、Java Virtual Machine (JVM)は、Javaヒープが空いている限りはJavaオブジェクトを作成し続ける。Javaヒープがオブジェクトでいっぱいになると、JVMはGarbage Collection (GC)という処理を実行して、使い終わったオブジェクトが占有していたメモリ領域を、新規のJavaオブジェクト作成用に再利用できるようにする。

GC実行中はアプリケーションの処理が概ね停止するので、如何に、パフォーマンスとスループットに悪影響を与えないようにGCを実行させるか、ということを目的としてチューニングする必要がある。

ちょっとしたユーティリティ類を動かすだけなら、せいぜい数百MB程度のJavaヒープで十分であり、GCが発生しても数百ミリ秒程度なので、気になることはまずない。しかし、業務システムの場合は、大量のデータと大量のトランザクションを処理するために、かなりのサイズのJavaヒープが必要となることが多く、GC実行時間が秒単位に延びてしまうことがある。

昔は、メモリが高価であり、アドレッシングも32bitだったので、2GB程度のJavaヒープで何とかやりくりしていたため、負荷が高いシステムでは、Javaヒープが極短い時間でいっぱいになり、GCが1秒間に何度も実行され、1回当たり数百ミリ秒〜数秒掛かるので、スループットが悪化し、最悪の場合はOutOfMemoryErrorに至ってしまうということがあった。

今では、64bitモードの広大なアドレス空間が利用可能で、メモリも安価になったので、深刻な問題に遭遇することは少なくなった。しかし、現在でも、高負荷で複雑なアプリが稼働する環境では、GC実行方式とJavaヒープサイズをチューニングすることの効果は大きく、システムの安定稼働のために重要な営みである。(逆に言うと、大して負荷が高くなく、アプリもそれほど複雑でなく、Javaヒープも潤沢に確保できる場合は、JVMがかなり自動でよろしく計らってくれるので、チューニングしてもそれほど何かが良くなるというものではない。)

GC方式の選択

GC方式は複数の種類から選択可能であるが、現状では世代別GCが最も多く使われていると思われる。Javaヒープサイズのチューニングは、アプリケーションの特性に応じて個別に検討する必要があるが、「NEWを大きく、OLDを小さく」、「サイズの差はOLDでつけて、NEWのサイズは固定」、「物理メモリが余っていても、全体サイズを大きくし過ぎない」といった原則に基づいてチューニングしていくことになる。

なお、Javaヒープサイズが極端に大きい、もしくは小さいなどの顕著な特徴がある場合は、他の方式のGCを検討する必要がある。選択できるGC方式は、Javaランタイムの種類ごとに異同があるので、JVM開発ベンダーのドキュメントを参照する必要がある。

世代別GCのメモリ構造と基本的な動作

詳細はJVM開発ベンダーに依存するが、世代別GCではプロセスが確保する全メモリ空間を、以下のように分類して管理する。

JVMのメモリーレイアウト図

領域説明
JavaヒープNEW領域(nursery)EdenJavaオブジェクトが新規に作成された際に、まずアロケーションされる領域。
SurvivorEdenスペースがいっぱいになった時点で、生存していたオブジェクトが残される領域。EdenとSurvivorの間で生存オブジェクトがコピーされることをフリップと呼ぶ。 アプリケーションの特性に依存するが、フリップによって生き残るオブジェクト数は少数であることが多く、NEW領域においてSurvivor領域に必要なサイズは、Eden領域よりも少なくて済む。この比率は、JVMが自動的に計算して動的に変動する。(多くの場合、NEW領域の大半はEden用に使われる。)
OLD領域(tenured)NEW領域で何度かフリップが繰り返される間、存続し続けたオブジェクトは、長命オブジェクトとみなされてOLD領域にコピーされる。OLD領域がいっぱいになると、フルGC(もしくはGlobal GC)と呼ばれるGCが実行される。NEW領域のGCは、EdenとSurvivor間でのコピーGCだったが、OLD領域のGCは、従来のマーク&スイープ型GCであり、必要に応じてコンパクションも実行される。なお、ラージオブジェクトとそれ以外に分けられ、OLD領域に占めるラージオブジェクトアロケーション用の領域の比率は、JVMが自動的にチューニングするが、このサイズが頻繁に増減するアプリの場合は、ラージオブジェクトエリアのサイズを明示的に指定した方が良い。
Nativeヒープクラス定義、メソッド定義、ダイレクトバイトバッファ、スタック、JVM自身の稼働領域などで使われる。Javaヒープの最小・最大のサイズは、java起動時引数-Xms-Xmxで指定するが、これではNativeヒープのサイズは制限されず、上限は当該OS区画に割り当てられている物理メモリサイズになる。アプリケーションの特性によっては、ダイレクトバイトバッファや、スタックのサイズを指定する必要が生じることがある。この領域のメモリメンテナンスは、ダイレクトバイトバッファ枯渇か、フルGC時に行われる。

NEW領域は、EdenとSurvivorに分けられる。JavaオブジェクトはEdenにアロケーションされるが、いっぱいになると、生存オブジェクトをSurvivorへコピーする。

動作の詳細はJVMベンダーに依存し、Oracle JVMの場合は、Survivor領域を二つに分けて、EdenからSurvivorへの生存オブジェクトのコピーは一時点では一方へ行い、EdenかSurvivorがいっぱいになると、他方のSurvivorへのコピーが実行される。IBM JVMの場合は、Edenがいっぱいになると生存オブジェクトをSurvivorへコピーし、今度はSurvivor領域をEden領域としてアロケーションして行き、以後、いっぱいになる度に入れ替えを繰り返す。何れにしても、NEW領域のGCは、コピーGC(Copying GC、もしくはScavenger GC)と呼ばれる。

NEW領域での、EdenとSurvivor間でのコピーを何度か繰り返しても存続し続けるオブジェクトは、OLD領域にコピーされる。OLD領域がいっぱいになると、フルGCが発生する。一般に、NEW領域のGCよりも、OLD領域のGCの方が遅く、アプリケーションの振る舞いに対して与える影響が大きい。

通常のアプリケーションでは、オブジェクトの大半は、短命オブジェクトだ。これらのオブジェクトは、メソッドブロック内や、長くてもトランザクションスコープを存続期間とするものであり、NEW領域で何度かフリップを繰り返すうちに消滅し、OLD領域へ昇格することはない。OLD領域へ昇格するのは、極わずかな長命オブジェクトだけだ(長命なものとして、セッションスコープ、アプリケーションスコープのオブジェクトが存在する)。しかし、NEW領域が小さいと、数百ミリ秒以下の間隔でEden領域がいっぱいになってしまい、短命であるにもかかわらず、OLD領域に昇格され、OLD領域がすぐいっぱいになり、フルGCが頻繁に発生することになってしまう。

短命オブジェクトをNEW領域のGCで確実に消滅させ、OLD領域のGCが発生しても短時間で完了させるために、NEW領域を十分に大きくし、OLD領域を必要十分以上に大きくしないことが、重要になる。NEW領域の比率を、全体の1/3程度としているケースが多いが、適切なサイズはオブジェクトのサイズ・個数・生存時間に依存する。オブジェクトのサイズが十分に小さく、生存時間が十分に短いことが分かっているアプリケーション以外では、NEW領域の方をOLD領域よりも大きくした方が適切な場合が多い。

本ページでは、主に、JavヒープのNEW領域とOLD領域のチューニング方針について記載するが、Nativeヒープについても、チューニングする必要があることがある。Javaヒープのサイズや使用状況は、冗長GCログから評価するが、Nativeヒープのサイズは、Linux/UNIX系コマンド"svmon -P"出力結果や、Javaプロファイラによって評価する必要がある。

世代別GCのチューニング方針

世代別のGCは、上記の通り、「NEW領域を大きく、OLD領域は小さく」することが重要だ。NEW領域を大きくすることで、OLD領域のGC発生頻度を減少させることができるし、OLD領域を小さくすることで、1回当たりのGC実行時間を短縮できるためだ。但し、OLD領域を小さくし過ぎると、OutOfMemoryErrorが発生してしまうので、必要十分なサイズに設定することが必要だ。

まず、類似すると考えられるアプリが実稼働している環境があるなら、当該環境をリファレンスして、最初の仮定値を決定するのが良い。他システムの設定をリファレンスすることができず、当該OS区画で利用可能な物理メモリの上限が決まっている場合は、以下のような感じで初期設定する。設定オプションは、Javaランタイムの種別ごとに異動があるので、上記のベンダー提供マニュアルを参照する必要がある。

  1. OS区画で利用可能な物理メモリの使用率に十分余裕がある中で、Javaプロセス全体で利用可能なサイズを決定する(ページングが発生しないように、OS+プロセスが実際に利用するメモリサイズが、物理メモリ全体の70〜80%程度になる程度で見積もる)。
  2. Javaプロセスで利用可能なサイズの2/3程度をJavaヒープサイズの最大値(-Xmx)に設定する。(残りの1/3がネイティブヒープで使われる想定。)
  3. Javaヒープサイズの最大値の70%程度を最小値(-Xms)にする。
  4. Javaヒープサイズの最小値の半分程度をNEW領域のサイズとする(NEW領域は最小=最大とする)。
  5. Javaヒープの全体から、NEW領域のサイズを引いたものが、OLD領域のサイズとなる。

Javaヒープサイズの設定を、上記のように、最小値(-Xms) < 最大値(-Xmx)とする場合は、差をつけるにはOLD領域のサイズで差をつけ、NEW領域サイズは固定にした方が良い。NEW領域のGCと比べると、OLD領域のGCの方が、まれにしか実行されないためだ(頻繁にサイズ拡大・縮小してほしくないため)。

次に、実際にアプリケーションをデプロイして、本業務ピーク時相当の負荷を掛けたときの冗長GCログを評価することで、以下の方針で、OLD領域のサイズを縮小し、NEW領域のサイズを拡大する。

  • OLD領域の、GC後のメモリ使用量が、OLD領域の最小値の70%程度になるまで、OLD領域の最小値を下げる(=NEW領域のサイズを拡大する)。
  • OLD領域の最大値を、OLD領域の最小値が70%程度となるまで下げる(=NEW領域のサイズを拡大する)。

NEW領域は、物理メモリが利用できる範囲内ではあるが、以下のようになるまで拡大する必要がある。

  • 高負荷時間帯に、OLD領域のメモリ使用量が増加しない、もしくは増加しても軽微である。
  • 高負荷時間帯に、NEW領域のGCが、概ね10秒以上の間隔で実行されている(まれに連続実行されることがあるのは問題ではない)。

上記は、OLD領域が、十分に確保できることが大前提となる。OLD領域が枯渇すると、OutOfMemoryErrorが発生してしまうためだ。以下のように振舞うようになるまで、OLD領域の適正なサイズを探っていく必要がある。

  • OLD領域の拡大・縮小が発生しない、もしくは発生してもまれである。
  • OLD領域のGCが、ピーク時間帯に発生しない、もしくは発生しても発生間隔が5分間以上である。

最終的に、ピーク時の、単位時間当たりに占めるGC実行時間の割合が、4%以下となることを目標に、チューニングすることが望ましい。繰り返しになるが、OLD領域を必要十分以上に大きくしてしまわないこと、NEW領域を十分に多く確保することが望ましい。

昔は、利用可能なメモリサイズが小さかったため、OLD領域を大きく取ることが推奨されていた。これは、メモリを十分に確保できない状況で、マーク&スイープ型GCが主流であったことの名残でもある。しかし、複雑で扱うデータ量も大きなアプリで、トランザクション実行時間が秒単位になるものが混ざっているような環境においては、 OLD領域を必要十分なだけ確保した上で、NEW領域を大きく確保する必要があるので、業務システム利用における多くの場合は、OLD領域よりもNEW領域の方がだいぶ大きくなるはずだ。

マーク&スイープGCから世代別GCへの移行

2GB程度までのJavaヒープサイズの場合は、世代別GCよりも、マーク&スイープ型の方が有利である可能性がある。この傾向は、サイズが小さくなるほど顕著になる。

サービス提供開始時点ではマーク&スイープ型だったとしても、徐々に処理量が増加し、GC負荷が高騰したために、Javaヒープサイズを拡大する要求が生じて、2GBを超えるようになったら、世代別GCへ移行することを検討することが望ましい。

GC方式の変更は、パフォーマンスに対して少なくない影響を与えることから、本業務サービス提供環境では、保守的な態度で、徐々に変更していくことが望ましい。

まず、最も保守的な方針は、マーク&スイープ型GCのときのJavaヒープサイズの最大・最小の設定値を、世代別GCのOLD領域の最大・最小値にして、NEW領域を単純に追加することだ。メモリに余裕があれば、まずは、OLD領域の最小値程度(=元のJavaヒープサイズの最小値≒最大値の70%程度)を、NEW領域としてJavaヒープに追加することが望ましい。

NEW領域を追加することで、OLD領域のGC実行頻度は減少するはずなので、その後の稼働状況を一定期間評価することで、OLD領域のGC後使用量を確認し、当該の量が70%程度となるまでOLD領域サイズを縮小し、その分、NEW領域を拡大すれば良い。本業務サービス提供環境で極端な設定変更が好ましくない場合は、数回に分けて徐々に割り当てサイズを変化させていくことが望ましい。

前項の繰り返しになるが、最終的に、以下のようになればよい。なお、強大なオブジェクトがアロケーションされた場合に、連続領域が確保できないなどの理由で、GCが連続実行されることがあるが、稀であれば問題ではない。

  • OLD領域の拡大と縮小が頻繁に発生しない。(特にオンラインのピーク時には発生しない。)
  • OLD領域のGC後の使用率が70%程度である。(低すぎも、高すぎもしない。)
  • OLD領域のGC実行間隔が概ね5分間以上である。(一時間に数回程度が望ましい。)
  • NEW領域のGC実行間隔が概ね10秒以上である。
  • GC実行時間比率が4%以下である。

チューニングが必要な場合

例として、以下のようになっている場合は、チューニングが必要だ。

事象 改善方法
OLD領域が、ピーク時間帯に徐々に拡大していく。 Javaヒープサイズの拡大は負荷が高くGC実行時間も長くかかってしまうので、ピーク時間帯に必要なサイズまで、OLD領域の最小値を拡大する。但し、バッチ処理などで、徐々に拡大するのではなく一気に拡大し、処理終了後に一気に縮小する場合は、この限りではない。
OLD領域のGCが、ピーク時間帯に何度も実行されており、GC後のOLD領域の使用率が低い(50%未満である)。 NEW領域で消滅すべきオブジェクトがOLD領域に昇格してしまっているので、OLD領域のサイズを削ってNEW領域を拡大すべき。
OLD領域のGCに数秒以上かかっており、GC後の使用率が低い(50%未満である)。 OLD領域のGCは、コンカレント・マーク&スイープ型GCであり、サイズが大きくなるとそれだけGC実行時間も長くなる。GC後の使用率が70%程度になるまで、OLD領域のサイズを縮小すべき。
OLD領域がいっぱいになっていないのに、OLD領域のGC (フルGC)が発生している。 アプリケーションで、System.gc()が実行されていないか確認し、実行されていないことを確認できたら、ダイレクトバイトバッファ枯渇を疑う必要がある。

チューニングポイントは他にもたくさんある。例えば、スタックサイズ、ラージオブジェクトエリアサイズ、ダイレクトバイトバッファサイズなどは、チューニングする必要に迫られる可能性がある。また、用途によってはシステムプロパティ(-Dproperty=value)で、タイムアウト値や機能無効化などを設定する必要があるかもしれない。これらのチューニング要否を含めて、全体としてはアプリケーションの動作特性に依存して個別的に評価・判断すべきであるが、「NEWを大きく、OLDを小さく」、「サイズの差はOLDでつけて、NEWのサイズは固定」、「物理メモリがあまっていても、全体サイズを大きくしすぎない」ということは、ほとんどの場合は守るべき事柄だ。

| 日記 | comments(0) | trackbacks(0) |

セッション共有について

Web系のシステムでセッションを用いるとき、永続化するか、他のクラスターメンバーと共有するかという選択肢がある。

セッションを永続化すれば、古くなったセッションを永続化してメモリ消費量を抑えたり、再起動後も利用可能にできるようになる。また、永続化されたセッションを、他の負荷分散対象クラスターメンバーと共有できるようにすれば、処理中のメンバーで障害が発生して、他のメンバーへリクエストが割り振られても、割り振り先メンバーで、セッションを継続的に利用できるようになる(再ログインせずにサービス利用を継続できる)。

かつては、セッション永続化・セッション共有を実現するシステムが多かったが、システムの規模・複雑さが増大していく中で、トランザクショナルなデータをセッションに格納して利用することが好まれなくなり、冪等な処理をステートレスに実装することが多くなった結果、重要性は低下した。

現状でも業務システム(Systems of Record (SoR))の場合は、セッション永続化・セッション共有が求められることがあるが、業界トレンドとは別の観点として、以下のことについて気を配る必要がる。

  • セッションの永続化は、原則として非同期書き込みになるので、必ずしも全てのケースを救えるわけではない(タイミングによって、巻き戻りや、業務データ用DBなど他の永続化機構との不整合が発生する可能性がある)。
  • セッションの永続化で必要になるI/O量は、トラフィック量×サイズに依存するため、ハイトラフィックなシステムの場合、業務DBに対するI/Oよりも多くなる。
  • セッションI/O量を削減するためには、セッションサイズを最低限度に抑える必要がある(トランザクショナルに必要なデータはDB等で永続化し、トランザクションはステートレスに実装する)。
  • 大量のI/Oを処理するために、ネットワーク帯域を圧迫しないように考慮する必要がある(業務セグメントと分ける、複数ポートを束ねてイーサチャネル構成にする、など)。

セッションの永続化・共有化が必要と考えられる場合は、まず物理層で実現可能な量であるかどうかを評価する必要がある。もし、業務処理に影響を与える可能性がある場合は、セッションのサイズを減らしたり、セッション永続化・共有化に用いるネットワークのポート増設・イーサチャネル構成、セグメント分離などを検討する必要がある。

セッションのサイズを減らすということは、セッションの永続化・共有化の必要性を減らすことでもあるので、最終的には、上記の費用と得られる効果とを比較・評価した上で、セッション永続化・共有化を利用するかどうかを決定する必要がある。トランザクション量・アプリの複雑さが高まると、それだけ多くの取り組みが必要になるので、このトレードオフは不利な方へ傾いていくことになる。

| 日記 | comments(0) | trackbacks(0) |

ITシステムにおけるアーキテクチャについて

ITシステムの構築にあたっては、リファレンスシステムを選定して、真似ることから始めるべきだ。

リファレンスシステムとのFit&Gapを評価し、変化点・新規要素となるGap部分に注力して検討を行う。この、Gap部分の検討及び、プロジェクト期間中から保守・運用期間中に発生するインシデントや変更要求に対応していく中で、複雑さが高まり、拡張性・保守容易性が極端に低下してしまうことがある。アーキテクトは、システムが複雑になりすぎないよう、常にシンプルさが保たれているように、常に心がけている必要がある。

複雑さが増していく要因は、個々の要件に対する個別的な対応が積み重なることにある。変更要求やインシデントなどの起因となる要件に対して、コスト要因、構築中の環境遷移・テスト要件などで、「こうすればこうできる」、「このためにはこうすれば良い」という技術的な判断を個別に行うことで、機能的には個々の要件を実現できるものの、全体として複雑さが増してしまうことがある。

技術的な決定を下すに当たっては、「できるかどうか」だけではなく、以下のような観点を踏まえて、「やってよいか」という評価を実施する必要がある。

  • 新規の技術的構成要素が増えないか
  • 後続フェーズでの保守体制・コストの増加要因にならないか
  • 既存のアーキテクチャの連続線上に存在するか
  • 既存の他システム実績があるか(もしくは、他システムでも流用可能な仕組みか)
  • 局所的な例外要素とならないか
  • 普通はどうするものなのか
  • 業界トレンドに沿っているか

少人数で、頭を悩ませて考えることは、危険な兆候である。考えることは重要であるが、頭で考えたことは、多くの場合、机上の空論になりがちであり、複雑化し過ぎる傾向にある。何故ならば、机上で、現実的に遭遇し得るあらゆるケースを見切れるだけの検討を施すことは、非常に困難なことであり、微視的な課題・困難・要件については、技術的に「こうすれば、こうできる」という解決策が必ず策定できてしまうためだ。

考えることは重要であるが、そのためには、事例に基づく必要がある。イノベーションは、実現されて初めてイベーティブになるのであって、実現できなかった机上の空論には何の価値もないからだ。事例に基づけない場合は、机上で策定したソリューションが、現実的に効果があるかどうかを、小規模に検証してみることが有効となる。この取り組みは、PoCとかプロトタイピングとか呼ばれる。

また、、システムのTCOに責務を持つステイクホルダーに対して、トレードオフ(Pros&Cons)を提示して意思決定してもらうように計らう必要があるかもしれない。なぜならば、現場の担当者は、全体最適に対して、局所的な責務しか帯びていないことがあるからだ。例えば、構築・更改案件の初期投資コストに対してのみ責務を負っており、その後の保守・運用フェーズへの技術的負債の蓄積による負の影響についてはスコープ外となっているような場合が挙げられる。

アーキテクティングは、「あれも、これも」できるようにすることではなく、「あれか、これか」を選択して制約を設けることである。

| 日記 | comments(0) | trackbacks(0) |

ITシステムにおけるツールの利用について

システム構築・維持保守では、様々なツールが使われる。ツールを適用する目的は、品質と効率の向上だろう。

例えば、アプリのリグレッションテストや負荷試験は、何度も繰り返し実施されることながら、人手でなんとかしようとすると、莫大なコストと期間がかかるため、ツール適用の効果が大きい。 そのため、かなり初期からツール適用が進んでおり、継続的インテグレーションやDevOpsの名の下に、デプロイメントパイプラインを設けて一気通貫の自動化を進め、アプリだけでなく、インフラの設定・構築も、その仕組みに乗せて管理しようという方針が進んでいる。

この辺りにツール適用して効果を高めるためには、テスト環境準備(アプリデプロイ、データ準備)、テスト実施、結果評価の、一連のプロセスを自動化することが重要なのであり、利用を始めてからPDCAサイクルを回して使いこなしていく過程が重要となるのだが、そもそも、ツールに対する取り組み姿勢が大前提になる。

ツール適用に当たっての議題は、当該ツールの機能もさることながら、どう使うかが大半だ。

企業の規模、システム部の規模が大きくなればなるほど、参画人数が多く、マルチベンダーの体制になる。

規模が小さい場合は、まず、ツールを適用するところから始めれば良いが、規模が大きくなればなるほど、やがて、効果が上がらなくなる。

初期には、ツールのライセンスをプールし、当該ツールを実行するための常設基盤を提供して、複数チームで共有する体制を設けることから始めれば良いが、やがて使いこなせず、期待した費用対効果が得られないという課題が明確になる。

次のステップとしては、以下の責務を持つチームを、内製化体制として設けることが望ましい。

  • 当該ツールを使いこなすためのガイドやアセットをメンテナンスして利用チームに対して技術支援する
  • 利用実績を踏まえてガイドやアセットをブラッシュアップしていく
  • 有効に活用されているかどうかを評価して、活用度が低い場合には、有効に活用してもらうための追加の取り組みを検討して実施する

逆に言えば、そういう体制やプロセスを設けずに、複数のチームで共有できるライセンスプールとランタイム環境を提供するだけでは、ツール適用の効果である、品質と効率の向上は期待できない。

| 日記 | comments(0) | trackbacks(0) |

ITシステムの基盤更改への取り組みについて

基盤更改とは

基盤更改とは、ITシステムの、ハードウェア・ソフトウェアの入れ替えを目的として実施するプロジェクトだ。

業務システムは何れ、基盤更改というプロジェクトに取り組むことになる。その契機は、ハードウェアやソフトウェアのサポート・保守切れ対応になる。

従って、この世の中で最も多いタイプのSIプロジェクト型と言えると思う。

基盤更改で最も問題になるのはコスト。業務サービスの継続性・安定稼働は大前提だが、業務要件を契機として始まる案件ではないため、投資よりも経費寄りの案件と言えるため、コストが問題になることが多い。

基盤更改案件で最も大きなコストになるのは、最低限度、購入する必要があるハードウェアやソフトウェア以外では、業務アプリのリグレッション試験のコストが最大になる。基盤更改プロジェクトの成否は、業務アプリのリグレッション試験を、どれだけ広く・深く実施できるかに掛かっていると言って良いと思う。

基盤更改への取り組みの歴史

歴史を遡ると、まずは、オープン系のシステムが実装され始めた2000年代前半。初期に構築されたオープン系システムが5-7年経過して、基盤更改のタイミングを迎えるようになった頃。

当時は、「基盤のハードウェア・ソフトウェアだけを入れ替える、業務アプリへの影響は極力最小限度にする」、というポリシーが採用されることがあり、仮に業務アプリ更改要件があっても、「まず基盤更改先行し、追って業務アプリ更改する」、という、基盤と業務アプリの更改タイミングをずらす方針が採用されたことがあった。その理由には以下のようなものが挙げられると思う。

  • 当時はまだオープン系のシステムは今ほど多く・複雑でもなかった。
  • システム部要員がメインフレーム経験に基づいていた。

メインフレームは、シングルベンダーによる垂直統合型で実装されている。ハードウェアとソフトウェアが、特定のベンダーによって実装されており(もしくは互換機ベンダー)、後方互換に対して高い互換性が維持されていた。数十年前にコンパイルされたバイナリモジュールがそのまま動作することが求められており、仕様はかなり詳細なレベルで明記されている(IBM社の「Principles of Operation」など)。

そのため、メインフレームの基盤更改の場合は、「業務アプリはほぼ変更せず、本業務稼働環境の横で別途構築された更改後のシステムに、本業務データを流し込んで、一定期間現新並行稼働させて、出力データに差異がないことを確認してから本番Go Liveする」という方式をとることができる。

オープン系システムにおける基盤更改の困難

上記の方針をオープン系のシステムにおいても採用しようとした基盤更改の取り組みが、2000年代前半に行われることがあったが、残念ながら、大きな問題を引き起こすことになる。その要因としては以下のようなことが挙げられる。

  • オープン系のシステムは、メインフレームと違って、ハードウェア・ソフトウェアの各スタック階層で、マルチベンダー実装が混在する。
  • スタック階層間のインタフェースレベルの整合性は何とか保たれるものの、振る舞いレベルの互換性の維持は困難。
  • オープン系では、メインフレームのように数十年前のプログラムに対する後方互換性よりも、機能追加の多さ・速さが求められていたため、後方互換も無視するわけではないが、注力する比率が相対的に低かった。
  • 実装が準拠する仕様が日進月歩で変化していったことで、仕様に準拠して振る舞いが徐々に変化していった。
  • 日進月歩での機能追加競争の中で、更改前はバグによって振舞っていた動作が、更改後は修正されて振る舞いを変えるということが発生する。
  • 明記された仕様に基づかない暗黙的な挙動が変更される。

その結果、業務アプリのリグレッションテストは、メインフレームのように、「完全に同じものを流せば同じ結果になる」というわけにはいかず、「入り口と出口だけ確認すればよい、差異が生じることは例外で、各々に対処すればよい」とはならなくなった。メインフレームではある程度成り立っていた、「現行踏襲」という要件は、オープン系システムでは要件として成り立たなくなったし、方針としても採用困難なものとなった。

そのため、全画面・全帳票・全バッチの機能確認試験および、性能試験・障害試験・運用試験を、人系のインテリジェントな判断を前提として実施する必要があり、システムの規模・複雑度が拡大するにつれて、コストと期間が、幾何級数的に拡大していった。

上記の経緯で早々に破綻した結果、各企業では、基盤更改は莫大なコストが掛かることから、投資案件となる要件、すなわち業務アプリ更改とタイミングを合わせて実施することが多くなった。

基盤更改に対してどのように取り組むべきか

基盤更改は、基盤更改単独ではなく、業務アプリ更改とセットで実施するべきだ。

業務アプリ更改でも、基盤更改でも、プロジェクトのコストの大半はテストに費やされる。「どうせコストが掛かるのであれば、両方を一緒のタイミングでやって、テストに掛かるコストを相殺しよう」、ということだ。

テストの次に多くの工数が掛かるのは、要件定義だ。「現行踏襲」という要件が使い物にならなくなった結果、暗黙的に現行踏襲を前提として始めたプロジェクトは、事実上、定義されていない要件に基づいて開始されることになるため、プロジェクト実施中に次々と未決事項・課題事項が発生し、やがて管理できる限界を超えて破綻してしまう。これを避けるためには、きちんと要件定義に取り組むことが必要であり、基盤更改の方が幾分かは楽になるが、業務アプリ更改のときに比べて格段に楽になるわけではない。

その結果、基盤更改のプロジェクト計画では、以下のようなことに注意が払われるようになった。

  • システム部予算の中期計画・長期計画で、基盤更改予定時期に合わせて、業務アプリ更改を計画する。
  • 基盤更改の目的は、製品保守切れ対応ではなく、現行維持保守課題の棚卸しと位置づけて、案件の計画時に、ユーザー部・基盤チーム・業務アプリチーム・運用チームの課題の洗い出し・吸い上げに注力する。(保守が切れることも維持保守課題の1つ。)
  • 経営課題は、業務アプリ更改にタイミングを合わせて、とりまとめと対策検討を行う。

上記の中でも、特に、アプリチームからの要件ヒヤリングは重要だ。

クライアント・ソフトウェア・スタック階層をフルに作り直してテストするには、投資案件として収益向上・コスト削減に直結する案件として予算確保して取り組む必要があるわけだが、5〜7年間程度の保守・運用期間で蓄積されてきたLessons Learned(教訓)を忘れてフルスクラッチで作り直すと、保守・運用期間の蓄積がゼロリセットされて、却って品質が低下してしまう。

こういうことは、現行本業務サービスの保守・運用に携わってきた業務アプリチームが多くの知見を有していることから、まず、プロジェクト計画フェーズで、十分に、変更要求・改善要望のヒヤリングを行い、当該プロジェクトではどこまで実施するのかを合意してから着手することが重要だ。

また、基盤更改プロジェクト開始後も、現行本業務サービス提供を通して生じた変更要求・改善要望が発生する。一般に、プロジェクトは、予め計画していた事柄に対する変動に弱く、プロジェクトの開始後に、予期せぬ変更が多く発生することは、プロジェクトを大混乱に陥れるに足る、重要なリスクとなる。いくら、ウォーターフォール型でフェーズ分割して、フェーズ間でイグジット・クライテリアを設けて取り組んでも、どうしてもその時々で、本業務サービス提供中に発生した変更要求・改善要望が生じてしまうものであり、通常、それらを切り捨てることはできないため、これらをコントロール下におくためには、着手後の要求・要望を吸収できるように、開発早期フェーズにおけるイタラティブ&インクリメンタルなプロジェクト設計が必要となる。

基盤更改プロジェクトの計画でやってはいけないこと

以下のような特徴を持つ基盤更改案件は、大炎上して失敗するリスクが非常に高いアンチ・パターンと言える。「予算が必要十分に確保できない」、「プロジェクト開始後に急速に未決事項・課題事項・変更要求が生じて管理・吸収できる限界を超えてしまう」、といったことが発生し、いわゆる炎上案件、デスマーチになってしまう可能性が高い。

  • 基盤更改と業務アプリ更改をセットにせず、業務アプリは極力変更しない方針とする。
  • 業務アプリチームで実施すべき事柄について定量的に見積もらずに過小評価する。
  • 業務アプリチーム、運用チーム、経営層からの要件のヒヤリングが浅い。
  • プロジェクト計画の策定時に、「案件が開始後にメンバーが揃ってから精緻化しましょう」と云って、具体的な検討を後回しにする。

コスト削減のための工夫

オープン系システムの規模と複雑さが拡大の一途を辿っている一方で、コスト削減の圧力が高まっていることから、コスト削減・CTOのために、以下のような取り組みも平行して行われている。

  • テスト自動化ツールの利用
    • リグレッションテスト
    • 負荷試験
    • 本業務サービス状況のキャプチャと、テスト環境での再生
    • CIツール
  • Webフロントなどのミッションクリティカル以外のシステムでのパブリッククラウド(XaaS)の利用(AWS, Azureなど)
  • 各種のSaaSの利用(Salesforce、サイボウズなど)
  • 初期投資コストは最小限度にしてシステム構築し、1/Nスケールのシステムでの負荷試験実績に基づいて、本業務環境で必要なリソースを追加調達する。

おわりに

上記は2010年頃までには成熟していたことであるため、現在から振り返ると10年以上過去から知られていた旧聞に属することであるが、現在でも、さまざまな規模の、さまざまな事情の企業があり、未だに黎明期に位置する企業もある。

そういった企業は、先行企業の実績を踏まえて最新技術を利用し始められる優位性がある一方で、AI、コグニティブ(という名のエキスパートシステム)、クラウド、と言ったバズワードに翻弄されて、成熟する機会を逸している面もある。

各企業、各アカウントで、各々、事情が異なるものだが、基盤更改は何度も繰り返されてきた営みであり、ある程度は、やるべきこと、やっていはいけないことが分かっている。自分の頭で考えて、咀嚼することは必要なことだが、考えるだけでは正しい解決方法にたどり着けないことが多いのも事実だ。常に、リファレンスする事例を調査して、Fit&Gapを評価してGapに対して集中して検討することが必要である。

| 日記 | comments(0) | trackbacks(0) |

ITシステムにおける新製品の採用について

業務システムで新製品を採用するときには、以下の何れかのパターンがあるように思う。

  1. 業務要件があり、新製品で実装可能な場合。
  2. ベンダーの営業マターで新製品を売りたい場合。

上記は排他的なわけではなく、各々の比率の大小はあっても、両方の要素を含むことが普通と思う。逆に言うと、上記の何れか一方だけに偏っている場合は、何らかの無理が生汁可能性が高まると思う。

海外・国内での実績がまだ少ない製品の場合は、ベンダーの手厚いサポートを約束させて取り組むことで成功留守可能性が高まり、ユーザー企業は要件が実装できるし、ベンダーは成功実績を作れるしで、Win-Winの関係になる。

悲劇的であるのは、新製品を売った後のシステム実装するデリバリーフェーズでのサポート力が弱く、まともに実装できずに炎上する、なんとかサービスインまでこぎつけても利用企業が少なくて保守フェーズで十分なサポートを受けられない、といったことになる場合だ。

ユーザ企業側で新製品を採用する場合は、以下のことに注意する必要があると思う。

  1. 国内・海外での利用実績。
  2. 上記実績の規模・複雑さ。
  3. 製品開発・保守ベンダーのデリバリーフェーズでのサポート体制。
  4. 業界トレンドに沿っているか。

例えば、大企業での複数の実績がある製品であっても、まだ本業務サービス提供に至っていないかもしれないし、サービス提供後であったとしても間もないかもしれないし、企業規模としては大きくても、当該システムは小規模だったり、社内系のミッションクリティカルでないシステムにおいて限定的な機能を利用しているだけかもしれない。

新製品採用時は、同業同規模の他社実績が十分あるものを選択するか、先進性高いものを提供ベンダーによる手厚いサポートをつけて余裕のあるスケジュールで取り組むか、いずれの方針とするのかを、明確にして取り組むことが望ましいと思う。

| 日記 | comments(0) | trackbacks(0) |

「旬魚菜酒処 中川」(蒲田)

JR/東急蒲田駅前の小料理屋。
うなぎ 藍の家」のビルの地下一階。

「味の山海里 口福」の料理人が独立して始めたとのこと。
「口福」に比べてお店はやや手狭になった。

元は「宗平(そうべい)」というお店の本店だったが、「宗平 西口店」は相変わらず「宗平」なので、こっちが「宗平 本店」になったのかな?もしくは、姉妹店の位置づけなんだと思う。



「口福」時代のフロア担当・客引きをしていたお母さんが相変わらず働いている。
「口福」ではメインが二つというのがインパクトあったが、こちらのお店は豚汁・ご飯お替り自由になって、インパクトは弱い。

まだ一度しか行ってないので、何度かランチに行って評価したいと思う。

旬魚菜酒処 中川
東京都大田区西蒲田7-27-5 City7 B1
大きな地図で見る


以下、「味の山海里 口福」の紹介時の記事。
--
JR/東急蒲田駅前の小料理屋。
細い方のアーケードを入ってすぐ左手の二階。

お母さんと若い板さんでやっており、ランチで訪問。
失礼ながら、居酒屋に毛が生えたくらいかと思って行ったので驚いた。

ここは良い店で応援したくなる。



ランチはたいていメインが2品らしい。ほかに、小鉢が一つに漬物と味噌汁。
この日は、鯛と大根の炊き合わせがどーんとあり、ミックスフライ、シラス丼、サーモン照り焼き、鯖照り焼きからどれかを選択。

サーモンと鯖は味が濃すぎたが、ご飯のお供としては許容範囲。
鯛と大根の炊き合わせが薄味で非常に美味。

良い店だと思う。また行きたい。

味の山海里 口福
03-3739-2029 東京都大田区西蒲田7-67-5 大黒ビル 2F
大きな地図で見る
| 飲食 | comments(0) | trackbacks(0) |
CALENDAR
Sun M T W T F Sat
 123456
78910111213
14151617181920
21222324252627
28293031   
<< May 2017 >>
WATCH
SEARCH THIS BLOG
LATEST ENTRIES
CATEGORIES
SELECTED ENTRIES
RECENT COMMENTS
RECENT TRACKBACKS
Twitter
MY WEB SITES
PROFILE
ADMIN
MOBILE
qrcode
ARCHIVES
SPONSORED LINKS