Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TECHHILLS-テックヒルズ- 「SHOPLIST」の技術負債-長年構築されてきたレガシーシステムを脱却することで見えてきた未来-

CROOZ
November 24, 2021

TECHHILLS-テックヒルズ- 「SHOPLIST」の技術負債-長年構築されてきたレガシーシステムを脱却することで見えてきた未来-

2021年11月24日(水)に開催されたTECHHILLS(テックヒルズ)で発表した資料になります。

SHOPLISTがリリースされてから今日に至るまでの情報を載せています。

CROOZ

November 24, 2021
Tweet

More Decks by CROOZ

Other Decks in Technology

Transcript

  1. SHOPLIST.com by CROOZについて 2012年7月のサービス開始から9年間で年間売上約300億円規模に 1年目 2年目 3年目 4年目 5年目 6年目

    7年目 8年目 9年目 22億円 65億円 97億円 145億円 190億円 214億円 271億円 249億円 245億円 2012年 2013年 2014年 2015年 2016年 2017年 2018年 2019年 2020年 体制変更
  2. SHOPLISTのあゆみ SHOPLIST のあゆみ ~リリースまで 事業面の話 ・2012年7月にリリース ・当時はCROOZ blogという月間700万PVを記録する広告メディアを運営 しておりおり、ファッションECの広告案件が多くあったため自社でもEC 事業を行おうということになり、総合ECモール「CROOZMALL」を

    リリース。 ・モールへの集客をする中でファストファッションのPV数が高かったため ファストファッションに絞った「SHOPLIST.com by CROOZ」をリリース ・CROOZ MALLをはじめとする既存のサービスのソースコードを基に、 6カ月で開発を行った。
  3. 技術的に得たもの SHOPLISTのあゆみ SHOPLIST のあゆみ リリース~2015年 ・AWS上での各種サービスの構築運用ナレッジレッジ ・ElasticSearch, MapReduce, Cognite, RedShiftなどPaaSの運用ナレッジ

    ・TVCM放映にも耐えられるアプリケーションのチューニングナレッジ 積み残した技術的負債 ・動くけど可読性・保守性の低いソースコード ←当初比較で約25倍にw ・ドキュメント未整備(特に仕様に関する部分) ←同じくw ・エラーログ実装 ←同じくw +野生のコードたち(リポジトリ管理外のコード) +PHP5をはじめとするサポート切れのミドルウェア +未対処のPHPエラーログ
  4. SHOPLISTのあゆみ SHOPLIST のあゆみ 2016~2019年 技術面の話 ・開発人数も正社員40名+開発パートナー20名規模 ・並行開発&開発人員の増加に伴い、ソースの衝突が頻繁に発生するように… ・ドキュメントがない&可読性が悪い状況化での新規参画するメンバーが増えた ことで、弊害(ベロシティの低下、開発職種の平均勤続年数の低下)が出始める。 ・エラーが出たら直すとか、使わなくなったらサービス上から消すとか

    本来当たり前にすべきソースコード上の保守に手が回らなくなる。 ・サポート切れミドルウェア問題など、認知はしているが移行するための作業 時間と計画メンテナンス時間が確保できない状態に… ・一か所を直すと意図しないバグを踏む状況に… デバッグめちゃくちゃしんどい…
  5. 技術的に得たもの SHOPLISTのあゆみ SHOPLIST のあゆみ 2016~2019年 ………(;・∀・)ハッ? 積み残した技術的負債 ・動くけど可読性・保守性の低いソースコード ←当初比較で約40倍にw ・ドキュメント未整備(特に仕様に関する部分)

    ←同じくw ・エラーログ実装 ←同じくw ・野生のコードたち(リポジトリ管理外のコード) ・PHP5をはじめとするサポート切れのミドルウェア ・未対処のPHPエラーログ
  6. リニューアル (作り直す) vs リファクタリング(直す) 結論:リファクタリング(直す形)で進める。 理由: ・そりゃできればゼロベースで作り直したい! ・誰もが「作り直さなきゃダメっすね…」と言っていた ・けど、以下の視点で非現実的 1.仕様や要件が無く、リバースエンジニアリングで調べるだけで膨大な工数

    がかかる。 2.仮にゼロベースで作ったとして既存DB移行(データ移行)が限りなく困難。 3.人員のリソース的な問題で、サービス開発を行いながら並行して リニューアルを行うのが限りなく困難。 (全員総出で1年かけりゃできるけど、並行してサービス開発を続行不可) なので、実現味が最も堅いリファクタリングベースで進める選択肢を採用。
  7. インフラアーキテクチャに関する方針 なのでサポート切れミドルウェアのバージョンも行うが、それ以外にレガシーな 部分について、できる範囲でモダンな構成に変更していく形で進めることに 具体的には ・OSおよびミドルウェアのバージョンアップ CentOS6.4→Amazon Linux2 / Apache 2.2

    → 2.4 / Maria DB 10.0 → 10.5 / PHP 5.4→7.4 ・EC2 インスタンスの世代アップ + AMD インスタンス利用によるコスト削減 ・Multi-AZ対応 ・AnsibleによるAWS EC2インスタンスの自動構築(コードによるインスタンス構築) ・Amazon EC2 Auto ScalingによるWebサーバの動的スケーリング ・Fastly Image Optimizer を利用したサムネイル作成処理のマイクロサービス化 ・Fastly Image Optimizer を利用したWebP変換対応 ・rsync→GitLab CI/CDへのデプロイ方法変更 ・CloudWatch Log Agent を利用したアプリケーションログの一括収集 ・AWS Fargateによるサーバーレスでのサービス運用(新規サブシステムから適用)
  8. 参考:旧構成図(Web関連) 連携会社etc 出店ブランド様 CS委託会社 配送会社 広告会社 etc… エンドユーザ Route 53

    Web ALB Admin ELB WAF ACL Web / API 検索API Cashier用 Cart用 XXX用 XXX用 社内管理画面 社外管理画面 EC2 (Web) Main DB EC2 (mariaDB) Session 用 ElastiCache (Redis) Ranking 用 Data Cache 用 Mail Proxy ELB SHOPLIST DB LB ZETA ELB AWS Cloud 外部 検索エンジン Mail Proxy S3 bucket メール配信 エンジン
  9. 参考:旧構成図(バッチ・サムネ関連) 連携会社etc 出店ブランド様 CS委託会社 配送会社 広告会社 etc… Batch05-08 BQClient Main

    DB EC2 (mariaDB) Stock DB S3 bucket Google BigQuery S3 bucket 従業員 (分析) 店舗用 EC2 (vsftpd) その他用 S3 bucket Image Proxy ASG Nginx+ SmallLight ImageProxy ELB IDCF CDN Mail Proxy ELB SHOPLIST DB LB ZETA ELB AWS Cloud 外部 検索エンジン Mail Proxy メール配信 エンジン
  10. 参考:現行システム構成図(Web関連) 連携会社etc 出店ブランド様 CS委託会社 配送会社 広告会社 etc… エンドユーザ Route 53

    Web ALB Admin ELB WAF ACL Main DB EC2 (mariaDB) Sub DB Session 用 ElastiCache (Redis) Ranking 用 Data Cache 用 Mail Proxy ELB SHOPLIST DB LB ZETA ELB AWS Cloud ZETA 検索エンジン Mail Proxy S3 bucket メール配信 エンジン Web / API ASG EC2 検索 ASG EC2 Cachier ASG EC2 Cart ASG EC2 SuperShip ASG EC2 Deqwas ASG EC2 EC2(社内管理画面) EC2(社外管理画面) Stock DB
  11. 参考:現行構成図(バッチ・サムネ関連) 連携会社etc 出店ブランド様 CS委託会社 配送会社 広告会社 etc… Batch05-08 BQClient Main

    DB EC2 (mariaDB) Stock DB Mail Proxy ELB SHOPLIST DB LB ZETA ELB AWS Cloud ZETA 検索エンジン Mail Proxy S3 bucket メール配信 エンジン Google BigQuery S3 bucket 従業員 (分析) 店舗用 EC2 (vsftpd) その他用 S3 bucket Fastly CDN (Image Optimizer)
  12. 技術的負債への向き合い方 ~組織としてすべきこと~ 1.技術的負債があることによる問題を経営層に理解してもらう ・ソースコードがスパゲッティ状態・クソ・化石、エンジニアの精神衛生上よくないといった 会話だけでは経営層には伝わりづらい。 ・同じく、マイクロサービス化、CI/CD導入といった解決策としての技術要素の会話も同じ。 ・大事なのは、技術的負債となりうる事柄が放置されていることで、具体的にどのような 問題が発生しているかを経営層の関心事の視点で会話できる状態とすること 例)ソースコードがスパゲッティ状態だったことによって、先日入社した人がソースコードを 読んで仕様を理解するのに40時間かかっていた。結果、ソースコードの8割がデッドコードで

    あることが分かり、理屈上ソースコードがきれいな状態であったら40時間×2割 = 8時間で できるはずで、32時間が無駄になっている可能性が高い。 ・技術的負債によってどんな影響が出ているのかを正しく経営層に理解してもらうことは 極めて重要。なぜなら技術的負債を返していくに経営層の理解と協力が確実に必要だから。 具体的には ・技術的負債に向き合うためにはヒト・モノ・カネの経営資源の投入が必要。 ※片手間では絶対できないし、できてれば今の状況になってない ・場合によっては、サービス停止を伴うメンテナンスや施策のリリース時期の調整など、売上減少 を伴う可能性のあることを実施する可能性があるため。
  13. 1.いらないものを捨てる 技術的負債への向き合い方 ~リファクタの話~ 具体的には ・機能単位で廃止された機能一式 ・呼ばれていないプロパティ、メソッド類 ・呼ばれていない定数 ・呼び出されているけど絶対にその分岐状態に入らないプログラムのブロック ・ガラケー固有処理(解像度判定・ガラケー用画面テンプレート) ・使われていないけど残っているDBのテーブル

    ・意味をなしていないログ など 当たり前のことだけど、できてないことが結構多い。 いらないものが雑音となって本質的にリファクタリングしなければならない部分に手を入れる 際に、手間がかかってしまうため、いらないものをまずは捨てる。 手段的にはIDEの機能、SonarQube、PHPMDなどの静的解析ツールをCI/CDに組み込んで 状況を把握し、あとは泥臭く実行。
  14. 2.公開範囲を小さくする 技術的負債への向き合い方 ~リファクタの話~ 具体的には ・継承先でしか呼ばれないのであれば public → protected に ・そのクラス内でしか呼ばれないのであれば

    private に ・全体で使わない定数であればクラス内定数に など公開範囲を小さくする。 3.同じ処理、似た処理のロジックを共通化する 1と2が終わったタイミングで、ソースコードとしてはある程度負える状態となってくるの で、ここから本来すべきリファクタリングの第一歩として同じ処理、似た処理の共通化を行 っていく 手段的としてはIDEの機能、SonarQube、PHPMDなどの静的解析ツールも使うが、 アナログにソースを読んで理解していくことも重要。
  15. 1.品質メトリクスを可視化する 技術的負債への向き合い方 ~システム的に整備すること~ 具体的には ・エラーログ件数(Warning / Notice 含む) ・Lintエラー件数 ・ソースコード重複件数

    ・カバレッジ ・DBのテーブル数 など できることからまずは可視化。 見えないと現状も把握できないし、目標も立てれない。 まずは可視化!
  16. 2.仕組みとしてできるものは強制する 技術的負債への向き合い方 ~システム的に整備すること~ 具体的には ・Code Formatter ・Merge Requestによるレビュー依頼など など すべてを人的な手段で行おうとはせず、ツールやシステムなどで強制できるものは強制

    して無理やり統制する。 3.CI/CDとして整備し、運用まで落とし込む まず、品質メトリクス集計など、デプロイ都度もしくは日次で回せるものは自動で回せる 仕組みを作る。 会議体などで、品質メトリクスをエンジニア全員に見る場を設け、正常なのか異常なのかを 確認する習慣をつけさせる。
  17. 1.開発環境を既存のと新規で平行して稼働させ、出たエラーをつぶす 技術的負債への向き合い方 ~インフラ移行の話~ 開発者 push EC2 instance Web / Batch

    CentOS 6.4 PHP5.4 EC2 instance DB MariaDB 10.0 既存環境 EC2 instance Web / Batch Amazon Linux2 PHP7.4 EC2 instance DB MariaDB 10.5 新規環境 エラー発生 ひたすらエラー修正 ・廃止関数など、文献上わかるものは検索して代替関数に置き換え。 ・あとはエラーログを見ながら地道に直す。
  18. OSおよびミドルウェアリプレイスは約3カ月という超突貫で実施しました 技術的負債への向き合い方 ~インフラ移行の話~ 2021/07 2021/08 2021/09 2021/10 2021/11 2021/12 計画作成

    構築スクリプト生成 DBインスタンス切替 Web / バッチ切替 不要テーブル調査 第1回目 メンテ実施 第2回目 メンテ実施 本番検証 (1台のみ) 第3回目 メンテ実施 (DB切替) 開発環境検証 本番検証 本番検証 MEGA Sale中 本番切替完了 第4回目 メンテ実施 (Web/バッチ切替) 本番切替完了 約3カ月で実施
  19. 切替後に発覚した主な問題は… 技術的負債への向き合い方 ~インフラ移行の話~ ・リポジトリ管理外の野良コードが実はあって、移行が漏れたバッチがあった。 →リポジトリ内にソースコードを入れて再デプロイして解消。 ・MariaDBのSlave間で今まで設定パラメータが実は違っていて、移行の際に設定が漏れた。 →用途ごとパラメータを再定義した。 ・Multi-AZ化により、ゾーン跨ぎのSQL応答が遅くなり、バッチ実行速度が最大で2倍遅くなる ものがあった。 →設計時の考慮漏れ。実行元のバッチインスタンスとバッチの参照先のSlaveインスタンスの

    ゾーンを合わせることで解消。 ・MariaDBのバージョンアップに伴い、クエリ処理が詰まる問題。 デフォルトのトランザクション分離レベルが変更になっているなど、RDBMS内部の仕様変更 によりクエリの応答時間が遅くなり詰まる。(バッチのみで発生) →考慮漏れもあるものの、バッチ内で行っているTEMPORARY TABLEの作成方法がよろしくないので プログラム側の改修で対処。 ・実はバッチサーバ内にworkディレクトリを事前に作る必要があって、それが無かったことで バッチがコケた。 →考慮漏れ。構築スクリプトを修正。
  20. 1年間取り組んで変わったこと ~定量的な話~ 技術的負債返済に関する主な指標 2020年7月時点 2021年7月時点 総エラーログ件数 約365万件/日 約160万件/日 (約55%削減) 論理LOC

    約200万行 約170万行 (約15%削減) DBデータ容量/1インスタンス 約1.6TB 1.1TB (約30%削減) OSバージョン CentOS 6.4 (サポート期日:2020/11/30) Amazon Linux2 (サポート期日:2023/06/30) Apacheバージョン 2.2 (サポート期日:2017/12/31) 2.4 (サポート期日:未定) MariaDBバージョン 10.0 (サポート期日:2019/03/31) 10.5 (サポート期日:2025/06/24) PHPバージョン 5.4 (サポート期日:2015/09/14) 7.4 (サポート期日:2022/11/28)