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
EMになってからチームの成果を最大化するために取り組んだこと/ Maximize team performance as EM
nashiusagi
0
100
Less waste, more joy, and a lot more green: How Quarkus makes Java better
hollycummins
0
100
リアーキテクチャxDDD 1年間の取り組みと進化
hsawaji
1
220
Kaigi on Rails 2024 〜運営の裏側〜
krpk1900
1
250
エンジニアとして関わる要件と仕様(公開用)
murabayashi
0
300
ローコードSaaSのUXを向上させるためのTypeScript
taro28
1
630
色々なIaCツールを実際に触って比較してみる
iriikeita
0
330
Click-free releases & the making of a CLI app
oheyadam
2
120
レガシーシステムにどう立ち向かうか 複雑さと理想と現実/vs-legacy
suzukihoge
14
2.3k
Tauriでネイティブアプリを作りたい
tsucchinoko
0
370
Hotwire or React? ~アフタートーク・本編に含めなかった話~ / Hotwire or React? after talk
harunatsujita
1
120
광고 소재 심사 과정에 AI를 도입하여 광고 서비스 생산성 향상시키기
kakao
PRO
0
170
Featured
See All Featured
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
42
9.2k
Bash Introduction
62gerente
608
210k
Why You Should Never Use an ORM
jnunemaker
PRO
54
9.1k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.2k
The Cost Of JavaScript in 2023
addyosmani
45
6.8k
Raft: Consensus for Rubyists
vanstee
136
6.6k
Designing on Purpose - Digital PM Summit 2013
jponch
115
7k
It's Worth the Effort
3n
183
27k
Unsuck your backbone
ammeep
668
57k
Why Our Code Smells
bkeepers
PRO
334
57k
4 Signs Your Business is Dying
shpigford
180
21k
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!!