プロダクションレディマイクロサービスを読んだ

プロダクションレディマイクロサービスを読んだ

今まで、マイクロサービスと口にはしていたものの、その概念を理解しきれていないと思ったのでこの本を読みました。 予想通り読み終えた後はだいぶマイクロサービスについての理解が進みました。 本編はおよそ160ページとページ数も少なくすぐ読めるのでおすすめです。

概要

この本のタイトルの一部でもある、プロダクションレディとは直訳すると「本番対応」という意味だそうです。 この本は本番対応のマイクロサービスとはどのようなものであるべきかといったことについて述べられています。

なぜマイクロサービスなのか

本の冒頭ではマイクロサービスとは何か、なぜマイクロサービスで作るのかということが書かれています。 個人的にはこの序盤の部分がかなり勉強になりました。

モノリスなアプリケーションの問題

モノリスなアプリケーションの問題は大きく分けると以下の2つです。

デプロイスピードが遅くなる

モノリスなシステムは、コード量が増えていくほど複雑になっていきます。 複雑なシステムに変更やバグの修正をしたときに、その変更箇所がどこに影響するのかを把握するが極めて難しくなります。 自分ではこの箇所にしか影響がないと思い、その部分だけテストしてデプロイをしてみると、 想定していないところにまで影響があり、バグを引き起こしてしまうということもあります。

逆に、影響箇所を徹底的に潰すために、テストを重厚に行おうとするとシステムが複雑すぎて、 テストケースが無限に増え、リリースまでの時間がかかりすぎてしまいます。

タスクの処理スピードの向上が難しい

ある程度アプリケーションが大きくなってくると、1つのリクエストに対してのタスク数は多くなっていきます。 そのタスクを同期的に行なっていると、レスポンスまでにかかる時間も当然長くなります。 場合によってはサーバー側の遅延が大きすぎて、アプリケーションが実用的ではなくなってしまうこともあります。 モノリスなサービスはタスクの処理時間がかかりすぎてしまうという問題に対して、サーバーのスケールアップという対策しか できないのです。(スケールアップとはサーバーのハードウェアのスペックをあげることです。)

マイクロサービスとは

モノリスのアプリケーションを独立したタスクで分割したものがマイクロサービスです。 各サービスが協調して、動作します。

レイヤードアーキテクチャが、ソースコードをクラスの役割によって分割し、モジュール間の独立性を高めるように、 マイクロサービスはタスクごとにサービスとして分割し、サービス間の独立性を高めたものです。 マイクロサービスの1サービスは他のサービスのことを知る必要はなく、自分に与えられたタスクを淡々とこなすだけです。

マイクロサービスに分割することでモノリスなアプリケーションの課題であった、

という問題に対して、対応できるようになります。

デプロイスピード

マイクロサービスの1サービスは独立しているため、マイクロサービスの他のサービスについて考える必要はありません。 マイクロサービスの1サービスで変更があった場合、サービスの中で、動作の確保だけをすればいいため、 重厚なテストケースをこなす必要もありません。(テストしなくてはいいということではなく、必要なテストはもちろん行います。) 自分のサービスのことだけを考えて、デプロイが可能であるため、デプロイスピードは向上します。 また、各サービスのデプロイスピードが向上することによって、サービス全体はよりユーザーにとって価値のあるものになります。

並行性

マイクロサービスはタスクごとに分割されているため、並行に処理することも可能になります。 あるサービスAにリクエストを行い、サービスBにリクエストを行う、ということを並行に行えば、サービス全体のタスクの処理時間は短縮することができます。 実際、多くの企業でタスクを並行に処理する方法として、Pub/Sub戦略がよく行われています。 もし、1サービスに対してタスクが発行され過ぎ、処理が滞ってしまうのであれば、サービスをスケールアウトすれば良いのです。(スケールアウトとは同様のサービスを提供するサーバーの数を増やすことです。) もちろん、スケールアップもモノリスなアプリケーション同様に可能です。

マイクロサービスにすることの難しさ

マイクロサービスにはメリットもありますが、 各サービスがスケールアウトして、分散アプリケーションになることにアーキテクチャが複雑になります。

マイクロサービスは4つのレイヤーから構成されると、本書では述べられていました。

インフラストラクチャーレイヤー

インフラストラクチャーレイヤーとは主にハードウェアを管理するレイヤーです。 アプリケーションをスケールアウトするには当然、サーバーの管理が必要です。 現在はインフラをクラウドを用いて、インフラストラクチャーを構成することが多いです。 インフラレイヤーの役割は以下の4つです。

通信レイヤー

通信レイヤーはサービス間の通信を問題なく、行えるように管理するレイヤーです。 1サービスはスケールアウトによって、分散されているため、ロードバランシングやサービスディスカバリが必要不可欠です。 DNSによる名前解決もこのレイヤーで管理されます。 通信に必要なTLSの管理もこのレイヤーで行われます。

アプリケーションプラットフォームレイヤー

このレイヤーはアプリケーションのCI、CDの管理、アプリケーションのロギング、メトリクスの監視を行うレイヤーです。 うまく、アプリケーションが動作することを補助するような役割です。

マイクロサービスレイヤー

言わずもがな、アプリケーションに関するレイヤーです。

マイクロサービスでは4つレイヤーが適切に動作することを確保することが必要不可欠です。 動作の確保するためには、各レイヤーごとにチームを割り当て、チームごとに役割をこなします。 チームを割り当てずに1つのチームだけで全てを行うことはやはり難しいです。 なぜなら、この4つのレイヤーを全てまっとうするには膨大な知識量と、作業を行う時間が必要だからです。 たとえ、4つのレイヤーを全て理解しているようなスーパーエンジニアが企業にいたとしても、 これらをチューニングするにはスーパーエンジニアが数人いるだけでは時間が足りません。

逆に言えば、これのレイヤーに人員を割り当てることができないのであれば、 本番対応可能なマイクロサービスを作り、動作させることは不可能であると本書では言われていました。

ソースコードやサービスだけでなく、チームも独立させる必要があるようです。 チームを独立させることで、サイロ化されるというデメリットも当然あります。 本当に難しいですね。 逆コンウェイの法則でも述べられているように、組織が分割され、独立していなければ、サービスも分割され、独立しないということです。

プロダクションレディ(本番対応可能)

モノリスなアプリケーションをマイクロサービスに分割できたとしても、そのマイクロサービスがうまく動作していなければ(プロダクションレディでなければ)、意味がありません。 マイクロサービスがプロダクションレディかを測る指標として、可用性についてのSLA(サービスレベルアグリーメント)があります。 サービスがどれくらい時間止まることなく動いていたかということです。 可用性についてSLAとして、よく以下の目標が掲げられます。

高水準な可用性についてのSLAを満たすためには以下のことが確保されていることが必要と本書では述べられていました。

これらについて本書では詳しく述べられていました。 これら全てについてまとめるのはしんどいので、ここら辺で終わります笑。

この本を読んでみて、マイクロサービスとは何かといのがよくわかりました。 また、プロダクションレディを達成する方法として、Kubernetesを活用することが有効だと感じました。 やはり、Kubernetesはマイクロサービスを推進するようなツールだということです。 次は改めてKubernetesについて勉強していこうと思います。以上。