そろそろラストスパートですね。
こんにちわ。こじまです。
アドベントカレンダーも22日目になりました。
エモ記事増えてきたので僕もエモ記事を書こうと思います。
マイクロサービスはコンテナの話だけではありません
最近ふと目にしたものにマイクロサービス=コンテナというものがあります。
間違いではない。コンテナは従来の仮想化と用途がかなり違い、本来の目的はIsolate環境を作ることですからね。
なのでIsolateされたプロセスは自然とマイクロサービスのようになる。
だからマイクロサービス=コンテナだという理屈ですね。
マイクロサービス化したい、というご相談を多く受けるのですが皆コンテナ化を中心とした話でIsolateの話すら理解しないままマイクロサービスっていう話をするところもあります。
サーバーレスもマイクロサービス
ここはまだ議論の余地があると思いますが、マイクロサービスアーキテクチャーという概念でいうとサーバーレスも1つも独立したサービスになり得るのでマイクロサービスと言えますよね。
ただ、誤解を生みやすいので僕は最近はサーバーレスをマイクロサービスと言わずあくまでもFaaS(Function as a Service)って言葉で定義づけをしています。
FaaSのポイントは処理のみを実行するということです。
リクエストをパースしたり、ルーティングすることは出来ません。
なので、受信したリクエストをFaaSに渡す際にある程度準備が必要になります。
例えばAzureの場合はCosmosDBのChange Feedがありますね。
CosmosDBというのはAzureが提供するNOSQLで、様々なNOSQLサービスと互換性を持っています。
このCosmosDBをベースにサーバーレスを組み立てる場合、CosmosDBの変更履歴をトリガーにしてサーバーレスを起動し様々な処理を繋いでいきます。
これがとても便利で、マイクロサービスをサーバーレスで実現するときには必要不可欠と言っても過言ではありません。
ちなみにその変更履歴はCosmosDBの中のコレクションにあるわけではなく、Change Feedという別のデータがありそれを利用します。
詳しい話は上記の公式ドキュメントを読んでください。
なので、マイクロサービスを実現する手段としてFaaSもある、ということです。
(FaaSそのものがマイクロサービスというのは間違い)
Kubernetesは?
Kubernetesはマイクロサービスの基盤として利用される場合が多いですよね。これ当然です。
Kubernetesの話は方々でされていますし、国内でもコミュニティが盛んに開催されていますので参加されると色々な情報を得られると思います。
福岡でも”ふくばねてす”というコミュニティがあるので参加してみると良いと思います。
で、本題。
先に書いたFaaSでも同じなのですがKubernetesがマイクロサービスか、という話ですね。
マイクロサービスの基盤として利用されることが多いということでKubernetesを導入すればマイクロサービスになるわけではありません。
これ以上でもこれ以下でもないですね。
マイクロサービス化するために必要なこと
FaaSやK8Sは実行基盤ですから、マイクロサービス化された”アプリケーション”は別で開発する必要があります。
CNCF周りや日本のクラウドネイティブなコミュニティ界隈でもここら辺のアプリケーション設計に関する情報って極端に少ないイメージです。
まあ、ここって技術者が常に検証しながらやっているところなので正解ってないんですよね。
で、弊社の場合どこからやるかって話をちょっと書こうかなと思います。
The Twelve-Factor APPの実装
The Twelve-Factor AppはSaaSを開発するときのガイダンスみたいなもので、12のガイドを実践すればクラウドネイティブ化しますよってやつですね。
で、まずはこれにそって全体の基本設計、アーキテクチャーを整えます。
多分ここ一番やってて面白いところですね。エンジニアの領域で言うとインフラもアプリもセキュリティも関わってきますのでみんなでワイワイ言いながら作れるところです。
マイクロサービスの粒度
ここは常に議論になるところで、さらに従来のシステムからマイクロサービスへリアーキテクトする時は最も難しいとされているところです。
ここでは敢えて新規にシステムを作るリビルドプランを前提で考えます。
これは弊社のイケメンエンジニアが常に言っていることなのですが、単体テストの重要性です。
単体テストが出来る=ある程度独立したモジュールになる、そういう解釈です。
ちょっとこちらの記事を見てください。
この記事中にこんな図があります。(抜粋)
依存関係逆転は、疎結合のアプリケーションを構築する上で重要な部分となります。その理由は、より低いレベルの抽象化ではなく、より高いレベルの抽象化に依存しそれらを実装するように、実装の詳細を記述することができるからです。 したがって、結果として得られるアプリケーションは、テストが容易で、モジュール性が高く、保守も容易です。
そのまま引用しましたがこれを実現するデザインパターンから始めるという感じです。
依存関係が強い構成の場合、実データも依存してくるので単体テストがやりづらい、出来ないということも起こり得ます。(サーバーレスで組むと顕著になります)
そこで登場するのがリポジトリパターンです。
※詳しいコードサンプルや実装に関しては、弊社のオフラインイベントとかでお話ししますね。
Unit of Workから先のストアを隠蔽しデータモックを作る形です。
実データが入ってきたら実データを使います。
このようにリポジトリパターンを使うことでマイクロサービスの粒度を調整できます。
リリースマネジメント
例えばKubernetesの場合、サイドカー的なアプリやOSSを組み合わせて基盤側で全て管理することもできますよね。
その典型的な例がIstioを使ったCircuit Breaker Patternだと思いますが、やはりその前提としてはアプリケーションの適切なマイクロサービス化をしなくてはいけません。リリースはアプリケーションではなく基盤側で管理するようにします。
最後の最後でここに強烈に依存するアプリをあったりなかったり。。。
最後は超ざっくりになりましたが、マイクロサービスはイケてるクラウドネイティブなので是非実践してもらいたいです。
ちなみに弊社のサービスKOSMISCHは、コードを解析しThe Twelve-Factor Appのガイドをベースとしたクラウドネイティブ化のアセスメントレポートを提供します。
今のところC#のみです。アプリからマイクロサービスを検討するのであれば是非使ってみてください。
てことで、残りわずかですがオルターブースアドベントカレンダーを引き続きお楽しみください!