はじめに
こんにちは、マイクロサービス基盤チーム所属のzigeninです。
この記事では、マイクロサービス化の取り組みについて紹介します。
技術的な取り組みやチームに興味を持っていただければと思います。
用語の定義
はじめに本文で使用する単語を定義させていただきます。
- コアドメイン:アンドパッドの事業に直結するドメイン
- 施工管理が該当します
- 施工管理は建設現場のマネジメントです。 ソフトウェア開発に例えるとプロジェクトマネジメントに近く、ツールとしてはJIRAやGitHub Projectをイメージしていただけると当たらずといえども遠からずです。
- 施工管理が該当します
- 汎用ドメイン:コアドメインを支援するドメイン
- 認証/認可など
- 施工管理などのコアドメインに付随する機能です。 認証/認可などがこれに当たります。
- 認証/認可など
取り組みの背景
マイクロサービス化の目的
現在、アンドパッドのサービスの大部分は、Ruby on Rails製のモノリスで実現されています。 去年頃から、このモノリスをマイクロサービスに分割したり、新規サービスをマイクロサービスとして開発する取り組みを行っています。
なぜ、マイクロサービス化を進めているのか?
それは、品質を保ちつつ、お客さまにより早く価値を届けたいからです。
- デプロイ頻度を増やす
- リードタイムを減らす
- 障害率を低く抑える
- 障害の復旧時間を短くする
マイクロサービス化により上記を実現し、目的達成に近づけるものと考えています。
モノリスのつらさ
まず、アンドパッドのモノリスの概略図を示します*1。
最初のうちは少数のドメインしかなかったのでモノリスでも問題はありませんでした。 事業の成長に伴いドメインが増え、ドメインを実装するコード間の依存関係も混沌としています。 このような状態により、検査に閉じた変更をしたつもりが、思いがけず施工管理の動作にも影響が出てしまってしまったこともあります。
検査と施工管理は、別々のチームが開発を担当していますが、 検査チームの開発者でも施工管理の実装の詳細を把握しておかないと、こういった事態を防ぐことは難しいです。しかし、担当外の領域の調査には時間がかかりますし、担当外の領域を完全に把握することも困難です。 調査、仕様把握に時間を咲くことに寄って開発速度は落ちますし、品質にも常に不安が残ります。
ふたたびマイクロサービス化の目的
さて、上述したパターンの事態を回避するにはどうすれば良いか?
解の1つは、以下の図に示したようなドメインごとにサービスを分割して、依存関係の方向を明確にすることです。つまり、マイクロサービス化です。
各サービスの開発者は、自サービスと依存先サービスのAPIだけを把握していれば良いことになります。把握すべき仕様、情報量が減るとともに、自サービスの変更が依存先サービスに悪影響を与える可能性も格段に減ります。 この状態なら、各サービスの開発者は、他サービスの詳細を調査する必要もありませんし、安心して開発を進められます。結果として、開発速度も上がり、品質も上がると考えています。
なお、記載したドメイン図は、説明用に作成したものであり正確に実態を示したものではありません。その点、ご留意願います。
マイクロサービスとは
マイクロサービスの定義は人によって異なることもあります。たとえば、2週間で開発完了する規模がマイクロサービスと定義する方もいます。
下記はマイクロサービスの定義をとある記事から引用したものです。 我々のチームではこの定義をベースとしています。
- 単一の目的
- 一つのことに集中しておりそれをうまくやること
- 疎結合
- サービス間の依存関係が少ないこと
- 互いに内部の詳細を知る必要もなく、どこかのサービスの変更により他のサービスの変更が発生することが少ないこと
- 高凝集
- それぞれのサービスが関連する振る舞いやデータをカプセル化していること
- データがある機能を作るときに、少ない数の変更で済むこと。理想は1つのサービスだけの変更で済むこと
採用技術について
技術スタック
- インフラ
- クラウドプロパイダ:AWS。一部GCP
- コンテナ:Docker Image + AWS ECR
- デプロイ基盤:kubernetess(EKS)。一部Lambda
- サービスメッシュ:Linkerd
- 監視:Datadog、Sentry
- CI/CD:Circle CI。一部AWS Code Build/Github Actions。CI Ops
- メッセージング:AWS SNS + SQS
- サーバ
- 言語:Go*2
- フロントエンドAPI:gRPC-Web/GraphQL
- フロントエンドAPIのFramework:Echo、go-chi、素のnet/http
- バックエンドAPI:gRPC
- バックエンドのFramework:なし
- データベース:AWS RDS(MySQL)、一部Dynamo DBやFirestore
サービス構成
Web フロント - BFF - バックエンドサーバの3段構成が一般的です(下図)。BFFはBackends for Frontendの略で、APIクライアントごとに用意されるサーバのことです。BFFは、様々なマイクロサービスのレスポンスを結合してAPIクライアントに返す役割を持ちます。
Web フロントはamplify、BFFとバックエンドサービスはEKSを使ってデプロイしています。Web フロントにBlue/Greenデプロイをしたい場合は、amplifyでなく、EKSでWebページのホストサーバーをデプロイします。
現状の課題
基盤チームとして、今後取り組んでいきたい課題を紹介します。
技術面
- 単純なメッセージングに加えて、結果整合性を保つ仕組みの実装
- チーム内にオートスケーリング設定のノウハウを蓄積する
- ロギングなどのドメインに依存しない技術基盤の仕組みを整える
- 開発者に、本番環境への強めの操作権限を与えないといけない状態
- サービス立ち上げ時に必要な作業の自動化比率を向上し手動作業を削減
最後に
ここまで読んでいただき、ありがとうございました! 次回、基盤チームの活動や組織を紹介します!
この記事でアンドパッドの基盤チームのことを知ってもらえたら幸いです。
アンドパッドの基盤チームではメンバーを募集中です。サービスを一ヶ月で立ち上げるような環境を作りたい、Go言語でサービスを開発しつつ1人で閉じない活動をしたい、もつれあったドメイン間の依存関係を整えたい、というような方は楽しめると思います。
なお、基盤チーム以外のチームのメンバーも募集中です。