Fabric」を使って、LINE風なチャットアプリを作ってみたいと思います。最後にマイクロサービスとは?昨今、様々なところで、マイクロサービスという言葉を聞くと思います。なんだか、バズワード化している感じもしますが、マイクロサービスとは、一言で言ってしまえば、今まで、一つの大きなアプリケーション(プロセス)で動かしていた複数のサービスを、1プロセスあたり1サービスに分けてしまいましょうということになります。マイクロサービスは、今後アプリケーションを設計する上で非常に重要な概念と言えます。クラウド上の基盤でアプリケーション開発・運用する際、マイクロサービスの特徴である「コンポーネント化」や「分散データ管理」は、非常に有効に機能します。マイクロサービスは、そのアーキテクチャの複雑さゆえ、学習コストは決して小さいものではないこともあり、マイクロサービスの採用に踏み切ることに抵抗を持たれる方も少なからずいらっしゃいます。本記事では、そういった方のために、可能な限り平易な言葉による解説、親しみやすい具体例、実践的なコンテンツをご提供することで、マイクロサービスの採用を検討している方の助力となればと考えております。具体的な例を上げて、更に詳しく説明します。説明をわかりやすくするために、マイクロサービスではないアプリケーション(ここではモノリシックなアプリケーションと呼びます)と、マイクロサービスなアプリケーションを比較してみます。モノリシックなアプリケーションまず従来型のモノリシックなアプリケーションがどういったものかを説明していきます。モノリシックなアプリケーションの代表的なものは、下図のような構成です。Javaで作成された掲示板のWebアプリケーションを例にあげております。Tomcatの上に、単一のJavaプロセスが稼働しており、その中には、メッセージやユーザー情報を管理するサービスクラス、画面を表示するJSPが内包されています。データストアは、単一のデータベースの中に複数のテーブルが入っており、Webアプリケーションはそのテーブルにアクセスすることで、情報を取得、更新します。マイクロサービスなアプリケーション先のモノリシックなアプリケーションをマイクロサービスに置き換えると、以下のような構成になります。違いを見ると一目瞭然なのですが、マイクロサービスなアプリケーションは、1プロセスごとに1サービスが稼働しており、そのサービスが稼働するために必要な他の全てのもの(ここではメッセージ表示UIなどのUIコンポーネント)も内包します。サービスがアクセスするデータストアは、サービス単位で全て独立しており、一つのデータストアをサービス間で共有することは原則としてありえません。サービス間の通信は、RPC(リモートプロシージャーコール)もしくはメッセージキューサービスを用いることが多くあります。上記の例はメッセージキューサービスです。あるサービスは、相手のサービスに送りたいデータをメッセージとして、キューに登録します。相手のサービスはキューからのそのメッセージを取得することで、サービス間通信を実現します。この例では、一つの仮想マシンやコンテナあたりに、1プロセス配備されていますが、必ずしもこのような構成にする必要はありません。以下のような構成でも問題はありません。上記例では、Javaをベースにしていましたが、PythonでもC#でも構いません。サービスごとに異なる技術を使ってもよいとになっています。あるサービスでは、開発言語C#、データストアMySQL、一方のサービスでは、開発言語Python、データストアPostgreSQLといった構成もありです。こちらについては、後述します。一見すると、モノリシックなアプリケーションと比べて、かなり複雑な構成ですよね。いろいろな課題が想像できます。サービス間の通信もモノリシックなアプリケーションと比べるとメッセージキューサービスを用いてるがゆえに手順が煩雑ですし、データの結合方法など、複雑がゆえに色々と考慮しなければならないことがあります。そのような課題を抱えてまでも、何故にマイクロサービスというアーキテクチャを検討する必要があるのかを、以降の章で説明していきたいと思います。マイクロサービスのメリットメリットその1:機能追加・変更による影響が少ないマイクロサービスを用いると、機能追加・変更をした場合の、他の機能への影響を少なくすることができます。先の掲示板のアプリケーションで、何らかの機能を追加するため、ソースコードを修正したとします。モノリシックなアプリケーションの場合、その修正による影響を調査するコストは想像に難くないと思います。ソースコードの構造を理解し、修正したメソッドや関数を呼び出している場所を特定し・・・なんてすごい手間ですよね。マイクロサービスであれば、サービス間の通信に利用するインターフェースさえ変更がなければ、他のサービスへの影響を一切気にかける必要はありません。先の例では、サービス間通信にメッセージキューサービスを使っていますが、その場合、サービス同士がやり取りするメッセージのフォーマットさえ変更がなければ、どれだけサービスの中身を改修しても、他のサービスへの影響はありません。メリットその2:スケールアウトしやすいマイクロサービスは、スケールアウトのコストを非常に少なくすることができます。先の掲示板サービスの例で、掲示板に投稿されたメッセージを閲覧するユーザーが爆発的に増加し、ロードバランサーで負荷分散しなければならなくなったとしましょう。モノリシックはアプリケーションですと、以下のような構成を取ります。上記の例を見れば分かる通り、メッセージ管理サービス、メッセージ表示JSPが2つに増え、ロードバランサーで分散されているので目的は達成できました。本来、負荷の増えていないユーザー情報管理サービスや、アクセスログ管理サービスまで負荷分散を行っています。これの欠点は、必要のないサービスまでスケールアウトすることにより、余分なサーバーリソースを消費してしまうことになります。マイクロサービスですと、以下のような構成になります。ご覧の通り、モノリシックなアプリケーションをスケールアウトした場合と違い、メッセージ管理サービスを含む仮想マシンのみをスケールアウトさせています。メッセージ管理サービスだけを稼働させる仮想マシンのリソースは、モノリシックなアプリケーションを稼働させるためのリソースより少なくてすみますので、スケールアウトした場合も全体的に消費するリソースは少なくすることが可能です。́∀`)bグッ!正確に言いますと、障害に強いのではなく、障害が発生することを前提に設計を行い、あるサービスに障害が発生しても、その障害の影響が他のサービスに波及しません。こちらも今までと同様に、まず、モノリシックなアプリケーションにおいて、アクセスログの処理に障害が出たとしましょう。掲示板アプリケーションでは、ユーザーがメッセージを書き込んだと同時に、アクセスログ管理サービスを呼び出し、アクセスログを記録します。アクセスログ管理サービスは障害が発生しているので、メッセージの書き込み中にエラーが発生し、メッセージの書き込みが失敗してしまいます。マイクロサービスでは、以下のようになります。冒頭でもご説明したように、サービス同士の通信はメッセージキューサービスを使っていますので、非同期であり疎結合です。エンドユーザーがメッセージを登録すると、メッセージ管理サービスが呼び出され、メッセージキューサービスにメッセージが配信され、エンドユーザーには処理が成功したように見えます。アクセスログ管理サービスは障害が起こっているため、アクセスログを記録することができません。キューにはメッセージが登録されているので、サービスが復旧次第、アクセスログを登録することができます。このような仕組みにより、障害の影響を最小限に抑えることが可能です。メリットその4:デプロイによる影響が少ない例えば、アクセスログの処理を高速化するために、アクセスログ管理サービスを修正したとします。モノリシックなアプリケーションでは、一つのサービスを修正するだけでも、アプリケーション全体をデプロイする必要があるので、全てのサービスを停止する必要があります。ユーザーに直接関係のないアクセスログの処理を修正・デプロイするだけで、掲示板のメッセージを閲覧・登録といったサービスも停止する必要はあり、そのユーザー影響は甚大です。マイクロサービスは、今までに挙げてきた例からもわかりますように、アクセスログの処理を修正した場合は、アクセスログ管理サービスだけデプロイすればよいのです。「メリット3:障害に強い」の例でも挙げたように、アクセスログ管理サービスが停止していても、他のサービスは通常通り稼動可能なので、ユーザー影響は全くありません。メリットその5:サービスごとに異なる技術を使うことが出来る先述しましたように、マイクロサービスでは、サービス間の通信はメッセージキューサービスなどを使うことによって、疎結合にします。やり取りするメッセージのフォーマットさえ変更がなければ、サービス間の影響は全くないので、各サービスごとで異なる技術を使っても構いません。言い換えれば、各サービスが提供する機能に適したアーキテクチャを選択出来るということです。先程の掲示板アプリケーションで、以下のような構成を取ることも可能です。Serverを用いているため、同じマイクロソフト製で相性が良いと思われるC#、ユーザー情報サービスは、単なるマスタメンテナンス画面であるため、scaffoldが利用可能なPHPのフレームワークCakePHPを採用し、データベースはPHPと相性がよいMySQL、アクセスログ管理サービスは、ログのフォーマットが将来的に変更する可能性が高いため、定型的なスキーマ構造を持たないDocumentDB、そしてJSONと相性がよいnode.jsを使う・・・といった形で、それぞれのマイクロサービスが提供する機能に適したアーキテクチャを選択することが可能になります。デメリットも・・・いいことずくめのマイクロサービスですが、デメリットもあります。モノリシックなアプリケーションに比べて、アーキテクチャが複雑になりがちです。モノリシックなアプリケーションで保有していた機能を細かいサービスに分けるがために、どうしてもサービス間通信や、サービス間のデータの結合、トランザクション処理が複雑になりがちです。サービス間通信は、RPCやメッセージキューサービスを用いなければなりませんし、トランザクション処理も単一のデータベースのように簡単にロールバックできません。性能面にも懸念が出てくる場合があります。モノリシックなアプリケーションは、サービス間の通信はインメモリコールになりますが、マイクロサービスではサービス間通信にRPCやメッセージキューサービスを用いるため、リモートコール(ネットワーク越しの通信)になります。インメモリコールの方が、リモートコールに比べて、レスポンス面で軍配が上がります。全体的なアプリケーションの性能要件をよく見極めなければいけません。メリットでもあった、サービスごとに異なるアーキテクチャを適用することができるというのも、一方ではデメリットの側面もあります。先程の例のように、サービスごとにC#、PHP、node.jsというアーキテクチャを用いるということは、それだけ、その技術を有するエンジニアが必要ということになります。モノリシックなアプリケーションでは、単一の言語で作成されるので、その言語に精通しているエンジニアだけ集めれてばよかったのに、マイクロサービス化したら、エンジニアのリソース確保が困難になるという可能性もあります。マイクロサービスは、モノリシックなアプリケーションより構成が複雑なゆえに、その設計に必要な技術は、モノリシックなアプリケーションのそれより高度なものが必要になります。Designなど)も必要になります。いったデメリットもありますので、マイクロサービスを適用する際は、そのトレードオフをよく考える必要があります。Fabric」さて、ここまでさんざん偉そうにウンチクを述べさせていただきましたが、実際にマイクロサービスなアプリケーションを作るための実践的コンテンツのご説明をさせて頂きたいと思います。Fabric」というものが提供されています。Fabricが適用する専用のデプロイコマンドを叩くだけで、Azure上の基盤にマイクロサービスが展開されるといったものです。Fabricでマイクロサービスが稼働するまでのおおざっぱな流れ先の説明は、あまりにもざっくりとしすぎたので、本章で、具体的な例も交えて説明します。Fabricにて、マイクロサービスが稼働するまでの、とってもおおざっぱな流れを図にしたものであり、細かい手順は後ほどご説明しますが、まずは、本章でイメージを掴んで頂ければと幸いです。Fabricは2018年7月9日現在、JavaとC#をサポートしており、上記の図の例は、Javaになりますが、多分C#もさほど変わりないと思っております。上記の図を元にして、詳細に説明致します。上記の図の項番((1)・・・(6))と、以下の説明の項番は対応しております。Fabricが稼働する環境を構築します。Fabricクラスターと呼称します。Fabricクラスターを構築することができます。Machineの集合体です。Machineにマイクロサービスを展開することとなります。Fabricとかマイクロサービスとか聞くと、なんかすごいことやってそうな雰囲気ですが、それらを構成する要素は、意外にもレガシーな技術なのです。マイクロサービスを構成するソースコードの作成マイクロサービスを構成するソースコードを作成します。肝心な部分ですし、エンジニアの腕がなる部分ですね。Fabricはフレームワークですので、ソースコード作成時には、フレームワークのルールに乗っ取る必要があります。実装の詳細については、後ほど説明しますが、ここで大事なのは、ソースコードを配置するディレクトリです。Fabricでは、サービス単位に以下のディレクトリを作成し、ビルドの成果物や設定ファイルを配置することが決まりとなっております。Dataそれぞれのディレクトリの詳細は以下のとおりです。Code・・・アプリケーションの実行ファイルを格納します。Config・・・アプリケーションの設定ファイルを格納します。Data・・・アプリケーションで使用するデータを格納します。重要で利用頻度が高いのはCodeというディレクトリです。ここでは、Javaで作成したコードをjarにビルドしたものを格納します。起動スクリプトの作成(2)で説明したCodeディレクトリには同時にentryPoint.shというファイルも作成する必要があります。このファイル、実際は、雛形作成ツールYeomanやEclipseなどのIDEプラグインで自動生成されることが多いのですが、非常に重要なファイルです。これは、(3)で作成した実行プログラム(Javaの場合はjar)を起動するためのスクリプトです。実際に中身を見てみましょう。App.jarなんともないbashのシェルスクリプトですが、最後の行にご注目ください。(2)で配置したjarで実行する一文があります。これが実はキモでありまして、それは、このあと(5)ご説明致します。Fabircクラスターへアップロードします。このコマンドを一発叩くと、指定したインスタンス数分、各ノードにマイクロサービスを構成する実行ファイルがアップロードされます。ノードが5つあり、インスタンス数を3としてアップロードすると、5ノードの中からランダムに3つのノードの実行ファイルがアップロードされます。マイクロサービスの起動(4)で各ノードにアップロードされたマイクロサービスは、entryPoint.shが内部的に起動されます。先程ご説明したようにentryPoint.shには最後の行に実行ファイル(App.jar)を起動する一文が書かれておりまして、これが実行されることにより、マイクロサービスを構成するプロセスが起動することになるわけです。Balancerで提供されています。Balancerに来たリクエストは、各ノードに配置されいてるマイクロサービスに分散されます。Fabricでマイクロサービスが稼働するわけです。Fabricでは様々な種別のマイクロサービスを作成することはできますが、本記事では以下の2つの代表的なマイクロサービスをご説明します。この後に紹介する実践的コンテンツ(チャットアプリ)でもこの2つのサービスを使います。Serviceその前にStateful及びStatelessの説明をさせて頂きます。Statefulであるとは?Statefulとはサーバーが状態を持つ構成のことをいいます。Statefulの代表格は、認証にセッションとCookieを使った実装です。セッションを使った実装は以下のようなイメージになります。アプリケーションサーバーはセッションを発行し、セッションIDとそれに紐づく値(ユーザー名など)を保存します。それと同時にアプリケーションサーバーはユーザーにセッションIDのCookieを発行します。次回のリクエストからは、ユーザーはHTTPリクエストにセッションIDが格納されたCookieをリクエストし、アプリケーションサーバー側では、そのCookieにあるセッションIDから、アプリケーションサーバー側にあるユーザー情報を取得して、アクセスしてきたユーザーを識別します。これだと不都合が生じる時があります。アプリケーションサーバーの負荷が高くなり、サーバーの台数を増やす(スケールアウト)したときは、以下のような構成になります。どちらのアプリケーションサーバーにアクセスしたときも同じセッション情報を取得できるようにしなければなりません。そのためには、セッション情報をアプリケーションサーバー間で共有する仕組みが必要になります。セッション情報をデータベースに格納したり、セッション情報をサーバー間でレプリケーションしたりと手法は色々ありますが、どれも大掛かりな構成となり非常に手間がかかります。これでは簡単にスケールアウトできません。これがステートレスでないことのデメリットです。Statelessであるとは?一方で、Statelessとは、サーバーが状態を持たない構成のことをいいます。Token(詳細はこちら)を用いた例です。Tokenを乗せています。Tokenの中に情報がある)ので、インフラ構成がシンプルになります。APIを用いたシステムの場合、APIはその汎用性を保つため、非常に細かい機能に分割され、様々なシステムから利用することが予想されます。そのため、負荷も高くなり、必要に応じてスケールアウトすることが必然とされますが、ステートレスであるということはスケールアウトしやすいということになります。これがステートレスであるということのメリットです。Serviceとは?先程ご説明したStatelessな構成を提供するためのサービスです。こちらは特に何も難しいことはありません。Serviceとは?Statefulな構成を提供するためのサービスです。こちらがちょっと特殊なのですが、先程もご説明したようにStatefulはサーバー側で状態を持つ、すなわちサーバー側でデータを持つことを前提とした構成です。Balancerによって構成された複数ノードが高度に分散して稼働します。Fabricはこの同期処理を裏でやってくれるのです。Fabricクラスター側でHashMapの内容が各ノード間で同期される仕組みとなっています。LINE風なチャットアプリを作ってみようでは、前置きが非常に長くなりましたが、早速、実践的なコンテンツを作成してみましょう。Fabricで作成してみたいと思います。チャットアプリの仕様チャットアプリの画面は以下のようになっております。画面下部にテキストボックスがあります。チャットに発言したい場合は、「名前入れてね」の部分に発言者の名前を入れて、「発言内容入れてね」の部分にメッセージを入れて「発言する」をクリックします。「更新する」のボタンをクリックしない限り、相手の最新の発言が表示されません。なんともレガシーな仕様ですみません。Fabricの説明がメインなので、あまりチャットアプリの仕様を複雑にすると、本質から外れてしまうような気がしたので、こんな簡単な作りにさせて頂きました。認証とかユーザー登録とかいった仕組みもありません。画面に表示されるユーザーのアイコンは、ユーザー名に紐付いております。ntakeiの場合はlisaの場合はそれ以外の場合はのアイコンが表示されるようになっております。システム構成チャットアプリのシステム構成は、下図のとおりになります。ChatWebとChatDataの2つのマイクロサービスから構成されており、それぞれの役割は以下のとおりです。Service)メッセージをReliableHashMapに登録・取得するためのRPCサービスを提供アプリケーションの動作シーケンスは以下のとおりです。ユーザーが特定のURLにアクセスすると、そのリクエストをHTTP経由でChatWebサービスが受け、ユーザーに画面のHTMLをレスポンスとして返す。ユーザーは、チャットのメッセージ登録・取得要求をHTTPの経由でChatWebサービスに要求する。ChatWebサービスは、RPC経由でChatDataサービスをコールし、ReliableHashMapにメッセージを登録・取得を行う。Fabricが、ReliableHashMapに登録されたデータをノード間でレプリケーションする。開発環境を構築します。Fabricでは、2018年7月9日現在、JavaとC#をサポートしていますが、今回はJavaで作成してみます。マイクロソフト的には、Javaはマイノリティかもしれませんが、多分、世界的にみれば、Javaのユーザーの方が多いと思いますので、Javaで作ってみます。いうか、私自身C#があまり得意でないというのも大きな理由のひとつなのかもしれません。Neonを想定しております。FabricのEclipseプラグインを使いますが、こちらWindowsには対応していないようです(2018年7月9日現在)。開発環境を構築してみましょう。Neonはインストール済みであるとします。FabricのEclipseプラグインをインストールします。Fabricのプロジェクトの雛形の作成や、クラスターへのデプロイなどをコマンドいらずのGUIでできちゃいます。Software...」の順にクリックします。「Add...」をクリックします。「Location」のところに、「http://dl.microsoft.com/eclipse」と入力して、OKをクリックします。Eclipse」にチェックして「Next」をクリックします。後はウィザード通りに従えば、プラグインのインストールは完了です。Fabricクラスターに対する各種操作(ビルドなど)を行うsfctlコマンドをインストールします。sfctlコマンドの動作にはPython3が必要になりますので、インストールします。python3次にsfctlコマンドをインストールします。sfctlこれでsfctlコマンドのインストールは完了です。FabricのビルドにはGradleが必要なので、これをインストールします。Gradleは、sdkmanというパッケージマネージャーを使ってインストールします。そのsdkmanをインストールします。helpEnjoy!!!上記のように表示されればOKです。上記の/path/toは、コマンドを実行したユーザーのホームディレクトリと読み替えてください。"/path/to/.sdkman/bin/sdkman-init.sh"Gradleをインストールします。gradleこれでGradleのインストールは完了です。小細工が必要になります。FabricのEclipseプラグインは、なぜか内部的にGradleのパスが、/usr/local/bin/gradleに固定になっているようなのです。実際にGradleがインストールされているパスへのシンボリックリンクを作成する必要があります。私の環境では、Gradleは/Users/ntakei/.sdkman/candidates/gradle/current/bin/gradleにインストールされていましたので、以下のようにシンボリックリンクを作成しました。本章では、今回作成するチャットアプリの、Eclipseでのプロジェクト構成を説明します。これ以降の章より、具体的な手順を説明しますが、その手順はかなりのステップ数に及ぶこととなります。途中で自分が何をやっているのか迷子にならないように、まず、手順の概略を最初に示します。全体の流れをおさえた上で、詳細に踏み込むというわけです。Fabricの、Eclipseプラグインによるビルドでは、ビルドツールとしてGradleを用います。Gradleの基本的な知識を事前におさえておく必要がありますので、Gradleに自信のない方は、まず本ブログの「多分わかりやすいGradle入門」をご覧になってください。今回のアプリケーション作成に必要なGradleの知識が一通り記載されています。前置きが長くなってしまいました。今回作成するプロジェクトは以下のような構成になります。Chatという親プロジェクトのサブプロジェクトして、3つのプロジェクト「ChatWeb」「ChatData」「ChatRPC」があります。ChatWeb、ChatDataは「システム構成」のところで説明したChatWebサービス、ChatDataサービスに該当します。ChatRPCはChatWeb、ChatDataの両方から参照されるプロジェクトで、ChatDataへのRPCでやり取りされるデータ、及びRPCのインターフェースを定義しています。ビルドの流れこれ以降は、ビルドの大まかな手順を示していきます。ビルドツールGradleにて、以下のような手順でビルドが行われます。ChatWebプロジェクトからビルドします。ChatWeb.jarが出来上がると、次はChatWebサービスを稼働させるために必要なライブラリのコピーを行います。これでChatWebサービスのビルドは完了です。ChatDataサービスにおいても、ほぼ同様のことを行います。ChatDataプロジェクトをビルドし、ChatData.jarを作成します。ChatData.jarが出来上がると、次はChatDataサービスを稼働させるために必要なライブラリのコピーを行います。Fabricクラスターにデプロイします。プロジェクトの構成、ビルドの大まかな流れをご説明しました。これより、詳細な手順に入ります。今回作成しようとするアプリケーションのソースコードは、以下のGitHubに登録しております。これから行うプロジェクトの作成で、ソースコードはもちろんのこと画像ファイル等いくつか必要なファイルがありますので、以下のGitHubをあらかじめCloneしておいてください。https://github.com/noriyukitakei/asf-sample-chatでは、まずはじめにChatプロジェクトを作成します。以下のような構成のプロジェクトを作成することをゴールとします。Eclipseを起動し、「File」→「Other...」の順にクリックします。Project」の順にクリックします。>」をクリックしてください。Name」の部分に「ChatWeb」と入力して、「Finish」をクリックしてください。下図のようにChatApplication/ChatWebPkg/Code/wwwroot/imgというディレクトリを作成し、3つの画像ファイルを置いてください。画像ファイルは先程のGitHubにあがっております。この画像ファイルは、ユーザー名と紐付いており、ユーザー名ntakeiで発言すると、ntakei.pngがアイコンとして表示されます。ntakei、lisa以外のユーザーはother.pngが表示されます。wwwrootディレクトリ配下に、以下の内容のファイル(ファイル名はindex.html)を作成してください。このファイルはチャットの画面を表示するためのHTMLになります。HTTPのリスニングポートの設定をします。Chat/ChatApplication/ChatWebPkg/ServiceManifest.xmlを開き、以下のように修正します。<Resources>〜<Resources>の部分を追加します。後に作成するHttpCommunicationListener.javaでこの設定を利用します。ServiceManifest.xmlというファイルはサービスごとに存在し、サービスの全体的な挙動を決定するための設定ファイルになります。Chat/build.gradleを以下のように修正します。Chat/setting.gradleを以下のように修正します。ServiceであるChatWebサービスのプロジェクトを作成します。プロジェクト自体は、Chatプロジェクトのサブプロジェクトとして既に出来ているので、ここではいくつかのファイルを追加・修正します。以下のような構成のプロジェクトを作成することをゴールとします。ChatWebサービスがWebサーバーとしてリスニングするためひ必要な構成ファイルHttpCommunicationListener.javaを以下の内容で作成します。先程作成したHttpCommunicationListenerをリスナーとして登録するため、Chat/ChatWeb/src/statelessservice/ChatWeb.javaを以下のように修正します。build.gradleを以下のように修正します。API」というエラーが出ている場合には以下の対処を行ってください。「Eclipse」→「Preferences...」の順にクリックします。rules)」を「Info」に変更して「OK」をクリックしてください。エラーが解消されるはずです。ChatRPCプロジェクトの作成ChatWeb⇔ChatData間でRPC通信をするために必要なJavaBeans及びインターフェースを定義します。以下のような構成のプロジェクトを作成することをゴールとします。「File」→「New」→「Other...」の順にクリックします。>」をクリックします。name」に「ChatRPC/src/rpcmethods」を入力して、「Finish」をクリックしてください。Beansを作成します。Chat/ChatRPC/src/rpcmethods/ChatMessage.javaを以下の内容で作成してください。ChatWeb⇔ChatData間でRPC通信をする際のメソッドのインターフェスを作成します。Chat/ChatRPC/src/rpcmethods/ChatRPC.javaを以下の内容で作成してください。build.gradleを以下の内容で修正してください。Serviceのプロジェクトを作成します。以下のような構成のプロジェクトを作成することをゴールとします。Service」の順にクリックします。Service」をクリックしてください。Serviceが作成されるはずなんですが、わたしの環境では一発で作成されませんでした。サービスの入れ物だけ出来て中身が空っぽなんです。Serviceを作成したらうまくいきました。゚)なんでなんでしょうね。バグですか?ささ、気を取り直して、先に進みます。Chat/ChatData/src/statefulservice/ChatData.javaを以下のように修正します。先程ChatRPCプロジェクトで定義したChatRPCインターフェースをimplementsしたRPC通信の実装クラスを作成します。Chat/ChatData/build.gradleを以下のように修正します。これで全てのプロジェクトを作成し終わったのですが、おそらくコンパイルエラーが多数出ていると思います。これは、Gradleの設定ファイルで設定した各プロジェクト間の依存関係が反映されていないからです。正確に言いますと、ChatWebプロジェクトとChatDataプロジェクトがChatRPCプロジェクトを参照出来ていませんし、build.gradleのdependenciesで定義した依存ライブラリをダウンロード出来ていないからなのです。ここで、Gradleの設定ファイルをプロジェクトに反映させる処理を行います。Project」の順にクリックします。すると、コンパイルエラーがキレイサッパリなくなるはずです。ローカルクラスターへのデプロイさて、これで準備は整ったので、Azureにデプロイしてみましょうと思いますが、いきなりAzureに上げる前にローカルクラスターにデプロイします。Machineを起動しなければいけないので、非常にお金がかかってしまいます。Machine起動していたら、いくらお金があっても足りません。そこで、ローカルクラスターの出番です。Fabricのクラスターです。Dockerがインストールされていれば、どこでも使えます。ローカルクラスターで試しに動かしてみて、問題なければAzure上のクラスターにデプロイするというのがベストです。ローカルクラスターをインストールしてみましょう。Dockerはインストール済みであることを前提とします。以下のDockerfileを作成します。.Dockerイメージが出来上がります。次に以下のコマンドでDockerイメージからコンテナを生成します。mysfclusterローカルクラスターが立ち上がるまでには、ちょっと時間がかかります。してからhttp://localhost:19080/にアクセスしてください。Exploreと呼びます)が表示されれば成功です。ローカルクラスターの準備が整ったところで、アプリケーションをローカルクラスターにデプロイしてみましょう。アプリケーションをビルドします。Application」の順にクリックします。ビルドが成功すると、Eclispeのコンソールに以下のように表示されるはずです。up-to-dateビルドが成功していたら、いよいよローカルクラスターにデプロイしてみましょう。Application...」の順にクリックします。「PublishProfiles/Local.json」を選択して、「Publish」をクリックしてください。Exploerの「Application」の表示が以下のようになります。(失敗するとApplicationの緑色の丸が黄色になったり赤になったりします)では、チャットにアクセスしてみましょう。http://localhost:8080/にアクセスしてください。キタ━━━━(゚∀゚)━━━━!!デプロイ成功ですヮ(゚д゚)ォ!ちゃんと動きます。Fabricクラスターへのデプロイいよいよこれが最後の手順です。Fabricクラスター)にデプロイしてみましょう。Fabricクラスターを使いには、公的な証明書機関で署名された証明書が必要になりますので、取得してください。Fabricのノード間の認証に利用されます。Fabricクラスターに適用するためには、Azureの証明書管理サービス「キーコンテナ」を使うのが一番です。取得した証明書をキーコンテナに登録する手順を説明致します。Azureポータルにアクセスして「すべてのサービス」とクリックしてください。テキストボックスが表示されますので、以下のように「キー」と入力すると「キーコンテナ」が表示されますので、クリックしてください。「追加」をクリックしてください。「名前」に任意の名称、「サブスクリプション」「リソースグループ」「場所」は環境に適したもの、それ以外は以下の図のように入力して、「作成」をクリックしてください。/インポート」の順にクリックしてください。「証明書の作成方法」は「インポート」、「証明書の名前」は任意の名称、「証明書ファイルのアップロード」はpfx形式(鍵と証明書が一つになったもの)の証明書を選択、「パスワード」はアップロードした証明書に設定されているパスワードを入力してください。最後に「作成」をクリックしてください。これで証明書の登録は完了です。次に後ほどの工程で使う情報を今のうちにメモしておきます。インポートが完了した証明書をクリックしてください。最新のバージョンの証明書をクリックしてください。拇印」「シークレット識別子」をメモっておいてください。Fabricのクラスターを作成します。Azureポータルにアクセスして「すべてのサービス」とクリックしてください。Fabricクラスター」が表示されますので、クリックしてください。「追加」をクリックします。「クラスター名」には任意の名称、「オペレーティングシステム」にはUbuntuServer、「ユーザー名」「パスワード」は任意のもの、「サブスクリプション」「リソースグループ」「場所」は環境に応じて必要なものを入力して、最後に「OK」をクリックします。ブロンズ、「仮想マシンのサイズ」は任意のもの(小さすぎるとクラスターが起動しないこともあります)、「VMスケールセットの初期容量」は5、「カスタムエンドポイント」は8080と入力して「OK」をクリックします。カスタムエンドポイントは、アプリケーションのエンドポイントのポートです。チャットのアプリケーションは8080でアクセスします。Balancer側で8080でリッスンして、各ノードにリクエストを分散してくれます。「必要な設定の構成」をクリックします。先程作成した「sf-cert」をクリックしてください。以下のようなエラーが発生します。「sf-certのアクセスポリシーを編集する」をクリックします。Machineへのアクセスを有効にする」にチェックを入れて、「保存」をクリックしてください。一度「sf-cert」をクリックしてください。「カスタム」にチェックしてください。以下の画面が表示されます。拇印」、証明書の拇印には先程メモした「シークレット識別子」を入力して「OK」をクリックします。設定に問題なければ「作成」のボタンが表示されますので「OK」をクリックします。Fabricクラスターが出来上がります。Fabricクラスターが完了したらデプロイしてみましょう。その前に、設定ファイルに修正が必要になります。拇印、証明書の秘密鍵の設定が必要になります。Chat/ChatApplication/ApplicationManifest.xmlを以下のように編集します。<Certificates>〜</Certificates>の部分を追加しました。拇印」を入力してください。Chat/PublisherProfiles/Cloud.jsonを以下のように修正してください。"/path/to/server.crt"}}上記のパラメーターについて説明します。Fabricのトップ画面(以下参照)に表示される「クライアントの接続エンドポイント」のホスト名の部分です。ConnectionPortは19080、ClientKeyは、先程キーコンテナに登録した証明書の秘密鍵で、x509形式であり、パスワードで保護されてない必要があります。ClientCertはx509形式の証明書です。デプロイしてみましょう。Application...」の順にクリックします。選択して、「Publish」をクリックしましょう。https://sf-chat.japaneast.cloudapp.azure.com:8080/にアクセスして、ローカルクラスターのときと同様にチャットの画面が表示されればOKです。Fabricを用いたマイクロサービスの実現方法がご理解頂けたかと思います。マイクロサービスは、あくまで目的ではなく、設計方法の一つです。モノリスが適しているシステムもあれば、マイクロサービスが適しているシステムもあります。大切なのはシステム設計をする際、モノリシックな観点に加えて、マイクロサービスな視点も持ち、そのシステムに適した設計を行うことだと思います。雑誌等の執筆依頼を受付しております。役に立たなかった1人がこの投稿は役に立ったと言っています。コメントをキャンセルメールアドレスは表示されません。Reserved.本サイトに掲載されている社名、製品名、サービス名等は各社の商標または登録商標です。プライバシーポリシーお問い合わせ。