Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Microservices Architectureを超大規模プロジェクトでやってみた
Search
Yasuhiro Miyake
November 18, 2016
Programming
7
13k
Microservices Architectureを超大規模プロジェクトでやってみた
Yasuhiro Miyake
November 18, 2016
Tweet
Share
Other Decks in Programming
See All in Programming
Amazon Nova Reelの可能性
hideg
0
250
chibiccをCILに移植した結果 (NGK2025S版)
kekyo
PRO
0
190
カンファレンス動画鑑賞会のススメ / Osaka.swift #1
hironytic
0
200
定理証明プラットフォーム lapisla.net
abap34
1
640
バックエンドのためのアプリ内課金入門 (サブスク編)
qnighy
1
220
CNCF Project の作者が考えている OSS の運営
utam0k
5
600
動作確認やテストで漏れがちな観点3選
starfish719
5
760
さいきょうのレイヤードアーキテクチャについて考えてみた
yahiru
1
400
Amazon Bedrock Multi Agentsを試してきた
tm2
1
190
2025.01.17_Sansan × DMM.swift
riofujimon
2
640
ASP. NET CoreにおけるWebAPIの最新情報
tomokusaba
0
190
Fixstars高速化コンテスト2024準優勝解法
eijirou
0
200
Featured
See All Featured
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
The Invisible Side of Design
smashingmag
299
50k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
The Art of Programming - Codeland 2020
erikaheidi
53
13k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
Fashionably flexible responsive web design (full day workshop)
malarkey
406
66k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
28
4.5k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
52k
VelocityConf: Rendering Performance Case Studies
addyosmani
327
24k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
127
18k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
7k
Transcript
Microservices Architecture を 超大規模プロジェクトでやってみた - 一筋縄でいかない苦闘の一年間 - 株式会社ワークスアプリケーションズ 三宅 泰裕
Agenda • HUEの変遷 • Dependency戦国時代 • MSA黎明期 • MSAなう •
まとめ • Q & A
0. HUEって?
HUE • ふえ? – High Usability Enterprise application – 「ひゅー」と読みます
– 電球ではありません。。。 http://www.worksap.co.jp/hue/
HUEの特徴 • Cloud Native • 分散処理機構 – 膨大な量の帳票の集計の高速化 (一億明細とか) •
人工知能 – 学習に基づく、Input Less化 • 応答速度にコミット – 100msで応答するという挑戦
規模感 • 開発者 – 3000+ (日本、上海、シンガポール、インド) • CIチーム – 30名(日本、上海)
• 運用チーム – 15名(増員中) • 偉い人 – 一杯
今日、言いたいこと • MSAへの移行は難しい、けど出来る! – 技術的な難しさ • 言うても組み合わせ、実はそんなに新奇性はない – 精神的な難しさ •
「諦める事」への慣れ • 「仕様」という言葉の魔法感 – ノーガードになる • パラダイムシフトを許容出来ない – 目に見える範囲で「改善」を積み上げる Springそのものの話は、あんまり無いですね、今回...
1. HUEの変遷
プロジェクト開始当初 • Springエコシステムをある程度使う – 2年半ぐらい前の話 Spring MVC Spring JDBC Spring
Cache Abstraction Application Code Forneus (自作超高速レンダリングエンジン) Google Closure Library
え?なんでRDBMSつかってるの? • 大号令、「RDBMSから脱却!」 – 2年前ぐらい • Cassandraの導入が決定 • Sparkをバッチ処理にもってくる •
メイン処理からRDBMSは完全撤廃 Spring MVC Spring Cache Abstraction Application Code Forneus (自作超高速レンダリングエンジン) Google Closure Library KVA (C*ドライバ)
ねえ、バージョンアップしてみて? • 1年ちょっと前 – 状況 • 三週間あればバージョンアップ出来ます! これって。。。
Monolithic !!
苦闘の歴史の始まり • 巨大でモノリシックなモジュール – 膨大なソースコードをマージして1つに • ビルド時間 – ほぼ1日(14時間) •
環境構築の時間は含まれておらず、構成確認は出来ない • テストも流せない…… • 浪費癖 – .warを動かすには、32Gbyteのメモリが必要です!! • 進まない理解 – MSA、え?それって美味しいの??
正しく考えてみる:仮説 個別のサービス単位でバージョンアップする 他に影響は及ぼさず、高速にビルド・デプロイ サービスレベルでの依存の排除 WebAPIにのみ依存する開発スタイル ということは?
Micro Services Architecture !! • これなんじゃね?
HUEの制約 • 目的 – 100msでの応答速度を達成する – 統一感のある、UI・UX • 戦略 –
コンパイルの出来るJS • Closure Compiler → Google Closure Library – 一元配信出来るCSS • LESS – サーバサイドレンダリング • Forneus
HUEの要求(一部) • ビジネスドメイン単位で導入したい – 例:) お客様が購入されたライセンス単位で • 品質を担保したい – 100msでの応答速度
• フレキシブルなスケールアウト・スケールアップ – 理にかなった、UI / UX • 導入作業を軽減したい – ERPの導入作業は凄く大変… • 時間、リソース、複雑さ
2. Dependency戦国時代
事実を詳らかにしていく作業 • とりあえず孤軍奮闘 • まずは依存性の調査 – mvn dependency:tree – Dependency
Analyzer – JSレベルでも、deps.jsとかを眺めてみる
こうなった。。。
どうしよう。。。 • 選択肢は2つ – 新しいものは美しく – 既存のものはサヨウナラ • 分けると良さそうな気がする –
最早、管理できない単位なのは明白
レポジトリ分割闘争 • 分割するってことは – 管理する単位自体を変えるっていうこと • どっちがいいの? – 1レポジトリで全部やるか •
ツリーは1つ • レポジトリも1つ – 細かく分けていくか • ツリーは1つ • レポジトリはN個
1レポジトリ派 • Pros – インテグレーションレベルでの問題発見の早さ • 製品の弱点がすぐに分かる仕組みをつくりやすい • Cons –
Cloneの速度 • 単純な物量 – テスト時間 • ユニットテストすら工夫して流す必要 – ビルド・デプロイ時間 • Googleスタイル、彼らはビルドツール開発にも注力 – Bazel → https://bazel.build/
レポジトリ分割派 • Pros – cloneが速い – ビルドも早い – テストもしやすい •
Cons – インテグレーションレベルでの問題は発見しづらい • ここに対する処方箋は必要
HUEの戦略 • Jenkinsレベルでどんどんテストを組み込む – 1レポジトリに組み込まれるもの • Pre-merge build (Merge前にUnitTestは流す) •
Smoke Test (Dockerベースで起動確認だけする) • GitlabでのReview Board (シニアのLGTM必要) • 開発者を不用意に待たせない – 2000人を10時間も待たせられない… • インテグレーションレベルの問題 – 0から環境を毎日作ってそこでテスト • ビルドこけたら緊急出動! – Immutable Infrastructureを目指す
戦略が決まったので、実行 • 「意味ある単位」に分解 – 業務機能での何となくの塊(完璧でなくていい) – 共通機能と業務機能は絶対に別 • ここは理解が得られやすい FW
(全部入り) 認証 経費管理 残り イテレーション単位で狙いを定めて、分解していく
得られた知見 • 共通部分は以外と切り出せる – 機能的な重複は意外と少なかった – ソースはカオスでも一旦置いておける • Refactoringは独立宣言後でも大丈夫(優先度的に) –
切り出せたものは極小に • 32G → 650Mbyte • 業務アプリはやっぱりFWにべったり – やったところでスリムにならない – メモリ:32G → 24Gぐらい(激重) 要はやっぱり、「依存関係」
3. MSA黎明期
作戦を立て直す #1 • レポジトリを分割してしまえは正しい • メモリ圧迫の原因は、Beanの過剰生成も – 去年の発表参照 • 共通部分の分離が急務だが、影響範囲は莫大 –
可視化しないと、どうなっているか分からない • ドメインの分割も出来ていない – 実は、大きなレイヤでは分かれている、ERPだから • HR, AC, SCM • 要するに、ヒト・モノ・カネ
作戦を立て直す #2 • FWに入っているものにも何か混ざってる – 承認ワークフロー – Collaboration Features •
Spreadsheet, Timeline, Drive, Talk etc... • 製品を構成する要素としてはFWに見えるけど – 実は、サービスとして切りだされるもの • 例:) Spreadsheetは、Google SpreadsheetのERP版
Beanの生成は手動定義 • Auto Confguration的ではなく – Confgurationクラスに必要なものを自分で書く – 依存ツリーは自分で意識して、@Importする @GuardedConfiguration(ExampleConfig.class) @Import({CassandraConfig.class})
public class ExampleConfig { @Bean public Foo foo() { return new FooImpl(bar()); } @Bean public Bar bar() { return new BarImpl(); } @Bean @Autowired public Baz baz(KeyValueAccess kva) { return new BazImpl(kva); } } @GuardedConfigurationはご愛嬌
Gitレポジトリは分割する • FWと称して全てを内包していたので – どんどん分解 Timeline Approval Spreadsheet Framework
普通の景色に戻す(ように頑張る) • ApplicationとLibrary – Library: 内製のラッパや、ユーテリティ、共通機能 – Application: サービスそのもの •
Application間はWebAPIでやりとり Application A use Logging Encryption Spring Boot use use Application B Application C WebAPI WebAPI
ビルドの単位も切り離そう • ドメインが分割不可能なら – 大きな開発組織単位で • Stakeholderが減る – 開発のやることは増えるが、責任は明確に •
出来るだけ政治的混乱に開発は巻き込まない Framework Collaboration Human Resource Accounting I/F
デプロイは一括でしか出来ない • ドメインの分割は本質的な問題 – 下記の状態。双方に初期出荷データが必要になる • 理想解 – サービス間でデータの共有をしない •
検索Indexどうするの? • データの分割はとてつもなく難しい – 定義の曖昧さ、責任の曖昧さ • 例) 承認ワークフローって皆、使うけど誰のもの? • 歴史的問題 – 組織はMSAに都合良く組織されない F/W Accounting
得られた知見 • ここまでやると、そろそろ本質に気づいてくる – ドメインとは • 実は、売りたい単位? • 実は、バージョンアップしたい単位? •
実は、ライセンスの単位? – こんな議論が繰り広げられるようになる • で、更なる(現実めいた)オーダが飛んでくる
4. MSAなう
で、幾らかかるんだっけ? • メモリを大量に消費する作りで • インスタンス自体はバラバラになっていって – あまり、メモリ自体の削減効率は上がらず...... • ビルドは綺麗になったものの •
デプロイは1回のみ
None
コストをさげるんだー!! • インスタンスコスト – 利用時間あたり、どれぐらい稼働させ続けるのか? • HUEは、1インスタンス、1サービスだと無理がある • Kubernetes –
巨大インスタンス1つで、N個のPOD(サービス)という戦略が可能 • かつ、M/Wリソースは共有出来ないといけない – 各社毎にインスタンスを立てていくと、凄く高い • Multi-tenancyという選択肢 • Managed Serviceも活用しよう – AWS Lambdaとか • 100ms単位課金(使った分だけお金を払う)
余談ですけど、高いですよ!! • 冗長性 – だって、普通に落ちるからね – 昼間はN個、夜間はN/2個とかは必要です – Multi-AZとかMulti-Region考慮すると余計高い •
というわけで、下記は必須です – 出納大臣(もしくは、Billing API) – 性能大臣 (もしくは、負荷試験と綿密なCP) コストと性能はトレードオフ、しかし、妥協点は見出すべきです!!
じゃあ、こうしよう! (取組中) • APサーバも含めて、M/Wは、Multi-tenancy • Multi-regionも視野にいれる AP C* ES Kafka
Redis Managed Service AWS Lambda とか... VPC
War → Docker (取組中) • ライブラリの制約からの解放 – やっと、Spring Boot使える... •
Docker Fileを成果物にする – Buildまで開発チームで責任もってもらう
運用も委譲しちゃえ (取組中) • ビルド – 開発者がやるもの • デプロイ – Ansibleベースで環境構築スクリプトも書いてもらう
• Scaling Factorとか、非機能要件 – 負荷試験環境でCPして、決める – k8sベースなので、YAMLで決められる • モニタリング – 可視化ツールで頑張る • Prometheusとか使い出す
CIの役割は? • インテグレーションの専門部隊へ – Jenkinsで魔法かけない • Monolithicアプリは往々にして、魔法で出来ている • インテグレーションレベルでの問題解決を! –
MS単位でリグレッションテスト – MS間で結合テスト – データの適用テスト、SlowTest等 • 開発クオリティを担保する方向へ!! – ビルド屋さんからの卒業 • 開発ライフサイクルそのものを定義していく部隊へ
本番環境は? • もちろん、専門チームが必要 – コンプライアンスとかの問題 • Opsを担う人を育てねば。。。
5.まとめ
インフラ #1 • インフラドリブンでいこう! – 個々の開発者の理想はチグハグ • 正直な所、意志の統一はほとんど不可能に近いかも…… • これは揃えとけ...
– Jenkins的なビルドツール – Gitレポジトリ申請フロー – 依存性をチェックする機構 • マージ前、トピックブランチにpushした直後 • どんどん落とす:Failさせる • ビルドドメインを決めたら、そこもチェック対象に
インフラ #2 • 構成管理はしっかりと – 毎日、環境は作りなおす – 当然、スクリプトで管理するべき • Ansibleとかいい感じ
• 出来上がった環境もチェックに使う – 環境構築スクリプト時点でも問題は発覚する • CI的な役割をする人間もどんどん文句言う – 第三者的評価もする • 素朴な疑問に目を背けない – 「自分の評価対象だけ、最新に出来ないでしょうか??」
開発者 #1 • まずは、「依存」に目を向けてもらう – mvn dependency:tree, 自分たちの依存はしっかり分かっておく • 「依存」と闘うことに、嫌気がさしてきたら
– Dockerベースでのビルドまでを出来るように頑張る • 当たり前をちゃんとやる – ステートレス, ドメインをしっかり定義して、そこを逸脱しない • 何でもテスト出来るようにしておく – Dependencyチェック, 初期出荷スクリプトのチェック, 各種テスト • 一番大事なことは – 「覚悟」しろ! って言うこと • 「運用」とか言われると、始めは誰しも怖いものです
開発者 #2 • Web APIベースでの開発には... – 互換性維持は基本、出来ればForwardも • Unit test、Swagger、バージョンを組み込んだAPIデザイン
– 低レイテンシ • 非同期、バルク、キャッシュの有効利用 – 結合テストの効率化 • モック、SDKの提供 (Feign的な...) – 監視のためのWeb APIのトレーサビリティ • 相関ID (Sleuth的な...) – 可用性の確保 • サーキットブレーカパターン、インフラも含めて (Hystrix的な...)
組織 • 開発は出来るだけ、Agileで – 早く見つけて、早く修正 • レビュー機関の必要性 – 製品としてのコンセプトを判断できるチーム –
Architectureを判断できるチーム • インフラチームとがっつりタッグを組まないと、形骸化 する • APIのルール、デザイン • M/Wの使用方法 – 無駄なコストをかけない – デザイン(UI/UX)を判断できるチーム
苦闘の歴史は? • 巨大でモノリシックなモジュール → 6個に分割、Gitレポジトリはもっと細かく • ビルド時間 – ほぼ1日(14時間) →
5〜40分を「並列」で • 浪費癖 – Xmx:32Gbyte → Xmx:1-4Gbyte • ライ◦ップもびっくり • ちなみに、話者も20K減量(前年比) • 進まない理解 – 無理、無知 --> どうしたら分割できるだろう?
Any Questions?
We are hiring!!