Speee DEVELOPER BLOG

Speee開発陣による技術情報発信ブログです。 メディア開発・運用、スマートフォンアプリ開発、Webマーケティング、アドテクなどで培った技術ノウハウを発信していきます!

追加開発プロジェクトでソフトウェア考古学に触れた話

この記事はSpeee Advent Calendar 2018 - Qiitaの12/21分の記事です。
この記事は hayato-iidaTei1988 が執筆しています。

ソフトウェア考古学とは

ソフトウェアプロダクトはコードと運用が合わさって価値を生み出すものですが、
長い年月運用されつづけることで少しづつ人が入れ替わり、当初の設計想定や運用想定が徐々に失われていきます。

ソフトウェア考古学とは残されたコードや運用業務から開発当初の意思を汲み取り、未来へつなげる仕事なのです。

なにこれ

遠い過去に作られ、永らく運用され価値を生み出していたものの、開発の手が入っていなかったプロダクト。
このプロダクトに対して新規機能追加改修するプロジェクトに参加し、成功に導くまでに得た、問題や知見をまとめます。

発掘編

まずは現状把握しようということでコードや運用を紐解くところから始めました。

コードはどこに?

社内のプロジェクトは全てGitに移行していたと思っていたが、このプロジェクトのコードは過去に使っていたSVNにしか存在していなかった。
SVNからコードを持ってこられたのだがなぜかファイルが足りずコンパイルが通らない。
幸い前任者が社内にいたので最新版をコミットしてもらって事なきを得た。

儀式化した運用業務

業務全体を把握している人がいなくなっており、残されたのは細かく分けられた運用と、それぞれの業務マニュアルだけだった。
そこには運用業務についてのみ記述されており、状況が変わっても運用を見直すことはもはやできなくなっていた。
不要な業務は残り続け、本来の目的を失って、まるで儀式のように行われていた。

みんなの仕様の知識を合わせても100%に届かない

上記のとおり全体像を把握している人間がいないので各自で持ち寄った知識や調査結果から元の仕様を再構成していった。
毎日新しい発見があり、非常に充実した発掘ライフを楽しんだ。

プログラムの振る舞いをコードから読み解いていくことで、本来想定していたであろう運用と儀式化された運用の間のミッシングリンク(失われた仕様)を見つけだしたこともあった。

業務全体の把握のため、コードの読み解きや運用のヒアリングを丁寧に行い、下記のようなドキュメント作成して現状の把握し、改修に備えた。

  • AsIsの業務フロー図
  • ER図
  • フローチャート
  • バッチの一覧表
  • システム構成図
  • サーバ構成図

正しく動いているかわからない

システムとして監視ができておらず手作業による監視をしていたが運用が引き継がれていくなかで適切にチェック項目が更新されておらず、正しく監視されなくなっていった

現状にあわせてチェック項目を再定義し、自動でチェックされる仕組みを構築した。

改修編

現状把握を踏まえた上で、根本的な体質改善を検討して実施していきました。

コード管理のモダン化

コード管理をSVNからからgitに変更し、PRレビューを必ず挟んでマージしていくフローに変更した。

Staging環境の構築

テスト用の環境が無かったので同一の環境を構築し、Staging環境でリリーステストをしないと本番にリリースできない手順にした。

CI/CDの導入

Jenkinsを立ててCIが実行されるようにした。
CDもあわせて構築し、必ずJenkinsからデプロイすることにした。

ジョブ管理

cronをやめてJenkinに移行し、ジョブの死活管理や再実行をし易い環境を構築した。

テストコードを書く意思決定

もともと既存コードに対してテストコードが一行も書かれていないところに追加改修を行う形だったので、以下の方針でテストコードを書いていくことにした。

  • 既存コードについてはEndToEndのテストを先に書いて動きの調査をするとともに、既存の動きに影響を与えていないことを確認。
  • 新規に書くコードについてはUnitTestを記述して、レビュー、改修、リファクタリングしやすい状態を目指す。

時間は限られていたものの、これをやったことでかなり品質が担保できた。

運用業務のリファクタリング

AsIsの運用からToBeの運用を再定義し、目的が失われないようにすべてドキュメント化しながら進めていった。
それと同時にシステム側でできる運用範囲を拡大し、人間が入る余地を減らす方針をたてて改修していった。

リリーステストが全部通るまでリリースしない

リリースに向けて既存機能も含めたテストコンディションを作成し、このテストを3周回すスケジュールを立てて取り組んだ。

周毎に出るバグについては必ず再現するUnitTestを書いてから改修することにした。
また、一つのバグが別のバグを隠していることが多いので、バグを起こしたコンディション以外のテストも毎回全部回すことにした。

結果最後の3周目で軽微なバグが出たので、そこでもう一周回す判断をし、改修した後に4周目のコンディションをすべて回してバグ0件になったためリリースの判断をした。

もしここでバグが出ていたらリリースを伸ばしてもう一周テストを回していた。

結果としてはリリース後のバグ0件で運用負荷を大きくさげることができた。

チームとして話しやすい環境作り

tech.speee.jp

上の記事でも大切さを語っている心理的安全性やHRTを重視したチーム作りを進めていた。
全員の知識を合わせても100%にならない問題とあいまって、日々新たな問題や、仕様の発見を気軽に共有できるように意識していた。
その結果ちょっとした気付きや違和感などをチームで気軽に話せるようになり、結果的に重要な課題に気がつくことができたりするなど、見えづらいところだが重要なポイントだった。

まとめ

振り返ってみるとAsIsの整理をして、わかりやすくドキュメントにまとめて、みんなでToBeを考えて、実現可能な実行計画をたてて進めていくというのが重要でした。
また、稼働して価値を生んでいるプロダクトではあるので、作ってきた人や、運用してきた人へのHRTは忘れずにコードを憎んで人を憎まずの精神でやっていくという点もチームの精神衛生上重要だったと思います。