レガシーシステム洗い出し大作戦

 レガシーシステム洗い出し大作戦

Fb69c72d5af289d6674d2659246a5291?s=128

Tomohiro Nishimura

August 18, 2018
Tweet

Transcript

  1. レガシーシステム 洗い出し大作戦 2018/08/18 Kyoto.なんか

  2. こんにちは

  3. id:Sixeightです はてなで働いています (@tomohi_ro)

  4. みなさん引っ越したことはありますか

  5. 古い部屋から 新しい部屋に 荷物を移動するのは とにかく大変

  6. 持ち物をすべて出してきて 要らないものと要るものに分けて ダンボールに詰める (こんなもの持ってたっけ??)

  7. 新しい部屋に運んだら 適切な位置に荷物を配置していく (こっちを先に開ければよかった…)

  8. あれ、これどこかで…

  9. 古い部屋 ↓ 新しい部屋

  10. レガシーシステム ↓ 新システム

  11. 引っ越し • 古い部屋のにもつをすべて出す • 要るもの要らないものに分けてダンボールに詰める • 計画をたてて • 新しい部屋の適切な場所に配置していく

  12. システムマイグレーション • 古いシステムの機能を洗い出す • 整理して移行する機能と廃止する機能に分ける • 計画をたてて • 新しいシステムを適切に実装する

  13. None
  14. はてブの情報

  15. None
  16. システム移行の歴史 1. コア部分の開発 (Scala) 2. フロントエンド部分の開発 (Perl) 3. データ移行 4.

    面の移行 5. それ以外の移行
  17. システム移行の歴史 1. コア部分の開発 (Scala) ← 理想のはてブを作る 2. フロントエンド部分の開発 (Perl) ←

    理想のフロントエンドのベースを作る 3. データ移行 ← レガシーシステムのデータを理想の形に変換する 4. 面の移行 ← 実際に画面を移していく 5. それ以外の移行 ← 例えばAPIとか
  18. 2つのシステムが同時に動いている状態 もちろんDBなどもそれぞれ持っている (そういう話はまたいつかの機会に)

  19. ここから洗い出しの話

  20. システム移行の歴史 1. コア部分の開発 (Scala) 2. フロントエンド部分の開発 (Perl) 3. データ移行 4.

    面の移行 ← ここをやったときには 5. それ以外の移行
  21. 面の移行時の洗い出し

  22. 面の移行時の洗い出し • 勘でIssueを登録していく ◦ 新たな仕様が発掘されたら Issueを追加する • Projectで管理 ◦ MAY/SHOULD/MUST

    ◦ BACKLOG/DOING/WAITING/確認/DONE ◦ まとめ・情報 • 依存関係は別のProjectを作って管理
  23. 依存関係とスケジュールをまとめて管理する • 機能間の依存関係を勘で並び替えて、それぞれ勘で見積もってこの週にはこれを やりますというのを決めた • 新たな依存関係が見つかったら並び替える • 「今週の進捗はこんな感じです、来週これをやるので、この辺の調査や調整をお願 いします。」みたいな確認作業をするのにも使っていた

  24. システム移行の歴史 1. コア部分の開発 (Scala) 2. フロントエンド部分の開発 (Perl) 3. データ移行 4.

    面の移行 ← ほぼ完了したものの… 5. それ以外の移行
  25. 先の見えない不安 • あとどのくらい残っているのか分からない ◦ 全体でどのくらいの量があって、いまどのくらい終わっているのかが分からない ◦ 樹海を闇雲に走っている状態 • 次から次へと想定外の出来事が発生 ◦

    こんな仕様もあったぞ! ◦ こっちのリソースにも依存していたからこれを先にやらないと! ◦ これは実はこういう握りがあって …
  26. 問題への対策 • あとどのくらい残っているのか分からない ◦ → 網羅的に洗い出すしかない • 次から次へと想定外の出来事が発生 ◦ →

    依存関係を明確にするしかない
  27. ちゃんと洗い出しをしないといけない

  28. なぜこれまで出来なかったのか • 10年を超える歴史の中で増改築を繰り返した結果… • 膨大なコード量 ◦ → 全て洗い出すだけで年単位で工数が必要 ◦ →

    そんな工数取れないでしょという風潮 • 失われた経緯 ◦ → 考古学者のように辛抱強く過去を解きほぐす必要がある
  29. システム移行の歴史 1. コア部分の開発 (Scala) 2. フロントエンド部分の開発 (Perl) 3. データ移行 4.

    面の移行 5. それ以外の移行 ← いまここ
  30. 現実的な洗い出し

  31. エンドポイント視点で洗い出す • すべてのエンドポイントを洗い出す ◦ → 機械的に洗い出す • とにかく一覧できるのが重要 ◦ →

    物量に絶望できる = 物量が見える
  32. Googleスプレッドシート

  33. None
  34. エンドポイント洗い出し時にあった方がよい項目 • Controller#Method (複数のURLが紐付いている可能性があるのでユニークな キーとして扱う) • エンドポイントのURL (複数あるなら検索用にそれも) • 調査時点のコードへのリンク

    (実装にすぐにたどり着きたい) • Issueへのリンク (対象について扱うIssueを作っておく) • 用途 (完全に理解したとしても翌日には忘れているので書いておく) • メモ (これ不要では???みたいなことを書く) • その他状態を表現するフラグ達
  35. リソース視点で洗い出す • 依存関係を洗い出す ◦ → 使っているリソースを明確にする • 地道な努力 ◦ →

    ひたすらコードを読むしかない
  36. エンドポイント単位でのリソース依存の洗い出し • 一行一依存として記録していくと扱いやすい ◦ → 後述 • まとめIssueを作って、各機能のIssueを紐づけていく ◦ →

    すべてのIssueがクローズされたら、そのリソースへの依存はなくなったとみなせる ◦ → まとめIssueに作戦を経緯として残し、各 Issueに細かい経緯を残す
  37. 他の切り口 • Worker単位でのリソースの依存 • Cron単位でのリソースの依存 • その他のわかりやすい切り口を見つけて洗い出していく

  38. 一行一依存として記録していくと扱いやすい • コードを読んで使っているリソースを全て洗い出していきます ◦ 1リソース1行で書いていく • 疲れてくるので、息抜き用のタスクを用意しておくと吉

  39. 一行一依存として記録していくと扱いやすい 行と列をひっくり返すと、リソースに依存するエンドポイントの一覧が手に入る IFERROR(TRANSPOSE(FILTER(範囲, 条件1, 条件2)), “”)

  40. 調査時に気をつけること • 人間の記憶を信頼しない ◦ 調べきれていなくても目についたところはメモしておく • コードへのリンクは細かめに ◦ 調査時のリビジョンを必ず含める ◦

    重要な処理ごとにリンクをする • 処理の流れを追える書き方にする ◦ 詳細を読まなくても処理が把握できる
  41. 視点 • 参照系の移行 ◦ → エンドポイント毎にリソースへの依存を明確にする ◦ → 依存の下流から移していけば安全 •

    更新系の移行 ◦ → グループ化して、グループ毎のリソースの依存と、グループ間の依存を明確にする ◦ → まとめて移行する必要がある ◦ → 依存の上流から移していけば安全
  42. どうしても言いたいことコーナー • 使ってないコードは消しましょう! ◦ 使っていないことを証明するのは困難 • 辿れる場所に経緯を残しましょう! ◦ 辿れない場所にある情報は存在しないのと同じ ◦

    本人しか知らない情報は存在しないのと同じ
  43. まとめIssueを作る • エンドポイント/機能単位でのIssueをまとめる ◦ まずは先程洗い出したエンドポイントの Issueを紐づけていく ◦ すべて閉じたらこのリソースへの依存はなくなっている ◦ チェックボックスをつけておくと何かとべんり

    • どのような対応が必要かによってセクションを分ける ◦ 何をすればいいのか明確にする • 作戦の相談などもこのIssueでやる ◦ 経緯を残しましょう
  44. まとめIssueからの洗い出し • 次はまとめIssueを起点に漏れていたものを調査する ◦ たとえば内部的な機能があったりする ◦ ステークホルダーを明らかにする • どんどんIssueを作ってまとめIssueに紐づけていく ◦

    すべてのタスクが洗い出せている状態を目指す • このタイミングで別の切り口のまとめIssueができるかもしれない ◦ 「ユーザー向けAPI移行作戦会場」とか「 XXX(サービス名)が使っているAPI一覧」とか ◦ ロール単位、機能単位、用途単位などのまとめ Issueが出来ていた
  45. やっぱりProjectで管理する • タスクの分類と進捗状況の確認(全体感の把握)を同時にやる ◦ 毎日眺めて状況を確認して、調査や調整などの先手を打つ ◦ 週一でDと一緒に全体の進捗を確認したり懸念点を洗い出したりする • 調整が済んで手を動かすだけになったタスクからTODOに入れていた ◦

    自分がやるときや、手が空いた人にお願いするときにすぐ出せるリストとして利用
  46. ポイント • 最初に切り口を決めて、その中での優先度順に洗い出していく ◦ → すべてを洗い出すのは無理だし、どこから手を付けるかを決める ◦ → 機械的に洗い出せるところを起点にすると楽 ◦

    例「サーバーの移行が先決、このサーバーを潰すにはこのサーバーが管理しているリソースを使わ なくなればよい、エンドポイントごとにリソースの依存を洗い出そう」 • その結果を使って、別の切り口で関連するものを洗い出していく ◦ → 複数の視点で洗い出さないと漏れができる ◦ → 関連するものを見ればいいので取り掛かりやすい
  47. 機能廃止について • 断捨離のチャンスなので機能の整理をして、工数も削減するとよい ◦ 全ての機能を移行する必要はない ◦ もう使われていないものもある ◦ 依存が複雑すぎて移行の工数を考えると廃止した方がマシな場合がある •

    廃止したい機能一覧を作って、1つ1つ検討、調整をした ◦ 確定したものから廃止していく ◦ レガシーシステムから機能やコードを剥がせば剥がすほど移行は楽になっていく
  48. まとめ

  49. 洗い出し成功によって得られた成果 • 必要な作業の全体像が見えてきて計画が立てやすくなった ◦ 物量が見えてきたのでここまでやったら終わりというのが見えてきた • このサーバーを移行するには、このエンドポイントとこの機能が潰せていると良いで すねのようなことが言えるようになった ◦ 作業量見積もりについて具体的な話ができるようになった結果無理な目標も現実的に

    • 予期せぬ事態がだいぶ減った気がする (肌感覚) • 洗い出しにしっかり工数をさけるようになった
  50. 課題 • 単純に大変 ◦ 必要な工程だと思うがもうちょっと省力化したい • 見積もりの知見が足りずに成果物を活かしきれていない ◦ 大中小くらいで見積もって、これは大だから時間がかかりますねくらいの雑さだった •

    コードから分からないことを洗い出すのが難しい ◦ この機能は実はこういう握りがあってみたいなのが突然現れて頭を抱えたりする
  51. 引っ越しがんばりましょう