2017spring jjug ccc_f2
TRANSCRIPT
#ccc_f2
エンプラ開発におけるレガシーアプリケーションの
巻き取りとモジュール分割の戦い2017/5/20
和田 一洋
#ccc_f2自己紹介
和田 一洋(わだ かずひろ)
• グロースエクスパートナーズ(株)所属
• 大手SIerで6年間勤務ののち2015年にGxP入社
• http://qiita.com/khwada
1
#ccc_f2紹介するプロジェクト
• 金融系のコンシューマー向けWeb会員サイト(会員数:約60万)の受託開発
• 10名強のチームで開発
• 顧客情報システム部門と開発チームを支援する業務に従事
顧客情報システム部門
弊社開発チーム10名強
要件や方式の取りまとめ支援
設計や開発改善の支援
2
#ccc_f2今日の話(変化のスイッチ)
• 以前の自分• 勉強会に参加したり、技術書を読んでも、日々の開発にどう生かせるのか、どうしたら近づいていけるのか分からなかった
• エンタープライズ開発のあるある?
• つまり「変化のスイッチ」が分からなかった• 「こうあるべき」「こうなるべき」は分かっても・・・
• 「何をまず変えれば変化の歯車が回りだすのか」「現実的にどうすれば変わるのか」が分からない※ http://d.hatena.ne.jp/Chikirin/20090210
3
#ccc_f2今日の話
• 参画から2年間の取り組みを4つのフェーズに分けてご紹介(だいたい半年ずつ)
• 各フェーズで取り組んだことと、その「変化のスイッチ」について
参画開発モダン化
巻き取り段階的な再構築
いまココ!
モジュール分割OAuth2 Provider
ふりかえりブランチ運用
CI/CD
build pipelineAPI化
モジュール再分割
4
#ccc_f2
参画期
5
参画開発モダン化
巻き取り段階的な再構築
モジュール分割OAuth2 Provider
build pipelineAPI化
モジュール再分割ふりかえりブランチ運用
CI/CD
#ccc_f2参画のきっかけ
• 既存のベンダーさんが大規模案件に追われる中、「規模は小さいがスピード感が求められる」開発を進めるために参画。
• システムの中身はほとんど知らない状態。
• レガシーフレームワーク(Struts1系ベースの独自フレームワーク)上での開発、ソースの変更履歴をコメントアウトですべて保持、そして、ベンダーをまたがったソースコードマージ・・・
⇒モジュール分割
6
#ccc_f2モジュール分割
war
レガシーフレームワーク
アプリ1
WebLogic
DB
Apache
7
#ccc_f2
war
モジュール分割
• SpringMVCベースの新規アプリを作成
• 2つのwarをearに同梱してデプロイ
レガシーフレームワーク
アプリ1
war
Spring
アプリ2
ear
WebLogic
DB
Apache
session
war
レガシーフレームワーク
アプリ1
WebLogic
DB
Apache
8
/aaa /bbb
#ccc_f2モジュール分割
• 役割分担• アプリ1:引き続き既存ベンダーが担当
• アプリ2:GxPが担当
• 制約• インフラ部門との調整にかける時間がなかったため、モジュールをear同梱することでインフラ影響を最小化
• DBは共有、HttpSessionも共有
9
#ccc_f2モジュール分割
• 残った課題(後述)• アプリ2で「メニュー」を表示できない
• 各機能の認可判定が仕様/実装ともに複雑で、認可判定ロジック(メニュー生成ロジック)は簡単には呼び出しや移植ができなかった
10
各機能
コンシューマー
各機能
認可判定ロジック
アプリ1
アプリ2
#ccc_f2モジュール分割の効果
• 提携サービスとの連携をはじめるにあたり、OAuth2連携を導入
• Spring Security OAuth2を利用して、アプリ2上にOAuth2 Provider機能を開発
⇒レストランやホテルの予約サイトなど、様々な提携サービスに「XXXXXでログイン」がついた
⇒レガシーフレームワーク上では難しい機能を実現し、モジュール分割の効果を示すことができた
11
#ccc_f2変化のスイッチ
• レガシーフレームワーク上での開発はしたくない、従来の開発文化を引き継いではいけない、という想い
• やや強引に「モジュール分割する」と決めて、顧客を説得し、ジャンプをした
• 課題も出たが、次につながる結果を出せた
12
#ccc_f2
開発モダン化期
13
参画開発モダン化
巻き取り段階的な再構築
モジュール分割OAuth2 Provider
build pipelineAPI化
モジュール再分割ふりかえりブランチ運用
CI/CD
#ccc_f2ふりかえり
• 開発が軌道に乗ったタイミングから、定期的なふりかえりを開始
• 隔週(目標)でKPTを実施• 若手を含めたチーム全員が、日常の作業からいったん離れて、プロジェクトについて考え、意見を発信する場(付箋を利用した個人ワークを挟む)
• 現在では、開発チームが10名強に増えたため、毎回2チームに分けて、それぞれテーマを決めて実施
14
#ccc_f2ふりかえり
• KPT
15
Keep
よかったので続けたいこと
Problem
Try
次にやってみること
問題点
#ccc_f2
16
ふりかえり前回までのTry進捗状況の確認 全体 10分
Keep/Problem出し 個人 5分
Keep/Problemをチーム内共有 チーム 10分
Try出し 個人 5分
Tryをチーム内共有 チーム 10分
全体共有 全体 10分
Actionの選定 全体 10分
・挙がったTryからタスク化するものを選ぶ・残っている過去のTryも含めて優先度が高い10個程度のタスクに対して、ToDoラベルをつけて担当者を割り当て
#ccc_f2補足:Atlassianツール
17
Wiki/情報共有他の例)・Redmine・Qiita:Team
Issue Tracking System他の例)・Redmine・Backlog・GitHub issues
Gitリポジトリ他の例)・GitHub・GitLab
継続的インテグレーション(CI)他の例)・Jenkins・Travis CI・Circle CI
#ccc_f2ブランチ運用
• 課題• masterへのマージタイミングをはっきり決めていなかった• 社内テスト環境にリリースするとき?
• 顧客の環境にリリースするとき?
• 本番リリースするとき?
• 並行開発時のブランチ運用ルールが曖昧で、ブランチがぐちゃぐちゃになりかけていた
⇒Git-flowをベースとしたブランチ運用を導入
18
#ccc_f2ブランチ運用
master
develop
feature/YY案件親
feature/作業1
feature/作業2
feature/保守XX
hotfixPR
本番リリース
PR PR
PR
本番リリース
本番リリース
案件親ブランチ、または、developへのマージ時に、PR(ソースコードレビュー)
masterへは「本番」リリース時にマージ(本番リリース履歴を残す)
運用上 featureブランチに親子関係を持たせる(案件親ブランチ⇔各タスクのブランチ)
19
#ccc_f2ブランチ運用
• 新たな課題• 顧客側でのテスト期間が長く、なかなか
developをmasterへマージできない
• その間、次の開発を「案件親ブランチ」で運用するが、並行開発案件が多くなると「開発親ブランチ」の数が多くなり、リリース順も分かりづらい
⇒バージョン番号を導入
20
#ccc_f2ブランチ運用
• バージョン番号• リリース順に採番
• バージョン番号ごとのdevelopブランチを作成
• 採番ルール• メジャーバージョン:一定規模以上の案件
• マイナーバージョン:定期保守リリースなど
• リビジョン:緊急リリース
• 間に案件が入った場合、マイナーバージョンで間に挟み、一度決めたバージョンは変更しない
9.1.1メジャー
マイナーリビジョン
21
#ccc_f2ブランチ運用
master
develop/v10.0.0
feature/YY案件親
feature/作業1
feature/作業2
develop/v9.1.0
feature/保守XX
hotfix
v9.0.0 v9.0.1
feature/保守ZZ
v9.1.0 v10.0.0
22
#ccc_f2CI/CD(テスト自動化)
• ふりかえりでも、テストコードを書いてテスト自動化に取り組みたいという意見が多かった
• 一方、Excelにスクリーンショットを貼る形式でのテスト結果エビデンスの納品が必要
⇒テスト観点を整理
23
#ccc_f2CI/CD(テスト自動化)
• エビデンス納品対象のテストを「結合テスト」と定義• 単体テストは原則JUnit化
JUnitでテストしづらいところは、手動(打鍵)でテスト
• 結合テストは打鍵してExcelにスクリーンショットを貼りつけ、整形してエビデンスとするただしSelenide(Seleniumラッパー)を利用して、ブラウザオートメーションによる打鍵補助を導入
24
#ccc_f2CI/CD(テスト自動化)
テストフェーズ テスト観点 実施&レビュー方法
単体 validationや業務ロジックのパターン網羅/境界値テストAPI呼び出しの正常系/異常系
JUnit(DB読み書きや他システムAPIはモック)テストコードレビュー
画面単体 画面レイアウト/文言正常系/異常系メッセージの表示位置JavaScriptの挙動
打鍵Excelでのテストエビデンスのレビュー
結合 画面遷移会員やデータのパターンデータの登録更新パターンモジュール間を結合したシナリオ
打鍵(Selenideによる打鍵補助)Excelでのテスト設計/テスト結果のレビュー
25
#ccc_f2CI/CD(テスト自動化)
• レビューアに優しいテストコード 例)validation
• 画面入力1項目ごとにグルーピングして階層化@RunWith(Enclosed.class)
• テストメソッド名は日本語に
26
#ccc_f2CI/CD(テスト自動化)
• 次のステップ• 外部仕様に対するテストコード
• 実装ロジックをなぞるテストコードは、プロダクトコードを直すときは必ずテストコードを触ることになる
• 改修時のデグレ防止、実装後のリファクタリングの自由度を上げられるテストコードに
• E2Eテストの自動化• selenideの資産を活用
• 主要なシナリオに限って回帰テストを定期自動実行
27
#ccc_f2CI/CD(テスト環境デプロイ)
成果物
成果物
ソースコード
WebLogicコンソール
デプロイ
成果物
push
テスト環境
pull
当初、ローカルでbuild、デプロイは手作業で実施
28
#ccc_f2CI/CD(テスト環境デプロイ)
• 課題• デプロイの手作業が煩雑
• 並行開発が増え、テスト環境が増えるとさらに煩雑
• テスト環境にデプロイしようとしてbuildするまで、JUnitテストをまとめて実行するタイミングがない
⇒Bambooを導入
29
#ccc_f2CI/CD(テスト環境デプロイ)
成果物
ソースコード
デプロイ
push
v9.0.0
テスト環境1
v9.0.1
テスト環境2
v9.1.0
テスト環境3
v9.2.0
テスト環境4
Trigger
pushをtriggerにbuildが走り、JUnitが落ちるとメール通知
デプロイの開始/終了を通知
30
#ccc_f2CI/CD(テスト環境デプロイ)
31
各環境にデプロイされているブランチを画面上で一覧参照
環境を選んで、build対象の/build番号を指定してデプロイ
#ccc_f2変化のスイッチ
• ふりかえりを起点に、手の届く範囲から地道な改善を積み重ねた• 参画期に、スピードを優先して進めた部分を見直して足場固め
• 自分たちでプロジェクトを改善できるという実感を得た
• 「自動化」という当たり前のことも、取り組んでいくと、教科書的な話だけでない次の課題やステップが見えてくる = チームの成長
32
#ccc_f2
巻き取り期
33
参画開発モダン化
巻き取り段階的な再構築
モジュール分割OAuth2 Provider
build pipelineAPI化
モジュール再分割ふりかえりブランチ運用
CI/CD
#ccc_f2巻き取り
• 参画から1年が経過したころ
• 諸般の事情により、レガシーフレームワーク上の「アプリ1」の保守開発も巻き取ることに
34
#ccc_f2巻き取り
• 課題:「アプリ1」のビルド方法・・・• 本番のwarを解凍し、リリース対象のclassファイルを入れ替えて、圧縮しなおすことでwarを作成して、リリースしていた
• テスト環境/本番環境の環境差異はコメントアウトで切替
• リリース時のミスも頻発・・・
⇒巻き取りに際してビルド改善の工数を確保していただいた
35
#ccc_f2build pipeline
• 「アプリ1」をgradleでビルドできるように• 環境ごとの差異は設定ファイルに追い出して、設定値でふるまいを変えるように改修
• ソースコードとビルド成果物を1:1に
• 地道に検証• gradleでbuildしたwarの中身を逆コンパイル
• 本番環境のwarの中身を逆コンパイル
⇒diffを取り、意図しない差異がないかを検証
36
#ccc_f2build pipeline
アプリ1push アプリ1trigger
war
アプリ2
trigger
build
push trigger
deploy
アプリ2
ear
37
#ccc_f2API化
• 「アプリ1」を巻き取ったことで、全体最適の視点で機能配置を考えられるように
• 2つのアプリの疎結合化に着手
• アプリ間連携をRest API化• HttpSession経由での新たな共有はしない
38
#ccc_f2API化
• 参画期の残課題だった「認可判定ロジック」を移植してAPI化
• 「アプリ2」でもメニューを表示できるように
各機能
コンシューマー
各機能
認可判定API
認可判定ロジック
移植
アプリ1
アプリ2
39
#ccc_f2変化のスイッチ
• 開発モダン化期で自動化をしていたからこそ、その流れに乗せることを前提にできた• 継続開発で顧客との築いてきた信頼関係が前提
• 各活動の意義を理解していただき、各案件や保守の中で少しずつ工数を使わせていただいた
• 「アプリ1」に手を出せるようになったことにより、部分最適から全体最適へ視点が変わった
40
#ccc_f2
段階的な再構築期
41
参画開発モダン化
巻き取り段階的な再構築
モジュール分割OAuth2 Provider
build pipelineAPI化
モジュール再分割ふりかえりブランチ運用
CI/CD
#ccc_f2段階的な再構築
• 顧客内でレガシーフレームワークの撤廃が求められるように
• 合わせて画面リニューアル、スマホ最適化方式の見直しなどを進めたい
• ただし、移植中の案件凍結はなるべく避けたい
⇒各開発案件内で、改修対象機能を「アプリ2」に移植していく方針に(段階的な再構築)
42
#ccc_f2段階的な再構築
機能1
機能2
機能3
…
機能4
機能5
機能1
機能2
機能3
…
アプリ1 アプリ1 アプリ2
機能4
機能5
アプリ2
機能1
機能2
機能3
…
もともと 現在 移植完了後…?
43
レガシーフレームワーク
レガシーフレームワーク Spring Spring
#ccc_f2モジュール再分割
• これでは、新しく、別のモノリシックなアプリケーションを作っているだけ・・・
• とはいえ、分割すればよい、というものでもない
⇒改めて、「このプロジェクトにおけるモジュール分割の意味」を考えた
44
#ccc_f2モジュール再分割
• 当初は「ベンダー」切り口でのモジュール分割• ベンダーをまたがったソースコードマージを避ける
• 1社体制になった今のモジュール分割• 複数案件並行開発時のマージを最小化
• 改修時の影響調査/リグレッションテスト範囲を局所化
• (将来的に)モジュールごとに非機能要件を分ける
45
#ccc_f2モジュール再分割
• 新規アプリへの切り出し• CRUD対象テーブルが比較的独立しており、同時に改修が入るケースが多い機能群
• 方式• 引き続きearに同梱(インフラの見直しは、
H/W保守切れのタイミングまで待つ)
• メモリ上でのHttpSession共有はしない(疎結合化)
• Oracle DBへのconnection数の増大を防ぐために、weblogicのconnection pool管理を利用
46
#ccc_f2モジュール再分割
アプリ1
レガシーフレームワーク
アプリ2
認可判定
Spring
各機能 各機能
アプリ3
Session管理
Spring
各機能
Session管理
Session管理
Session管理(DB)
コンシューマー
cookie
47
再分割後
#ccc_f2
…
サービス
モジュール再分割
アプリ1
レガシーフレームワーク
アプリ2
認可判定
Spring
各機能 各機能
アプリ3
Session管理
Spring
各機能
Session管理(DB)
コンシューマー
cookie
将来像(仮)
48
Spring
各機能
#ccc_f2変化のスイッチ
• 「一括再構築」はリスクも高く、案件凍結が必要になるため避けたい。⇒これまでの実績から「段階的に進める」という提案ができた⇒再構築の効果も、早期から段階的に得られる
• 「マイクロサービスアーキテクチャ」という世のトレンドを、自分たちのプロジェクトに引きつけてどうしていくべきか考えた
49
#ccc_f2
まとめ
50
#ccc_f2まとめ
51
参画期
強い思いでジャンプ⇒モジュール分割
開発モダン化期
ふりかえりを起点に地道な改善・デファクトに乗る・ブランチ管理・自動化⇒次のジャンプの土台
巻き取り期
自動化を土台にして新たなジャンプ⇒全体最適への視点の変化
段階的な再構築期
「段階的」に進める⇒世の中のトレンドを自分たちのプロジェクトにひきつけて「アプリ分割」
外発的 内発的
#ccc_f2まとめ
• 内発的なスイッチ• ふりかえりを起点に、手の届く範囲から改善
• 自分たちでプロジェクトを改善できる、という実感を得る
• 取り組んでいくと、教科書的な話だけでなく、次の課題やステップが見えてくる = チームの成長
• 外発的なスイッチ• 世の中のアーキテクチャ/技術トレンドの変化、新しいツールの普及(「当たり前」が変わっていく)
• やや(?)無茶な要件やスケジュールを真剣に考えてみる機会が、ブレークスルーを生むことも
52
#ccc_f2まとめ
• 内発的なスイッチ• 自分たちでコントロールできる
• 外発的なスイッチ• 自分たちでコントロールできない
• ただし、チームがちゃんと準備をしていれば、チャンスが訪れたときに掴むことができる
• 準備 = 社内外の勉強会などを通して世の中のトレンドを知る。知るだけでなく、触ってみて、自分たちのプロジェクトに引きつけて考える。
53
#ccc_f2
54
ありがとうございました。