Living with legacy systems

361526561f688516bc1bd9463ecd18fe?s=47 fukudat
February 14, 2019

Living with legacy systems

デブサミ2019 14-A-6 「レガシーのいい感じの付き合い方」

361526561f688516bc1bd9463ecd18fe?s=128

fukudat

February 14, 2019
Tweet

Transcript

  1. レガシーとの いい感じの付き合い方 2019/02/14 #devsumiA 14-A-6

  2. None
  3. VOYAGE GROUP 3

  4. ECナビ(https://ecnavi.jp) ・2004年スタート ・ネットショッピングでお 得にポイントが貯まる、 ポイントサイト ・主婦層が中心

  5. 発表者

  6. セッション概要 • レガシーシステム改善に取り組む方に向けて、 • 15年物のレガシーシステムを4年間改善し続けている経験を 元に、「レガシーとのいい感じの付き合い方」をお伝えします。 • 「技術詳細」でなく「判断」寄りの説明が多いです。

  7. 時期 1999年頃〜 2015年10月〜 2016年6月 2016年7月〜 2017年11月 2017年12月〜 2018年4月 2018年4月〜 名称

    カイゼン前 カイゼン 事始め ECナビ AWS移行 旧管理系 AWS移行 カイゼン 継続中 環境 オンプレ オンプレ オンプレ →AWS(大半) AWS(大半) →AWS AWS カイゼンに取り組んだ2015年〜2018年の活動をお伝えし、 最後に振り返ります。 全体構成
  8. カイゼン事始め 時期 1999年頃〜 2015年10月〜 2016年6月 2016年7月〜 2017年11月 2017年12月〜 2018年4月 2018年4月〜

    名称 カイゼン前 カイゼン 事始め ECナビ AWS移行 旧管理系 AWS移行 カイゼン 継続中 環境 オンプレ オンプレ オンプレ →AWS(大半) AWS(大半) →AWS AWS
  9. 2015年当時の状況(システム周辺) • 事業ライフサイクルが、成長期から成熟期に差し掛かり始めた 頃。 • 事業方針を「収益成長 only」から「収益成長 and 業務改善」へ 転換

    ◦ ちょうど同時期に、事業全体での振り返りプロジェクトが実 施された。
  10. 2015年当時の状況(システム周辺) • エンジニア組織は、別ミッションを持つ2グループで構成。 ◦ 「システムと開発者の生産性を向上」 ▪ システム改善専任チーム • エンジニア組織内で意思決定する ◦

    「事業の各領域を成長させる」 ▪ 別チーム • 事業側と連動して開発を進める。
  11. 2015年当時の状況(システム概要) 古くて大規模 10〜15年物が半分 1089機能+900table 旧管理系サーバがカオス 200x年からメンテ放置 雑多詰め込み状態 インフラがオンプレ&別部門管 轄で、変更が遅い。

  12. 時間が経ち、さらに問題が広がる がけっぷち。 自分たちで変えてやる • オンプレ、データセンター撤退の予兆 • エンジニア新規採用、苦戦。 • 在籍エンジニア、モチベーションDOWN

  13. • 2015年10月〜12月の3ヶ月で、4-5人で調査とヒアリングした。 その後、事業全体での議論も実施。 • 機能一覧、テーブル一覧、コード量・半減期調査、機能相関分 析、サービス全体図、コスト管理、セキュリティ対策評価、イン フラ役割分担検討、etc… • 資料作成は、grep、静的解析、ログ解析、リバースエンジニア リング、などの手法で実施。新規作成がほぼ。

    事始め① 調査
  14. 具体例) 機能一覧 • 機能とパスを調べ上げ、分類をつけて、一覧形式に。 • 機能単位は、関係者全員で議論できるので便利

  15. • 【社内用語】 • 1単位 ◦ 対象:画面系:URL、バッチ系:crontabでの1行 ◦ 対象外:システム内部モジュール • 事業とシステムのインターフェースのような箇所に論点を絞る

    ことで、事業部全体で必要性の議論しやすくする。 ◦ より上段で必要性が判断できれば、詳細な必要性は後で 調べればよい。 事始め① 調査(機能とは?)
  16. 事始め② “葬り” • 【社内用語】不要な機能を削除すること • 初回6ヶ月実施、あとは随時実施。 • 「問題の分母を、手間を掛けずに減らす」効果

  17. 機能数の推移 2015年→2019年 1876→700

  18. テーブル数の推移 2015年→2019年 1200→813

  19. コード行数の推移 2015年→2019年 半減

  20. 無理しない方針 • 長期で段階的にカイゼン ◦ 短期のフルリプレースだと、規模的に非現実的。 • 取り組む問題は、絞る ◦ 発散してコツコツやっても、規模的に終わらない。 ◦

    「価値」と「工数」の評価軸で、選びとる。
  21. 無理しない方針(補足) • 評価軸 ◦ 価値 ▪ 「いま取り組むことで、長期&段階的カイゼンがより加速 していくか?」 ◦ 工数

    ▪ 「5人くらいのチームで、3〜6ヶ月内で完了できるか?」
  22. 調査&葬り後の現状 • インフラは、問題の量と複雑さ & オンプレ環境の制約 & 管轄 の問題が絡み合い、「少しずつカイゼンしていく」ことができな い。 •

    アプリケーションは、必要十分に絞った。機能追加と修正は随 時発生。 • アプリケーションをカイゼンするには、コントロールできるインフ ラがあると、進みが早い。
  23. 問題選定 • いま、取り組む! ◦ 自由なインフラ ▪ インフラとアプリを管轄を分けずに運用する ▪ レイヤー間で権限を分けず、開発者がコントロール可 能な状態にする。

    ◦ AWS移行 ▪ サービス全体をオンプレからAWS移行する ◦ 開発しやすい環境整備 ▪ 環境に依らず、アプリケーションを誰でも同じ開発フ ローで開発できるように、整備しておく
  24. 問題選定 • 先送り! ◦ アプリケーションの根本的見直し ▪ インフラの後で。 ◦ その他 ▪

    ソースコード&データベースがeuc-jp ▪ Oracleから卒業 ▪ 古いインフラ資産のリプレース(監視/ログ/LDAPなど ▪ 他サービスのAWS移転 ▪ サービス間の密結合・依存性の撤廃 ▪ メール配信サーバリプレース ▪ etc...
  25. まとめ(カイゼン事始め) • 調査&葬りにより、機能を必要十分に絞り、各機能の今後の位 置づけも把握できた。 • 問題自体はリストアップしつつ、無理しない方針と大雑把な判断 軸、だけ認識合わせをし、細かいロードマップを引かなかった。 • 「いま取り組む」と「先送り」をはっきりとさせた。

  26. ECナビAWS移行 時期 1999年頃〜 2015年10月〜 2016年6月 2016年7月〜 2017年11月 2017年12月〜 2018年4月 2018年4月〜

    名称 カイゼン前 カイゼン 事始め ECナビ AWS移行 旧管理系 AWS移行 カイゼン 継続中 環境 オンプレ オンプレ オンプレ →AWS(大半) AWS(大半) →AWS AWS
  27. 移行方針 • こだわる ◦ 自由なインフラを実現する ◦ AWS移行 ◦ 開発しやすい環境整備 •

    こだわらない ◦ 積極的に改良しない。既存要件を踏まえればよし。 ▪ アプリケーションのアーキテクチャ ▪ サーバ構成、ミドルウェア ▪ 監視、ログ収集
  28. • 期間 ◦ 2016年9月〜2017年2月ごろ ▪ 6ヶ月くらいで片付けよう。 ▪ 移行日は仮 スケジュール

  29. 先送り 移行範囲

  30. 移行先(範囲別詳細 • ecnavi-web ◦ EC2 ▪ 問題無さそう • MySQL ◦

    RDS MySQL ▪ 問題無さそう • Oracle ◦ RDS Oracle ▪ 不安…?
  31. 不安とは? • Enterprise Edition & RAC & アプライアンス • 既存と近しい要件が、RDS上では無い。

    • サービスレベルを変えない前提での、RDS上での最適構成が 不明。
  32. RDS移行 • ランニングコストの問題 ◦ Enterprise Edition(既存スライド案) ▪ 高価! ◦ Standard

    Edition(ダウングレード案) ▪ (価格だけ見ると)お値打ち! • ダウングレード案を深掘り、他の観点で実現可能か を検討していく
  33. ダウングレード案を検証 • 機能差 ◦ パフォーマンス情報収集が自前 ◦ メンテナンス作業が自前 • パフォーマンス ◦

    問題なし • データ移行時の互換性、移行時間 ◦ 問題なし • ※追加での開発および運用工数が発生するも、それでも断然 お得。
  34. • 検証期間 ◦ 2016年7月〜11月(5ヶ月) • 結果 ◦ ダウングレード案でGo ダウングレード案を検証

  35. • 期間 ◦ 2016年12月〜2017年2月 ▪ 移行実施タイミングは、2月or4月以降だったので、2月 を選択。 ▪ 残り3ヶ月で、データベース検証以外の移行タスクを片 付けていく。

    スケジュール(データベース検証後、調整
  36. • 開発しやすい環境整備に向けて、以下に絞って対応 ◦ AWSのリソース構築/変更 ◦ EC2のプロビジョニング • 選んだ理由 ◦ 今後の改善が加速させる為に、任意のバージョンの言語

    やミドルウェア環境を構築してテストができるようにする。 注力すること
  37. 目指す状態 • 普段のアプリケーション開発と同じ感覚で、開発/リリースがで きるようにする ◦ コード化する ◦ レビュー可能 ◦ リリースプロセスを自動化する

  38. AWSリソース構築 • リリースフロー

  39. • CloudFormationテンプレートでコード化 • sandbox環境と本番環境を用意 ◦ sandboxは、開発者に広く権限を渡し、試して壊すをやりや すく。 ◦ 本番は、sandboxで作った構成を再現すれば良い •

    レビューフロー(※開発者のスキルに合わせて ◦ 実際に構成を作ってからレビュー ◦ 不安であれば実際に作る前にレビュー 解説) AWSリソース構築
  40. プロビジョニング • リリースフロー S3 EC2

  41. 解説) プロビジョニング • Puppetマニフェストで管理 ◦ オンプレで利用されていたものをほぼコピー • 開発しやすい環境整備の視点で、改善した点 ◦ Puppetのversionを2系から当時の最新の4系へ

    ▪ 2系は、web上でノウハウ探せない状態 ◦ CircleCIでマニフェスト適用を試せるように ▪ 実際のサーバに依存したコードがあった為
  42. やってみた結果 新卒が権限追加依頼のPR投げる

  43. やってみた結果 EFS来た!使ってみようをアプリエンジニアから投げられる

  44. まとめ(ECナビAWS移行) • 全体を見通して、一番不安な問題から検証した。不安を解消して から、具体的な移行作業に入った。 • 達成したいゴールに対して、手段は今あるものを絶対とせず柔 軟に選び直した。 • AWSのリソース構築/変更、EC2のプロビジョニングに絞って、開 発しやすい環境整備を実現させた。

  45. 旧管理系AWS移行 時期 1999年頃〜 2015年10月〜 2016年6月 2016年7月〜 2017年11月 2017年12月〜 2018年4月 2018年4月〜

    名称 カイゼン前 カイゼン 事始め ECナビ AWS移行 旧管理系 AWS移行 カイゼン 継続中 環境 オンプレ オンプレ オンプレ →AWS(大半) AWS(大半) →AWS AWS
  46. 旧管理系サーバー • バックオフィス向け。10-15年選手多し。 ◦ 管理画面 (主にPHP、一部Perl CGI) ◦ バッチ (主にPerl、多種多様)

    • 新機能は「新」環境があるので、そちらで。
  47. 旧管理系サーバー • 位置付け ◦ 事業の大黒柱だが、枯れてる領域。 ◦ 粛々と安定稼働させたい。機能改良は不要で、修正も歴 史的に少ない。 • 移行後の新サーバ名:antique

  48. 旧管理系サーバーの内部イメージ

  49. アプリケーション 問題点(1) 規模 × レガシーあるある問題

  50. 225 管理画面のURL Path数 問題点(1) 規模 × レガシーあるある問題

  51. 470 バッチの数(crontab調べ) 問題点(1) 規模 × レガシーあるある問題

  52. レガシーあるある問題(※一部抜粋 • ユニットテストが書かれていないコード多数 • 継続的なテストが行われていないため、知らない間に動かなくなっている • 積み重なったパッチ的な対応の結果、膨れ上がったクラス • 同じような機能を持つライブラリ •

    Subversion の複数リポジトリが複雑に配置 • サードパーティのコードがリポジトリに含まれている • crontab で華麗にスケジューリング、順序が重要! • 局所最適結果として乱立するフレームワークとその亜種。 • アプリ間やアプリ-FW間の依存も強く、絶妙なバランスで動いている • 絶対パスによるファイルの参照 • 実行環境に依存するパラメータのハードコーディング • 他とは異なる開発/デプロイフロー(本番サーバーでsvn up) • 学習コストが高くなり結果として属人化 (※小さい問題は、他にも多数) :
  53. システム基盤 問題点(2) システム基盤周りがメンテし辛い

  54. None
  55. 古さの歴史的経緯 • OS、言語バージョン、ミドルウェアが、単純に古すぎ。 • 過去に数回サーバーリプレイスは実施したが、物理サーバの 載せ替えに留まり、この点は改善は無し。 ◦ 当時のリソース状況や事業状況により、問題点に対応しき るパワーが無かった。 ◦

    社内システムという甘え
  56. 単にEC2に移行した場合に残る問題 • アプリケーションやフレームワーク ◦ 数の多さ×レガシー満載 ◦ 開発しにくい環境 ▪ 膨れ上がった Subversion

    リポジトリ ▪ 本番環境に ssh ログイン & svn up • インフラ ◦ 「古い」ままのリスク ◦ 既にAWSで稼動中のシステムと異なる構成
  57. 移行時の改善ポイント • 開発しやすい環境整備 ◦ Subversion から Git へ ◦ パッケージ管理ツール(Composer/Carton)の導入

    ▪ Subversionレポジトリにコミットされた、サードパーティ のコードを移設 ◦ Jenkins による自動デプロイ • 自由なインフラ ◦ マシンイメージをAWS上の既存システムと同一に 。
  58. 移行時の先送りポイント • 先送り ◦ アプリケーションをクラウドネイティブな構成へ ▪ 改善ポイントに関わる所を、必要最小限で対応するに 留める ◦ ユニットテスト書いてカバレッジを上げる

    ▪ 時間が掛かりすぎるし、後からでもできる為
  59. テスト方針 • 1.新環境でユニットテストがパスする ◦ UTのカバレッジ低い。 ◦ UTを増やすのは、時間が掛かりすぎる。 • 2.本番に近い環境で、実際に動かして、アウトプットを照合する ◦

    課題:開発環境のデータは、本番環境とは程遠い
  60. テスト環境への要求 • 本番相当のデータを利用できる • データが壊れても元に戻る • 本番環境やユーザーに影響を与えない → 自由なインフラを活用する

  61. None
  62. 解説) テスト環境 • 「ECナビAWS移行」で構築した、CFn + Puppet で作成。 • AWS LambdaでCFnのChangeSetを作成し、日次でRDSスナッ

    プショットからリストア • 本番環境とはネットワーク上分離。メールサーバーは、送信を 外向けにブロック • エラー通知はSlackに転送し、エラー状況を可視化
  63. None
  64. 解説) テスト方法 • バッチ1つずつ ◦ 1.テスト環境でテスト ▪ 結果が、現行本番環境とテスト環境で比較して同一で あることで担保 •

    既存仕様で、メールでこと細かに実行結果が送ら れくるので、活用。 ◦ 2.テストがクリアしたら、新本番環境へ移行。現行本番環 境で停止。 • 実際実施してみると、想定通りには、いかず。
  65. バッチ一つ動かしてみると • ユニットテストが書かれていないコード多数 • 継続的なテストが行われていないため、知らない間に動かなくなっている • 積み重なったパッチ的な対応の結果、膨れ上がったクラス • 同じような機能を持つライブラリ •

    Subversion の複数リポジトリが複雑に配置 • サードパーティのコードがリポジトリに含まれている • crontab で華麗にスケジューリング、順序が重要! • 局所最適結果として乱立するフレームワークとその亜種 • 絶対パスによるファイルの参照 • 実行環境に依存するパラメータのハードコーディング • 他とは異なる開発/デプロイフロー(本番サーバーでsvn up) • 学習コストが高くなり結果として属人化 : エラーおおすぎ
  66. エラー要因 • 先にあげたあるあるの課題が足かせになって、エラーが大量 にでる。 • 特にハードコーディングとかライブラリの問題とか根幹の部分 のエラーが多く発生 • 軌道修正しよう

  67. テスト軌道修正(1) • エラー多発問題 ◦ 個別で無く横断的に把握してまとめて潰す。 ▪ 1.テスト環境で、全バッチをスケジュール通りに動作。 ▪ 2.エラーを捕捉分析して、原因に対処。

  68. テスト軌道修正(2) • 密結合・依存性問題 ◦ 移行単位をバッチ単位で無く、似たものグループ単位にし て、問題を軽減する。 ▪ 任意のバッチグループと管理画面を分けて

  69. 軌道修正後の進捗 • Slackエラー件数推移 ◦ 2018/1/21 1982 件 ← 全実行スタート ◦

    2018/1/30 528 件 ← 潰し回る日々 ◦ 2018/2/10 23 件 ← ほぼ問題無し • バッチは、まとまった単位で段階的に移行 • 管理画面は運用者含め、みんなでE2Eテスト後、一気に移行
  70. オンプレ卒業 • 約4ヶ月で、470 バッチ、 225 画面の移行 • 移行後のトラブルは、特に無し。安定稼働。

  71. まとめ(旧管理系AWS移行) • レガシーの厄介な問題に対して、手書き図のように大雑把に捉 えて把握し、要因に個別対処せずに解決する手段を考え出し た。 • システムに対する今後の期待を踏まえ、解決したい問題(自由 なインフラと開発環境の整備)と先送る問題を切り分けた。 • 取り組みながら見えてきた課題には、既存の実現手段に拘ら

    ず、手元の武器(AWS移行後の環境、バッチのメールなど)を組 み合わせて、新しい手段(テスト環境)を作っていく。
  72. 振り返り

  73. 時期 1999年頃〜 2015年10月〜 2016年6月 2016年7月〜 2017年3月 2017年4月〜 2018年9月 2018年10月〜 名称

    カイゼン前 カイゼン 事始め ECナビ AWS移行 旧管理系 AWS移行 カイゼン 継続中 環境 オンプレ オンプレ オンプレ→AWS(大半) AWS(大半)→AWS AWS カイゼン実績 • 全サービスのAWS移転、開発しやすい環境整備、アプリ・イン フラ運用、葬り済みの機能
  74. • 無理はしてない。 ◦ 普通に。 ◦ 長時間労働、要員追加、精神的ストレスは、特に。 • でも、着実にレガシーから脱却しつつある。 相当頑張った?

  75. • 「レガシーシステムは、問題の”数”と”質”の2面の難しさがあ る。でも、一度に取り組む数を減らせば、攻略は、少しずつだ が確実に進められるだろう」という認識があった。 • だから、各個撃破という戦法を選択した。 ◦ 問題の量と複雑さに苦しまないように切り分けて ◦ 1個ずつ各個撃破し

    ◦ コントロール可能な範囲を徐々に広げた。 ◦ 以上を繰り返す。 なぜ「無理せずカイゼンが進む」?
  76. • 現状把握から始める ◦ レガシーシステムの事実をカイゼンの立脚点とする • いま取り組む事を絞る ◦ 効果x工数のコスパの良さで見極める • 建設的先送り

    ◦ 色々手を出す位なら、先送る。 ◦ 周辺状況の変化により、あとの方が対応しやすくなること もある。 各個撃破を実現する基本動作
  77. レガシーとのいい感じの付き合い方 各個撃破! • 現状把握から始める • いま取り組む事を絞る • 建設的先送り はじめは、 問題を減らす

    & 解けるサイズに切り出すところから! ご清聴ありがとうございました