0
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

HerokuでMicroservicesを実装するときに役立つ便利機能

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、ぜひご検討くださいませ。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
0
Help us understand the problem. What are the problem?