デブサミ2019 14-A-6 「レガシーのいい感じの付き合い方」
レガシーとのいい感じの付き合い方2019/02/14#devsumiA 14-A-6
View Slide
VOYAGE GROUP3
ECナビ(https://ecnavi.jp)・2004年スタート・ネットショッピングでお得にポイントが貯まる、ポイントサイト・主婦層が中心
発表者
セッション概要● レガシーシステム改善に取り組む方に向けて、● 15年物のレガシーシステムを4年間改善し続けている経験を元に、「レガシーとのいい感じの付き合い方」をお伝えします。● 「技術詳細」でなく「判断」寄りの説明が多いです。
時期 1999年頃〜2015年10月〜2016年6月2016年7月〜2017年11月2017年12月〜2018年4月2018年4月〜名称 カイゼン前カイゼン事始めECナビAWS移行旧管理系AWS移行カイゼン継続中環境 オンプレ オンプレオンプレ→AWS(大半)AWS(大半)→AWSAWSカイゼンに取り組んだ2015年〜2018年の活動をお伝えし、最後に振り返ります。全体構成
カイゼン事始め時期 1999年頃〜2015年10月〜2016年6月2016年7月〜2017年11月2017年12月〜2018年4月2018年4月〜名称 カイゼン前カイゼン事始めECナビAWS移行旧管理系AWS移行カイゼン継続中環境 オンプレ オンプレオンプレ→AWS(大半)AWS(大半)→AWSAWS
2015年当時の状況(システム周辺)● 事業ライフサイクルが、成長期から成熟期に差し掛かり始めた頃。● 事業方針を「収益成長 only」から「収益成長 and 業務改善」へ転換○ ちょうど同時期に、事業全体での振り返りプロジェクトが実施された。
2015年当時の状況(システム周辺)● エンジニア組織は、別ミッションを持つ2グループで構成。○ 「システムと開発者の生産性を向上」■ システム改善専任チーム● エンジニア組織内で意思決定する○ 「事業の各領域を成長させる」■ 別チーム● 事業側と連動して開発を進める。
2015年当時の状況(システム概要)古くて大規模10〜15年物が半分1089機能+900table旧管理系サーバがカオス200x年からメンテ放置雑多詰め込み状態インフラがオンプレ&別部門管轄で、変更が遅い。
時間が経ち、さらに問題が広がるがけっぷち。自分たちで変えてやる● オンプレ、データセンター撤退の予兆● エンジニア新規採用、苦戦。● 在籍エンジニア、モチベーションDOWN
● 2015年10月〜12月の3ヶ月で、4-5人で調査とヒアリングした。その後、事業全体での議論も実施。● 機能一覧、テーブル一覧、コード量・半減期調査、機能相関分析、サービス全体図、コスト管理、セキュリティ対策評価、インフラ役割分担検討、etc…● 資料作成は、grep、静的解析、ログ解析、リバースエンジニアリング、などの手法で実施。新規作成がほぼ。事始め① 調査
具体例) 機能一覧● 機能とパスを調べ上げ、分類をつけて、一覧形式に。● 機能単位は、関係者全員で議論できるので便利
● 【社内用語】● 1単位○ 対象:画面系:URL、バッチ系:crontabでの1行○ 対象外:システム内部モジュール● 事業とシステムのインターフェースのような箇所に論点を絞ることで、事業部全体で必要性の議論しやすくする。○ より上段で必要性が判断できれば、詳細な必要性は後で調べればよい。事始め① 調査(機能とは?)
事始め② “葬り”● 【社内用語】不要な機能を削除すること● 初回6ヶ月実施、あとは随時実施。● 「問題の分母を、手間を掛けずに減らす」効果
機能数の推移 2015年→2019年1876→700
テーブル数の推移 2015年→2019年1200→813
コード行数の推移 2015年→2019年半減
無理しない方針● 長期で段階的にカイゼン○ 短期のフルリプレースだと、規模的に非現実的。● 取り組む問題は、絞る○ 発散してコツコツやっても、規模的に終わらない。○ 「価値」と「工数」の評価軸で、選びとる。
無理しない方針(補足)● 評価軸○ 価値■ 「いま取り組むことで、長期&段階的カイゼンがより加速していくか?」○ 工数■ 「5人くらいのチームで、3〜6ヶ月内で完了できるか?」
調査&葬り後の現状● インフラは、問題の量と複雑さ & オンプレ環境の制約 & 管轄の問題が絡み合い、「少しずつカイゼンしていく」ことができない。● アプリケーションは、必要十分に絞った。機能追加と修正は随時発生。● アプリケーションをカイゼンするには、コントロールできるインフラがあると、進みが早い。
問題選定● いま、取り組む!○ 自由なインフラ■ インフラとアプリを管轄を分けずに運用する■ レイヤー間で権限を分けず、開発者がコントロール可能な状態にする。○ AWS移行■ サービス全体をオンプレからAWS移行する○ 開発しやすい環境整備■ 環境に依らず、アプリケーションを誰でも同じ開発フローで開発できるように、整備しておく
問題選定● 先送り!○ アプリケーションの根本的見直し■ インフラの後で。○ その他■ ソースコード&データベースがeuc-jp■ Oracleから卒業■ 古いインフラ資産のリプレース(監視/ログ/LDAPなど■ 他サービスのAWS移転■ サービス間の密結合・依存性の撤廃■ メール配信サーバリプレース■ etc...
まとめ(カイゼン事始め)• 調査&葬りにより、機能を必要十分に絞り、各機能の今後の位置づけも把握できた。• 問題自体はリストアップしつつ、無理しない方針と大雑把な判断軸、だけ認識合わせをし、細かいロードマップを引かなかった。• 「いま取り組む」と「先送り」をはっきりとさせた。
ECナビAWS移行時期 1999年頃〜2015年10月〜2016年6月2016年7月〜2017年11月2017年12月〜2018年4月2018年4月〜名称 カイゼン前カイゼン事始めECナビAWS移行旧管理系AWS移行カイゼン継続中環境 オンプレ オンプレオンプレ→AWS(大半)AWS(大半)→AWSAWS
移行方針● こだわる○ 自由なインフラを実現する○ AWS移行○ 開発しやすい環境整備● こだわらない○ 積極的に改良しない。既存要件を踏まえればよし。■ アプリケーションのアーキテクチャ■ サーバ構成、ミドルウェア■ 監視、ログ収集
● 期間○ 2016年9月〜2017年2月ごろ■ 6ヶ月くらいで片付けよう。■ 移行日は仮スケジュール
先送り移行範囲
移行先(範囲別詳細● ecnavi-web○ EC2■ 問題無さそう● MySQL○ RDS MySQL■ 問題無さそう● Oracle○ RDS Oracle■ 不安…?
不安とは?● Enterprise Edition & RAC & アプライアンス● 既存と近しい要件が、RDS上では無い。● サービスレベルを変えない前提での、RDS上での最適構成が不明。
RDS移行● ランニングコストの問題○ Enterprise Edition(既存スライド案)■ 高価!○ Standard Edition(ダウングレード案)■ (価格だけ見ると)お値打ち!● ダウングレード案を深掘り、他の観点で実現可能かを検討していく
ダウングレード案を検証● 機能差○ パフォーマンス情報収集が自前○ メンテナンス作業が自前● パフォーマンス○ 問題なし● データ移行時の互換性、移行時間○ 問題なし● ※追加での開発および運用工数が発生するも、それでも断然お得。
● 検証期間○ 2016年7月〜11月(5ヶ月)● 結果○ ダウングレード案でGoダウングレード案を検証
● 期間○ 2016年12月〜2017年2月■ 移行実施タイミングは、2月or4月以降だったので、2月を選択。■ 残り3ヶ月で、データベース検証以外の移行タスクを片付けていく。スケジュール(データベース検証後、調整
● 開発しやすい環境整備に向けて、以下に絞って対応○ AWSのリソース構築/変更○ EC2のプロビジョニング● 選んだ理由○ 今後の改善が加速させる為に、任意のバージョンの言語やミドルウェア環境を構築してテストができるようにする。注力すること
目指す状態● 普段のアプリケーション開発と同じ感覚で、開発/リリースができるようにする○ コード化する○ レビュー可能○ リリースプロセスを自動化する
AWSリソース構築● リリースフロー
● CloudFormationテンプレートでコード化● sandbox環境と本番環境を用意○ sandboxは、開発者に広く権限を渡し、試して壊すをやりやすく。○ 本番は、sandboxで作った構成を再現すれば良い● レビューフロー(※開発者のスキルに合わせて○ 実際に構成を作ってからレビュー○ 不安であれば実際に作る前にレビュー解説) AWSリソース構築
プロビジョニング● リリースフローS3 EC2
解説) プロビジョニング● Puppetマニフェストで管理○ オンプレで利用されていたものをほぼコピー● 開発しやすい環境整備の視点で、改善した点○ Puppetのversionを2系から当時の最新の4系へ■ 2系は、web上でノウハウ探せない状態○ CircleCIでマニフェスト適用を試せるように■ 実際のサーバに依存したコードがあった為
やってみた結果新卒が権限追加依頼のPR投げる
やってみた結果EFS来た!使ってみようをアプリエンジニアから投げられる
まとめ(ECナビAWS移行)• 全体を見通して、一番不安な問題から検証した。不安を解消してから、具体的な移行作業に入った。• 達成したいゴールに対して、手段は今あるものを絶対とせず柔軟に選び直した。• AWSのリソース構築/変更、EC2のプロビジョニングに絞って、開発しやすい環境整備を実現させた。
旧管理系AWS移行時期 1999年頃〜2015年10月〜2016年6月2016年7月〜2017年11月2017年12月〜2018年4月2018年4月〜名称 カイゼン前カイゼン事始めECナビAWS移行旧管理系AWS移行カイゼン継続中環境 オンプレ オンプレオンプレ→AWS(大半)AWS(大半)→AWSAWS
旧管理系サーバー● バックオフィス向け。10-15年選手多し。○ 管理画面 (主にPHP、一部Perl CGI)○ バッチ (主にPerl、多種多様)● 新機能は「新」環境があるので、そちらで。
旧管理系サーバー● 位置付け○ 事業の大黒柱だが、枯れてる領域。○ 粛々と安定稼働させたい。機能改良は不要で、修正も歴史的に少ない。● 移行後の新サーバ名:antique
旧管理系サーバーの内部イメージ
アプリケーション問題点(1) 規模 × レガシーあるある問題
225管理画面のURL Path数問題点(1) 規模 × レガシーあるある問題
470バッチの数(crontab調べ)問題点(1) 規模 × レガシーあるある問題
レガシーあるある問題(※一部抜粋● ユニットテストが書かれていないコード多数● 継続的なテストが行われていないため、知らない間に動かなくなっている● 積み重なったパッチ的な対応の結果、膨れ上がったクラス● 同じような機能を持つライブラリ● Subversion の複数リポジトリが複雑に配置● サードパーティのコードがリポジトリに含まれている● crontab で華麗にスケジューリング、順序が重要!● 局所最適結果として乱立するフレームワークとその亜種。● アプリ間やアプリ-FW間の依存も強く、絶妙なバランスで動いている● 絶対パスによるファイルの参照● 実行環境に依存するパラメータのハードコーディング● 他とは異なる開発/デプロイフロー(本番サーバーでsvn up)● 学習コストが高くなり結果として属人化(※小さい問題は、他にも多数):
システム基盤問題点(2) システム基盤周りがメンテし辛い
古さの歴史的経緯● OS、言語バージョン、ミドルウェアが、単純に古すぎ。● 過去に数回サーバーリプレイスは実施したが、物理サーバの載せ替えに留まり、この点は改善は無し。○ 当時のリソース状況や事業状況により、問題点に対応しきるパワーが無かった。○ 社内システムという甘え
単にEC2に移行した場合に残る問題● アプリケーションやフレームワーク○ 数の多さ×レガシー満載○ 開発しにくい環境■ 膨れ上がった Subversion リポジトリ■ 本番環境に ssh ログイン & svn up● インフラ○ 「古い」ままのリスク○ 既にAWSで稼動中のシステムと異なる構成
移行時の改善ポイント● 開発しやすい環境整備○ Subversion から Git へ○ パッケージ管理ツール(Composer/Carton)の導入■ Subversionレポジトリにコミットされた、サードパーティのコードを移設○ Jenkins による自動デプロイ● 自由なインフラ○ マシンイメージをAWS上の既存システムと同一に 。
移行時の先送りポイント● 先送り○ アプリケーションをクラウドネイティブな構成へ■ 改善ポイントに関わる所を、必要最小限で対応するに留める○ ユニットテスト書いてカバレッジを上げる■ 時間が掛かりすぎるし、後からでもできる為
テスト方針● 1.新環境でユニットテストがパスする○ UTのカバレッジ低い。○ UTを増やすのは、時間が掛かりすぎる。● 2.本番に近い環境で、実際に動かして、アウトプットを照合する○ 課題:開発環境のデータは、本番環境とは程遠い
テスト環境への要求● 本番相当のデータを利用できる● データが壊れても元に戻る● 本番環境やユーザーに影響を与えない→ 自由なインフラを活用する
解説) テスト環境● 「ECナビAWS移行」で構築した、CFn + Puppet で作成。● AWS LambdaでCFnのChangeSetを作成し、日次でRDSスナップショットからリストア● 本番環境とはネットワーク上分離。メールサーバーは、送信を外向けにブロック● エラー通知はSlackに転送し、エラー状況を可視化
解説) テスト方法● バッチ1つずつ○ 1.テスト環境でテスト■ 結果が、現行本番環境とテスト環境で比較して同一であることで担保● 既存仕様で、メールでこと細かに実行結果が送られくるので、活用。○ 2.テストがクリアしたら、新本番環境へ移行。現行本番環境で停止。● 実際実施してみると、想定通りには、いかず。
バッチ一つ動かしてみると● ユニットテストが書かれていないコード多数● 継続的なテストが行われていないため、知らない間に動かなくなっている● 積み重なったパッチ的な対応の結果、膨れ上がったクラス● 同じような機能を持つライブラリ● Subversion の複数リポジトリが複雑に配置● サードパーティのコードがリポジトリに含まれている● crontab で華麗にスケジューリング、順序が重要!● 局所最適結果として乱立するフレームワークとその亜種● 絶対パスによるファイルの参照● 実行環境に依存するパラメータのハードコーディング● 他とは異なる開発/デプロイフロー(本番サーバーでsvn up)● 学習コストが高くなり結果として属人化:エラーおおすぎ
エラー要因● 先にあげたあるあるの課題が足かせになって、エラーが大量にでる。● 特にハードコーディングとかライブラリの問題とか根幹の部分のエラーが多く発生● 軌道修正しよう
テスト軌道修正(1)● エラー多発問題○ 個別で無く横断的に把握してまとめて潰す。■ 1.テスト環境で、全バッチをスケジュール通りに動作。■ 2.エラーを捕捉分析して、原因に対処。
テスト軌道修正(2)● 密結合・依存性問題○ 移行単位をバッチ単位で無く、似たものグループ単位にして、問題を軽減する。■ 任意のバッチグループと管理画面を分けて
軌道修正後の進捗● Slackエラー件数推移○ 2018/1/21 1982 件 ← 全実行スタート○ 2018/1/30 528 件 ← 潰し回る日々○ 2018/2/10 23 件 ← ほぼ問題無し● バッチは、まとまった単位で段階的に移行● 管理画面は運用者含め、みんなでE2Eテスト後、一気に移行
オンプレ卒業● 約4ヶ月で、470 バッチ、 225 画面の移行● 移行後のトラブルは、特に無し。安定稼働。
まとめ(旧管理系AWS移行)● レガシーの厄介な問題に対して、手書き図のように大雑把に捉えて把握し、要因に個別対処せずに解決する手段を考え出した。● システムに対する今後の期待を踏まえ、解決したい問題(自由なインフラと開発環境の整備)と先送る問題を切り分けた。● 取り組みながら見えてきた課題には、既存の実現手段に拘らず、手元の武器(AWS移行後の環境、バッチのメールなど)を組み合わせて、新しい手段(テスト環境)を作っていく。
振り返り
時期 1999年頃〜2015年10月〜2016年6月2016年7月〜2017年3月2017年4月〜2018年9月2018年10月〜名称 カイゼン前カイゼン事始めECナビAWS移行旧管理系AWS移行カイゼン継続中環境 オンプレ オンプレ オンプレ→AWS(大半) AWS(大半)→AWS AWSカイゼン実績● 全サービスのAWS移転、開発しやすい環境整備、アプリ・インフラ運用、葬り済みの機能
● 無理はしてない。○ 普通に。○ 長時間労働、要員追加、精神的ストレスは、特に。● でも、着実にレガシーから脱却しつつある。相当頑張った?
● 「レガシーシステムは、問題の”数”と”質”の2面の難しさがある。でも、一度に取り組む数を減らせば、攻略は、少しずつだが確実に進められるだろう」という認識があった。● だから、各個撃破という戦法を選択した。○ 問題の量と複雑さに苦しまないように切り分けて○ 1個ずつ各個撃破し○ コントロール可能な範囲を徐々に広げた。○ 以上を繰り返す。なぜ「無理せずカイゼンが進む」?
● 現状把握から始める○ レガシーシステムの事実をカイゼンの立脚点とする● いま取り組む事を絞る○ 効果x工数のコスパの良さで見極める● 建設的先送り○ 色々手を出す位なら、先送る。○ 周辺状況の変化により、あとの方が対応しやすくなることもある。各個撃破を実現する基本動作
レガシーとのいい感じの付き合い方各個撃破!● 現状把握から始める● いま取り組む事を絞る● 建設的先送りはじめは、問題を減らす & 解けるサイズに切り出すところから!ご清聴ありがとうございました