Microservices Advent Calendar 2018 23日目、本日はかしゆかの誕生日です、ゆかちゃん誕生日おめでとうございます、三十路だね。ということで、本日は記念して、Heroku のお便利機能についてご紹介します。
きっかけはどうであれ、「さぁMicroservicesへ移行するぞ!!」というよりも「Microservices化しないとあかんやつや...」みたいになって、アプリケーションアーキテクチャの一切合財を、根底から覆すような自体に陥ってから始まることはよくあることです。そのときは、アプリケーションアーキテクチャの変更を、インフラ・プラットフォームが障壁となって、実現を困難にするのはよろしくないのは想像に難くないでしょう。
実際には、Microservices
の原典通り、モノリシックアプリケーションを少しずつ引っ剥がしながら、Microservies
化を進めていくことが多いと考えています。もし、Heroku だったら、そのときの障壁をどれだけ少なくすることができるだろうか、という問いに対してPrivate Space DNS Service Discoveryを紹介できます。
Private Space DNS Service Discovery
Herokuは、アプリケーションの動作するコンテナをDyno
と呼んでいます。Heroku Private Spaces サービスの中で実行されるすべてのDyno
に対して内部的にホスト名が割り当てられる仕様になっています。FQDN は次の通りの命名規則になっています。
内部アドレスのFQDN: [Dyno番号].<プロセスタイプ>.< Herokuアプリ名>.app.localspace
Dyno番号
Dyno番号
とは、起動しているコンテナの通し番号です。標準では 1つのDyno
で起動するようになっていますが、スケールさせることによって、これを10個、100個と簡単に増やすことができます。起動した順番によって、この番号が割り振られる仕様となっています。たとえば、20個のDyno
を動かした場合には、1〜20の通し番号が振られる、ということです。
プロセスタイプ
Dyno
は役割を持って起動させることが可能です。
一つのアプリケーションソースコードで、複数のプロセス・アプリケーションを起動したいということはよくあることでしょう。外部からのアクセスを受け付けるWebアプリケーションの役割をもつもの、バックエンドで非同期処理を行うもの、時限的にバッチ処理を行うもの。他にも様々な役割を持つものがあるでしょう。これらは、一般的に起動するコマンド自体が異なっているものです。たとえば、Node.jsのExpress
フレームワークでアプリケーションを作った場合、Webアプリケーションは npm start
で起動されるでしょうし、バックエンドアプリケーションは npm run worker
などのように別の起動コマンドを指定しているはずです。異なるプロセスとして個別に動かしたい場合は、このように起動コマンドを分離して利用します。
Heroku では、これらを「プロセスタイプ
」として定義を行います。具体的には、ソースコードのあるルートディレクトリにProcfileを準備して定義します。先程の Node.jsの例を記述するとするならば、次のとおりになります。
web: npm start
worker: npm run worker
このようにして、起動タイプを変えることで、個別にDyno
を制御できるのが特徴です。web
プロセスは、スペックの低いDyno
を、アクセスをできるだけ処理したいから5個動かす。バックエンドのworker
プロセスは、重めの処理を行い、メモリも使うのでスペックの高いDyno
に。処理依頼自体は多くないので、2子で動かす。などのように個別に定義できるのがお便利なところです。
また、このweb
プロセスタイプは外部に必ずサービスを公開するURLをもつことになりますが、web
プロセスタイプを持たないHerokuアプリケーションを作成することで、Private Space内だけでアクセスできる、内部専用のアプリケーションを提供することもできます。外部からはアクセスされたくない、隠蔽されたサービスの開発も容易にできてしまうんですね。
Herokuアプリ
Herokuでアプリケーションを実行する場合に、一つのURLが割り振られる単位、または一つのソースコードツリーで表現されるアプリケーションの単位を、Herokuへデプロイする単位となります。Herokuアプリケーションには、一つのGitリポジトリが割り当てられています。このリポジトリにソースコードをpushすることで、一つのアプリケーションがデプロイされます。
サービスの内容、実現したい機能によって、この単位は分割されるでしょうが、この一つの管理単位のことをHerokuアプリケーションで分割するようになっています。
このHerokuアプリケーションでは、「環境変数」「アドオン」をセットする単位ともなりますので、共有して利用したい機能をまとめるには、それらを共有したい単位にして一つのアプリケーションとすることも検討できます。ただし、アドオンについては、複数のHerokuアプリケーションで共有できるものもあります。例えばHerokuの提供するHeorku Postgres
は、複数のHerokuアプリケーションで共有できるものです。
DNSサービスディスカバリの使い方
例えば、test-private-space という名前の Herokuアプリケーション上に、webとworker Dynoが2つずつ稼働していて、この中の worker の1つ目の Dynoへアクセスしたい場合であれば、1.worker.test-private-space.app.localspace というホスト名へアクセスすれば、該当のアプリケーションへダイレクトに接続することができます。
実際に稼働中のDynoを指定してアクセスできるのはありがた嬉しいのですが、スケールしていて複数のDynoが動いているような場合、わざわざ特定のDynoをアプリケーションで指定するには荷が重すぎます。
なんと、FQDNのうち[Dyno番号]
は省略することができます。[Dyno番号]
を省略してホスト名解決を行うと、稼働中のプロセスタイプのDynoのうち、ランダムで対象のDynoの3つのIPアドレスが返ってくる仕様です。もちろん3台稼働していなければ、1つや2つしか返ってこないケースもあります。この取得したIPアドレスを元にアクセスすれば、自動的に負荷分散の機能も享受されるという仕組みにもなっています。
まとめ
Microservices
でサービスメッシュ構造となるときに、具体的にそのサービスをポイントする方法が明確になっていなければ、使いにくいことこの上ないでしょう。自動的に割り振られるホスト名の場合、そのサービスが実現するものと名前が紐づけされていなければサービスとホスト名を紐付ける別の何かをジュビしなければなりません。
Heroku Private Spaceをご利用であれば、サービスを特定できるHerokuアプリケーション名とプロセスタイプを名付けることが自由にできます。そして、その名前がそのままホスト名として利用できることは、機能的価値が高いのではと考えられます。
Microservices の実現のお供にHeroku、ぜひご検討くださいませ。