Erlang WebサーバCowboy入門

2014年9月24日

Erlang Cowboy

Cowboyとは

特徴はスピードと軽さです。 またHTTP/1.0、HTTP/1.1、SPDY、WebsocketとRestのすべてに対応しています。

他のアプリケーションにも簡単に組み込めるので、様々な使い方が可能です。

また、CowboyはErlangで書かれているサーバのため、フォールトトレランスの面でも優れています。

前書き

この記事はCowboyの公式Getting Startedガイドを多く参考しています。

公式ドキュメントサイトはかなりよくできていますので、英語はできる方はぜひ確認してください。

Hello Erlang!

今回作るアプリケーションは単純なHello worldになります。

早速、Cowboyアプリケーションのフォルダーを作成してみましょう。

mkdir hello_erlang && cd hello_erlang

ErlangやCowboyアプリケーションを作るためのerlang.mkを利用します。
erlang.mkとCowboyは同じ開発者が作っていますので、相性はいいです。

erlang.mkをダウンロードします。

wget https://raw.githubusercontent.com/ninenines/erlang.mk/master/erlang.mk

アプリケーションベースファイルを生成する。

make -f erlang.mk bootstrap

このコマンドで下記のファイルが生成されました。

├── Makefile
└── src
    ├── hello_erlang.app.src
    ├── hello_erlang_app.erl
    └── hello_erlang_sup.erl

※ 生成されるアプリケーションはフォルダー名前を利用します。

Cowboyをプロジェクトに追加するため、Makefileを下記のように変更。

PROJECT = hello_erlang
DEPS = cowboy
include erlang.mk

アプリケーションリソースファイルsrc/hello_erlang.app.srcにcowboyの依存を追加します。

{application, hello_erlang, [
	{description, ""},
	{vsn, "0.1.0"},
	{modules, []},
	{registered, []},
	{applications, [
		kernel,
		cowboy,
		stdlib
	]},
	{mod, {hello_erlang_app, []}},
	{env, []}
]}.

makeコマンドでCowboyとその依存パッケージを一括にダウンロードし、コンパイルします。

make

アプリケーションのメインのソースファイルであるsrc/hello_erlang_app.erlにCowboyを初期化します。

start(_Type, _Args) ->
    %% ルートの宣言
    %% {ホストマッチ, [ {パスマッチ, 実行するcowboy_http_handler, [cowboy_http_handlerのオプション] } ]
    Dispatch = cowboy_router:compile([
        {'_', [{"/", hello_handler, []}]}
    ]),
    %% httpリスナーを起動
    %% ポートを8080に設定します
    cowboy:start_http(my_http_listener, 100, [{port, 8080}],
        [{env, [{dispatch, Dispatch}]}]
    ),
    %% スーパバイザを起動
    hello_erlang_sup:start_link().

erlang.mkには便利なテンプレート機能があります。 この機能を使うとモジュールコードの骨組みを自動的生成できます。

使い方は:

make new t=テンプレート名 n=モジュール名

利用できるテンプレート一覧はmake list-templatesで確認できます。

make list-templates
Available templates: cowboy_http cowboy_loop cowboy_rest cowboy_ws gen_server ranch_protocol supervisor

hello_handlercowboy_httpをベースにしたいので、下記のコマンドを実行します。

make new t=cowboy_http n=hello_handler

src/hello_handler.erl が新しく生成されました。

リクエストはhandle関数で処理されます。

デフォルトのhandle関数は何もしないので、処理をを追加し、「Hello Erlang!」をレスポンスするようにします。

handle(Req, State=#state{}) ->
    %% cowboy_req:reply はレスポンスを生成します
    %% cowboy_req:reply( ステータスコード, ヘッダー, レスポンスボディ, 元のリクエスト変数 )
    {ok, Req2} = cowboy_req:reply(200,
        [{<<"content-type">>, <<"text/plain">>}],
        <<"Hello Erlang!">>,
        Req),
    {ok, Req2, State}.

ソースファイルをコンパイルする。

make

hello_erlangアプリケーションを起動する。

erlang.mkmake shellコマンドでErlangのシェルにアプリケーションを起動できます。 make shellを使うことで依存アプリケーションのパスは自動的設定されますので、開発の時には便利です。

make shell

Erlangのシェルが起動されたが、hello_erlangはまだ動いてないです。 下記のコマンドでhello_erlangアプリケーションを起動します。 application:ensure_all_startedを使うことで依存アプリケーションは自動的に起動されます。

> application:ensure_all_started(hello_erlang).

ブラウザーでhttp://localhost:8080/を開けると「Hello Erlang!」が表示されます。

Cowboyサーバーを起動できました!

ファイルを自動的にコンパイルし、効率をアップ!

Erlangはコンパイル言語なので、ソースを変更する度にファイルをコンパイルする必要があります。 開発や実験の再は都度コンパイルをするのは負荷がが多いため、自動的にソースをコンパイルする方法を紹介します。

tddreloaderモジュールを利用して、自動的に変更されたファイルをコンパイルして、シェルにリロードする。

Makefileを下記のように変更します

PROJECT = hello_erlang
DEPS = cowboy
SHELL_DEPS = tddreloader
include erlang.mk

make shellコマンドを実行するとtddreloaderが自動的にダウンロードされ、プロジェクトの依存に追加します。

make shell

Erlangシェルからtddreloaderを起動する。

> tddreloader:start().
> application:ensure_all_started(hello_erlang).

src/hello_handler.erlを変更してみるとシェルに下記のメッセージが表示します

Compiling "src/hello_handler.erl" ... succeeded (hello_handler)
Reloading hello_handler ... version 312343512379116245493915842374805693179 ok.
======================== EUnit ========================
module 'hello_handler'
  There were no tests to run. 

ファイルが自動的にコンパイルされ、さらにテストがあれば、テストも実行されます。

ブラウザーをリロードすると結果が変わります!

tddreloaderを自動的に起動する

Makefileを下記のようにすると自動的にtddreloaderを起動することができます。

PROJECT = hello_erlang
DEPS = cowboy
SHELL_DEPS = tddreloader
SHELL_OPTS = -s tddreloader start
include erlang.mk

リリースを作成する

make shellは開発の時に便利ですが、開発が終わってリリースを作りたい時にerlang.mkで簡単に作れます。

Erlangでは複数なリリースツールがありますが、erlang.mkでデフォルトに利用されているrelxを使って、リリースを作ります。

make bootstrap-rel

このコマンドでrelフォルダーとrelx.configファイルは生成されました。

リリースを生成するにはmakeコマンドを実行します。

make

最後に、次のコマンドでリリースを起動できます。

./_rel/hello_erlang_release/bin/hello_erlang_release start

リリースを止める時はstartstopに変えればいいです。

./_rel/hello_erlang_release/bin/hello_erlang_release stop

またconsoleでアプリケーションを起動して、Erlangシェルを開きます。

./_rel/hello_erlang_release/bin/hello_erlang_release console

.relフォルダーをサーバに持っていけば、同様にリリースを起動できます。

Observerを使ってみる

ErlangにObserverという便利なツールがあります。 Observerを使って、Erlang VMの様々な情報を確認できます。

Erlangシェルに下記コマンドを実行しますとObserverを利用できます。

> observer:start().

Erlang VMの情報

Erlang VMの負荷チャート

Hello Erlangアプリケーションを確認

Hello Erlangプロセスを確認