株式会社日立ソリューションズ

株式会社日立ソリューションズ

300画面の大規模Webシステム「建設業情報管理システム」をRubyで構築、開発規模を1/5に削減

日立ソリューションズは、一般財団法人 建設業情報管理センター(CIIC )の「第7期建設業情報管理システム」をRubyで構築し、2013年4月にカットオーバーした。

今回開発した建設業情報管理システムは、建設業の分野で欠かせない手続きである「建設業許可」と「経営事項審査」の業務を支援する。建設業は、約47万社の建設企業と100万人以上の技術者を抱える一大産業であることから、建設業を営むには必要不可欠の手続きである「建設業許可」手続きの規模は膨大なものとなる。

また、公共工事での入札では業者を事前に登録するが、このとき「経営事項審査」の通知書が必要となる。毎年約15万社が審査を受けることから、ここでも膨大な事務作業が発生する。新システムはこれらの業務を支援するシステムであり、責任は重い。 今回開発した「第7期建設業情報管理システム」は、同じ業務のために作られた従来のシステムを置き換えるものだ。従来のシステムはやはり日立ソリューションズが開発したもので、Javaにより構築されていた。これをよりコンパクトかつカスタマイズ性を高くすることが、新システムの目標であった。

Rubyによりコード規模を圧縮、システム変更を容易に

Ruby採用の理由としては、システムの変更をより短期間に、効率よく行いたかったことが大きい。制度 の改正によりシステムの要件は変わるが、こうした変化に対応するにはRubyの特性が有効だと考えたのである。

「『経営事項審査』は制度改正により、 かなりの頻度でシステムの改修が発生する。変わる事を前提に、がちがちのシステムではなく、簡単に手を入れられてしかも品質が良いシステムを作りたかった」(同社)。

従来のシステムが過去10年におよぶ改造の繰り返しで複雑化していたことも、背景としてあった。今後のランニングコストとなるシステム改修のコストを下げたかったことが、Ruby採用の大きな動機だったのである。

第1フェーズで従来のシステムを再現、第2フェーズで新たな要件を取り入れ

今回のシステム構築では、第1フェーズ、第2フェーズの2段階を踏んでプロジェクトを進めた。ここで目を引くのは、「第1フェーズ」では従来のシステムとまったく同じ仕様のシステムをRubyで開発し、第2フェーズで新たな要件を入れるやり方を採ったことだ。

このようなやり方を採用した理由は、第1フェーズ は従来のシステムとまったく同じ仕様であることから要件定義が不要となること、それにRubyベースで従来の システムと同じ仕様・挙動のシステムを開発可能であることを早い段階で実証できることである。

「(従来のシステムの場合と)同じものを入力してテストしたかった。同じものを入力して同じ結果が出ることで、Rubyベースの新システムの採用を進めやすくなる」。

また、顧客に対して早期に「動くもの」を見てもらい、確認できることは大きなメリットだった。

「第1フェーズの終わりで、実際に動いている『もの』を見ることができる。検収期間の数カ月前に動いているものを見て安心していただける。イメージと違うのであれば早めに意見を吸い上げられる」(同社)。

もう一つの理由は、第1フェーズを進行する間に、第2フェーズで追加する要件を洗い出して決定する工程を進めることにより、プロジェクトをよりスピーディに進行させようとしたことである。「要件定義や設計の部隊は独立して動けた」(同社)。

新システムの仕様については、明らかに決まっているものと、仕様決定までに「悩みたい」ものとがあった。第1フェーズについては従来のシステムと同じものを作ることで、「悩みたい」部分は第2フェーズに持ち越すことができる。

Javaベースの従来のシステムに比べコード規模は1/5に

今回のシステムは、2011年7月に入札の公示が出された。これを受け、日立ソリューションズは本格的な開発に入る前に、Web系とバッチ系の主要機能をRubyにより先行開発し、生産性や性能などを検証した。この結果、システム全体をRubyで再構築するプランを採用することにした。

2012年6月末、前述した「第1フェーズ」のシステム、すなわち従来のシステムとまったく同じ仕様のシステムが完成した。

2012年の10月から11月にかけて、第2フェーズを開発した。ここでは、制度改正による新たな要件も取り入れた。その後、リリースに至るまでの期間、品質確保と性能対策を進めた。カットオーバーは前述のように2013年4月8日 である。

