以前、heroku 上級編 - Private Space でできること -でも触れましたDNSサービスディスカバリ機能は奥深く、さまざまな機能が利用できます。うまく組み合わせると、通常のPaaSでは実現の難しいこともカンタンに実装できたりします。
今日は、その中から「環境変数」について紹介します。
DNSサービスディスカバリで利用できる環境変数
ここに書いてあるよ、と言ったらそれまでですが。もう少し具体的に説明します。
全部で 4つの環境変数があります。これで、Private Space内で割り当てられた名前やIPアドレスを知ることができます。表の部分をコピペしたら、ちゃんとMarkdownでコピペされたので「qiitaやるじゃん」って思ったとこです。
| 環境変数名 | 内容 | 
|---|---|
| HEROKU_DNS_FORMATION_NAME | 対象のdynoを含むプロセスタイプのホスト名 | 
| HEROKU_DNS_DYNO_NAME | 対象の dyno に割り当てられた内部FQDNホスト名 | 
| HEROKU_DNS_APP_NAME | dynoを有するHerokuアプリのサブドメイン名 | 
| HEROKU_PRIVATE_IP | dynoに割り当てられた、Private Space内でアクセス可能なプライベートIPアドレス | 
では、もう少し具体的に示していきます。
例えば、sample-app というPrivate Space 内で動いている Herokuアプリがあるとします。Internetでアクセスする場合には、https://sample-app.herokuapp.com が標準のホスト名になるものです。
このとき、web dyno が 4つ。worker dyno が 2つ動いていたとした場合に、実際にこれらの環境変数名がどうなるかを示していきながら説明します。
まず、dyno の内部FQDNホスト名は次の形式で割り当てられます。この基本をおさえた上で、次にすすんでどうぞ。
内部アドレスのFQDN: [Dyno番号].<プロセスタイプ>..app.localspace
では、web.1 dyno (1番目のweb dyno)で実行した場合にはどうなるでしょうか。
| 環境変数名 | 返却されるホスト名/IPアドレス | 
|---|---|
| HEROKU_DNS_FORMATION_NAME | web.sample-app.app.localspace | 
| HEROKU_DNS_DYNO_NAME | 1.web.sample-app.app.localspace | 
| HEROKU_DNS_APP_NAME | sample-app.app.localspace | 
| HEROKU_PRIVATE_IP | 10.x.x.x | 
IPアドレスは起動するタイミングによって、常に変動しますので省略しています。
では、worker.2 (2番目のworker dyno)で実行した場合は、というと次のようになります。
| 環境変数名 | 返却されるホスト名/IPアドレス | 
|---|---|
| HEROKU_DNS_FORMATION_NAME | worker.sample-app.app.localspace | 
| HEROKU_DNS_DYNO_NAME | 2.worker.sample-app.app.localspace | 
| HEROKU_DNS_APP_NAME | sample-app.app.localspace | 
| HEROKU_PRIVATE_IP | 10.x.y.y | 
つかいかた
これらがわかるとどんな良いことがあるでしょうか。dyno 自身がこれらを利用するということは少ないでしょう。ただ、これらの情報を他に接続するような場合に利用したり、相手に知らせたりすることができるようになります。
HEROKU_PRIVATE_IP/HEROKU_DNS_DYNO_NAME
先日、苦難の上に到達した Private Space 内で自分自身の IPアドレスを特定する方法 でも紹介しましたが、IPアドレスや自分自身のホスト名は、外部からアクセスしてもらうときに必要不可欠な情報になります。
Java RMIなどでは、自分自身のIPアドレスを指定して、待ち受けて起動するような仕様になっているものがあります。何も指定しないと、デフォルトではhostnameで解決されたIPアドレスを指定するようです。
ということを紹介しましたが、具体的にはApache JMeterなどでは、Master/Slave の構成にする際に、Slave側は外部からアクセスできるようなRMI Serverのホスト名(IPアドレス)を指定する必要があります。具体的には Javaから JMeterを起動する際に、javaコマンドの引数に次のような指定が必要になるはずです。例えば、次のように起動コマンドに指定するでしょう。
java -Djava.rmi.server.hostname=${HEROKU_DNS_DYNO_NAME}
java -Djava.rmi.server.hostname=${HEROKU_PRIVATE_IP}
このように指示しないと、動いてほしいように動作しないということになります。
HEROKU_DNS_APP_NAME
heroku へdeployするソースコードは、Herokuアプリ名が何になるか分からずにdeployされます。可搬性も考慮すると、そのようにコーディングすることが望ましいというか、そうせざるを得ないでしょう。この場合、あるdynoから他のdynoへ接続したい場合に、内部ホスト名を指定する場合にサブドメインとしてこのHEROKU_DNS_APP_NAMEを指定します。
たとえば、worker.1(1番目のworker dyno)へアクセスしたいときには、次のようにホスト名を指定することになります。
1.worker.${HEROKU_DNS_APP_NAME}