久しぶりに Azure Web サイトで色んな言語を動かしたい欲が戻ってきたので、昔試して挫折した Go 言語にもう一度挑戦してみました。
Microsoft Azure Web サイト で Go言語 を CGI で動かす - Qiita のように CGI で動かしている方は居ましたが、net/http を使った方法はまだ誰も試してなさそうだったので、今回は httpPlatformHandler を使って実現してみたいと思います。
Go 言語のインストール
Downloads - The Go Programming Language
Go 言語は Windows 版の 32bit バイナリを使いました。一度、ローカルにダウンロードしてもいいですが、Web サイトには curl と unzip が入っているので、以下のコマンドを叩くだけでインストール出来ます。
curl -O https://storage.googleapis.com/golang/go1.3.2.windows-386.zip
unzip go1.3.2.windows-386.zip
ランタイム系は最近 wwwroot\bin 以下に入れるようにしているので、今回も同じようにしました。
後は管理ポータルから GOROOT の設定を行っておきます。デフォルトでは C:\Go がルートになってしまうので、明示的に Go 言語のルートを指定してあげる必要があります。
これで Go 言語のインストールは完了しました。
サーバーの用意
Go 言語での HTTP サーバーのコードは以下の記事で紹介されているものをベースに、少しだけ httpPlatformHandler 向けに手を加えたものを用意しました。
Go言語でhttpサーバーを立ち上げてHello Worldをする - Qiita
と言っても変更点はリッスンするポート番号を環境変数から取るようにしただけです。
package main import ( "fmt" "net/http" "os" "runtime" ) func viewHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, World, " + runtime.Version()) } func main() { http.HandleFunc("/", viewHandler) http.ListenAndServe(":" + os.Getenv("HTTP_PLATFORM_PORT"), nil) }
本来ならポート番号をパラメータとして渡せるようにした方がいいのですが、今回はまず Go 言語のサーバーを動かすことを優先しました。
httpPlatformHandler の設定
httpPlatformHandler の設定を行う Web.config は殆どテンプレと化しています。run と一緒に与えるパラメータも環境変数として与えた方が便利に使えるとは思います。
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <handlers> <add name="httpPlatformHandlerMain" modules="httpPlatformHandler" path="*" verb="*" resourceType="Unspecified" /> </handlers> <httpPlatform processPath="%GOROOT%\bin\go.exe" arguments="run D:\home\site\wwwroot\server.go" startupTimeLimit="60" startupRetryCount="5" /> </system.webServer> </configuration>
しばらく見ていない間に httpPlatform 要素については公式ドキュメントが用意されてました。元々は Java のアプリケーションサーバーへ対応するためのハンドラーですが、それ以外にも便利に使えます。
Azure へのカスタム Java Web サイトのアップロード
これで全ての準備が終わったので動くのか確認してみます。
所詮 Hello World なので表示はしょぼいですが、一応 Go 言語のバージョンも表示するようにしてるので動いてることがわかりますね。
確認のためにサイトへアクセスすると go.exe がコンパイルを行うので少しだけ時間かかることがありますが、一度起動してしまえばサーバーのインスタンスは基本的に立ち上がりっぱなしになります。
Process Explorer で確認すると go.exe の子プロセスとして、コンパイルされた server.exe がぶら下がっていることがわかりますね。ちゃんと go.exe が死ぬと server.exe も死にます。