システム規模は画面数300と大きなものだ。Javaベースの従来のシステムは、2002年頃に独自フレームワークを用いて構築したもので、バッチ処理などは速度を重視してC言語で開発していた。この開発規模は約450kステップである。一方、Rubyベースの新システムは約100kステップである。テーブル数は約100、29のバッチ処理もRubyによる開発で一本化した。

新旧の両システムを比べると、ステップ数換算では1/5の規模で開発できたわけだ。

「100kステップ のRubyコードのほとんどはバリデーション。値のチェックが複雑なのがこのシステムの特色」(同社)。Ruby on Railsにはバリデーションのサポートがあるが、今回のシステムではRailsフレームワークを拡張することで複雑なバリデーションを実現した。「アプリケーションの各部分に記述が散らばる形ではなく、フレームワーク内の一カ所にバリデーションを記述できた。このやり方はうまくいった」(同社)。

開発会社として、島根県の開発会社である株式会社プロビズモが協力している。Rails上に開発するアプリケーションの実装は主にプロビズモが担当した。一方、日立ソリューションズ側はRailsフレームワークの内部を拡張する開発を主に担当した。このフレームワーク拡張部分の規模 は約6kステップである。アプリケーションとフレームワークで協調したわけだが、このとき両社は「責任分界点、一括請負といった常識を超えて 、一致協力して開発した」と話す。

今回のシステムは、日立ソリューションズとしても大きな挑戦だった。それまでの最大規模のRubyベースのシステムをはるかに上回る開発規模だったからだ。しかも、複雑な業務知識を大量に織り込んだシステムである。

品質管理と性能対策も、今回のシステム構築の課題だった。品質管理としては、ここまでの大規模Ruby案件は初めてだったことから、「過去の実績がなく、バグ曲線をどこで収束させれば良いのか判断が難しかった」。フェーズ1として、従来のシステムと同仕様のシステムを開発したことには、品質確認の意味もあった。

500Kステップのテストケースを書き、チューニングで高速化

今回のシステムの構築では、日立ソリューションズ内の「Rubyセンタ」が大きく貢献した。Rubyベースの大型案件を成功させるべく、会社を挙げて取り組んだ格好である。例えば、Rubyセンタ側からは「Rubyは動的言語だから、テストを徹底しよう」という掛け声をかけた。

そこで今回のシステム構築では、テストの徹底を図った。「コードカバレッジを100%にする」との高い目標をかかげ、テストコードを大量に書いた。その結果、テストケースが500Kステップと、システム本体よりはるかに大規模なものとなった。「テストケースが10万件でテスト時間も10時間と大規模なものになった。テストを書きすぎた。この反省から、以降のプロジェクトでRubyセンタはテストケースを薄く広くかくことを推奨している。」(同社)。

このような反省はあったものの、今後何年にもわたって改修を続けていくことが確実なシステムであるため、テストコードは無駄にはならない。「テストコードは一回作ったら資産」(同社)。結果として、バグを出しにくいシステムを作ることができたと同社は考えている。

性能対策でも苦労があった。従来のシステムではCでバッチ処理を開発していたのだが、「Rubyベースの新システムで、バッチが同等の性能で動くこと」が求められた。

「当初、C言語で1時間半かかるバッチがあり、Rubyで組んだところ当初は70時間かかった」。これをチューニングして、なんとか1時間半まで押さえ込んだ。「ActiveRecordを外した。これによりメモリ上に大量のオブジェクトが作られることがなくなりGC(ガーベジコレクション)の回数も減った。GCのチューニングも徹底的に行った。最後は並列化も導入した」(同社)。

もっとも、こうしたチューニングは予想の範囲内だった。もともとC言語で書いていた処理をRuby on Railsで何の工夫もなく書いたのでは、速度が出る訳がないからだ。

特に気を配ったのは、処理の順序性が重要となるバッチ処理である。順序性が重要ということは、並列処理には適さないということだ。「細かいことの積み上げでチューニングした。GC停止時間を短くするなどを繰り返し、性能目標を達成した」(同社)。

このように、大規模で複雑な業務システムにRubyで挑んだ同社は、拡張したRuby on Rails上のアプリケーションと充実したテストという、新たな世代のシステム資産を築き上げた。構築時にはテストコードの記述や性能のチューニングで苦労はしたが、新システムは今後数年間にわたる改修作業の負担を軽減してくれるはずだ。

参考写真

image01 image02 image03

※本事例に記載の内容は2014年3月取材日時点のものであり、現在変更されている可能性があります。