- 更新
2014-11-20
- バージョン
0.0.5
- 作者
@voluntas
- URL
実際に仕事で Erlang/OTP を使う際に必要になるポインタをまとめることにした。
躓きながら進むのも良いが、まずはポインタに沿って進みその後、色々考えて進むのが良いだろう。
検索すればやまほど出てくるので、基本的には「まとまってる」という点でのポインタを上げる事にする。
書籍に関してはオーム社の プログラミング Erlang で問題ない。
Erlang/OTP の父が書いたこともあり、かなり基本を中心としてしっかりかかれている。ただしかなり古いので、あくまで基本的なところだけを参考にするべきだ。最新の Erlang/OTP (R16B03-1) では動かないところもあったりする。
もう一つ書籍では無いが Learn you some Erlang for great good! の日本語訳 もとても良い。
Learn you some Erlang for great good! は Heroku で働いている Fred が書いた。Heroku はルーティングメッシュやログ周りを Erlang/OTP で実装しているヘビーユーザだ。OTP 部分もかなり詳細に書かれているため、これを読めば一通り Erlang/OTP の内容が理解できるだろう。
このレベルの内容が日本語で読めるのは本当にありがたい。皆 @ymotongpoo に感謝すると良い。
注意点として、この本はライブラリ等の解説は含まれていない。
また Erlang のドキュメントを一部翻訳したモノも紹介しておこう。
Erlang Efficiencyガイド バージョン自体が古いので、今は使われていないものもある。ただ、幅広い範囲で知識を得られる。これを読んでから英語版を読めば理解しやすいだろう。
かなりあるが、まずはなんといっても Programming Erlang: Software for a Concurrent World の 2nd だろう。これは プログラミング Erlang の原著である。
最新版はまだ出ていない R17 の機能である map なども含まれている。実は rebar の説明も入っていたりする。
次は少し古いが Erlang and OTP in Action と Erlang Programming だろう。Erlang and OTP は OTP についてかなりわかりやすく書いてあるのでオススメだ。 Erlang Programming は EUnit などテストの話もしっかり書いてある。
もっと入門っぽいのが欲しければ Introducing Erlang もある。ただこれで学べるのは基本的に プログラミング Erlang に書いてある、日本語で読める文献があるのであまり読む機会はなさそうだ。
あとはドキュメントがかなり有用だ。Erlang/OTP のドキュメントはとてもよく出来ている。私はランチャーの検索対象に入れて、ローカルで検索して使っている。
ドキュメントは Erlang/OTP R16B03-1 で参照可能だ。
海外の情報は多すぎて書き切れない、検索すれば基本的にはぶつかると思うので、ここでは割愛。
基本は Emacs を使うべきだ。なぜならば Erlang/OTP のソースコードパッケージに erlang.el がふくまれているからだ。
基本的に Emacs 以外はオススメ出来ないのだが、残念ながら宗教上の理由でそれ以外の人のためにも紹介しておく。
私は残念ながら VIM なので Emacs の恩恵は受けられない。私はこの辺とオレオレ拡張を使っている。
IDE が欲しいなら IntelliJ がオススメだ。このプラグインの作者は IntelliJ の中の人だったりする。
じつは出来もかなりイイ。
Standalone Erlang IDE という名前からもかなり期待が持てる。メールするとバイナリが貰えたりするらしい。
今人気の Sublime Text 向けも存在する。モダンな人はコレを使うと良い。
開発環境も Windows 版があることもあり、幅広い。
本番へのデプロイはほとんどの場合、これだろう。というか Windows Server にデプロイした話を聞いたことが無い。なので実は開発も Linux ベースでやると良い。
多くの開発者はディストリとして Ubuntu を選択しているようだ。
こちらも多いが、実際本番では使われないので開発専用。Halfword が使えなかったりと色々不満がある。
ただ、まぁ困ることはほとんど無い。
未経験なので何とも言えないのだが、ちゃんと Windows バイナリも用意されている Erlang/OTP です。
基本的にはソースコードからのインストールをオススメするが、Kerl を使ったり、Erlang Solutions からパッケージでもインストールできる。
さらに Mac であれば MacPorts や Homebrew でインストールすることも可能だ。ここでは時前ビルドを紹介する。
kerl は複数の Erlang/OTP を管理してくれるツールだ。
日本語での解説があるのでコレを読めば大丈夫だろう。
http://qiita.com/tatsuya6502/items/f15da8ea6e793c5038a2
もし Java との接続を考えている場合は以下のサンプルは使えないので注意して欲しい
./configure --enable-smp-support \
--enable-m64-build \
--enable-native-libs \
--disable-sctp \
--enable-threads \
--enable-kernel-poll \
--enable-hipe \
--without-javac
hipe や native-libs は有効にしてもデメリットになることは無いので採用することにしている。
apt-get や yum でインストールが可能だ。windows や mac のバイナリも存在する。
https://www.erlang-solutions.com/downloads/download-erlang-otp
ビルドツールについては主に二種類ある。 rebar と erlang.mk だ。
rebar で良いだろう。つい先日 2.2 が出たこともあり落ち着いている。
rebar のコンパイルはとても簡単だ。
$ git clone git@github.com:rebar/rebar.git
$ cd rebar
$ make
あとは rebar のバイナリが出来たのでそれを PATH が通ってる場所に置けば良い
rebar は compile から xref まで様々な機能が対応している。リリースもこれ一つで出来る。
自動ビルドツールもオススメしておきたい。Erlang/OTP 対応は多いが、時前のビルドが出来るようになる。
circle.yml:
dependencies:
pre:
- bash ./install-otp_src_R16B03.sh
cache_directories:
- otp_src_R16B03
test:
pre:
- ln -s ~/<application-name> ~/bin/erl
override:
- make
install-otp_src_R16B03.sh:
set -x
set -e
if [ ! -e otp_src_R16B03/bin/erl ]; then
curl -O http://www.erlang.org/download/otp_src_R16B03.tar.gz
tar xzf otp_src_R16B03.tar.gz
cd otp_src_R16B03
./configure --enable-smp-support \
--enable-m64-build \
--enable-halfword-emulator \
--disable-native-libs \
--disable-sctp \
--enable-threads \
--enable-kernel-poll \
--disable-hipe \
--without-javac
make;
fi
Erlang/OTP が無ければコンパイルしてインストールしてくれる。
rebar を Makefile でラッピングするのが Erlang/OTP 流らしい。難しい事はやっていないので、参考にして欲しい。
Makefile:
.PHONY: all compile deps clean test devrel rel
REBAR_CONFIG = rebar.config
APP_NAME =
all: clean deps test
deps: get-deps update-deps
@./rebar -C $(REBAR_CONFIG) compile
update-deps:
@./rebar -C $(REBAR_CONFIG) update-deps
get-deps:
@./rebar -C $(REBAR_CONFIG) get-deps
compile:
@./rebar -C $(REBAR_CONFIG) compile skip_deps=true
@./rebar -C $(REBAR_CONFIG) xref skip_deps=true
devrel: rel
$(foreach dep,$(wildcard deps/*), rm -rf dev/$(APP_NAME)/lib/$(shell basename $(dep))-* && ln -sf $(abspath $(dep)) dev/$(APP_NAME)/lib;)
rm -rf dev/$(APP_NAME)/lib/$(APP_NAME)-*
rm -rf dev/$(APP_NAME)/lib/$(APP_NAME)
mkdir dev/$(APP_NAME)/lib/$(APP_NAME)
ln -sf $(abspath ebin) dev/$(APP_NAME)/lib/$(APP_NAME)/ebin
ln -sf $(abspath priv) dev/$(APP_NAME)/lib/$(APP_NAME)/priv
rel: compile
mkdir -p dev
mkdir -p deps
(cd rel && rm -rf ../dev/$(APP_NAME) && ../rebar generate && ../rebar generate target_dir=../dev/$(APP_NAME))
test: compile
rm -rf .eunit
@./rebar -C $(REBAR_CONFIG) eunit skip_deps=true
clean:
@./rebar -C $(REBAR_CONFIG) clean skip_deps=true
distclean: clean
@./rebar -C $(REBAR_CONFIG) clean
@./rebar -C $(REBAR_CONFIG) delete-deps
rm -rf dev
dialyze-init:
dialyzer --build_plt --apps erts kernel stdlib mnesia crypto public_key snmp reltool
dialyzer --add_to_plt --plt ~/.dialyzer_plt --output_plt $(APP_NAME).plt -c .
dialyzer -c ebin -Wunmatched_returns -Werror_handling -Wrace_conditions -Wunderspecs
dialyze: compile
dialyzer --check_plt --plt $(APP_NAME).plt -c .
dialyzer -c ebin
rel や dialyzer 周りは後ほど説明する。基本的には compile と get-deps がメインとなる。get-deps は依存関係の解決、compile はコンパイルと xref を呼び出す。
xref はクロスリファレンスで「存在しない関数」を呼び出したとき教えてくれる。
Python のライブラリだが、簡単に言えば「ファイルが更新されたら」している処理を行ってくれる。
$ watchmedo shell-command --patterns="*.erl;*.hrl" --recursive --wait --command="rebar compile xref eunit skip_deps=true" src include test
上記のように設定しておけば毎回コンパイルとテストが走る。
OMake の -P と似たような機能だ。
まず Web アプリの場合は Cowboy を選択するのが無難だ。
ただしテンプレートも含めた開発となると難しい、あくまで API サーバを開発する前提が良いだろう。
HTTP クライアントは色々あるが Hackney が定番だ。プール機能も保持している上に、開発が活発だ。
cowboy_client という experimental なものもあるが、まずは Hackney を使っておくのが無難だろう。
そうなるとシリアライズする JSON ライブラリが重要になってくる。
日本後を扱うか、扱わないかで変わるが、基本的には jsx か jsonx の二択になる。
jsx は日本後の取り扱いが簡単なので、まずは jsx で開発して行き、将来的に速度が必要になったら jsonx に変えて行くのが良いだろう。
ちなみに jsx は pure Erlang で jsonx は NIF (C 拡張) だ。
- MySQL
- Postgres
- Redis
- Riak
メジャーなモノ以外はあまりないので自作することをお勧めする
Erlang では頑張らないで素直に JSON を返しましょう ...
reloader と sync の二つがある。シンプルな reloader を好んで使っている。
コンパイルをすることで自動で読み込んでくれる機能だ。
$ erl -s reloader
これを使う事でわざわざ c(spam). という感じで再コンパイルする必要は無い。
Dialyzer は静的解析ツールである。導入時にコストがかかることもあるのだが是非導入するべきだ。
Erlang/OTP で製品開発を行う際に一番の障壁となるのが「導入」だ。
「開発言語が使える人が居ない」などの理由で断られることがある。
ちなみに、これは至極まっとうな意見だと考えている。
そもそも Erlang/OTP をネットワークサーバを書く用途以外で使うので無ければやめるべきだ。
ウェブアプリであれば、余地はあるかもしれない。ただ API サーバに限定すべき。
ウェブアプリでも JS 側でテンプレートを持ったりと昨今の JS 側の充実を考えると、 HTTP API サーバとしての活躍の場は徐々に広がってきているようだ。
実は並列をメインとしている場合は、ほとんどの場合で Golang で書いた方がよい可能性が高い。
そもそもネットワークサーバではなく何かしらのツールを作ろうとしているのではないだろうか。
まずは社内で Golang と Erlang/OTP の比較をするべきだ。 本当に Erlang/OTP である「必要があるのか?」という事は大きなポイントだろう。
Erlang/OTP はネットワークサーバの DSL だと思って良い。 そのため得意では無い場面で使う場合はかなりのリスクがある。
さらにライブラリも 1 から開発する必要性も出てきたりする。
ライブラリ開発が難しい場合はそもそも Erlang/OTP などの人口が少ない言語を選択するのは懸命ではない。
もしそれでも開発したい場合は、アピールが必要になる可能性が高い。
主に、実績を聞かれると思う。そのときは以下のように答えれば良い。
- LINE のメッセージサーバは Erlang/OTP です
- WhatsApp のプラットフォームは Erlang/OTP です
- ドワンゴのニコニコ動画の生放送部分の一部は Erlang/OTP です
- League of Legends のチャットサーバは Erlang/OTP です
有名どころはこの辺か。WhatsApp を知らない人はそうそういないだろう。もし居たとしたら 4.5 億ユーザがいる LINE ですと紹介すればいい。
上司がもしゲーム好きなら League of Legends のユーザ 7500 万人のチャットを支えていますよ。秒間 11000 メッセージを処理しています、というのもいいだろう。
これで落ちない場合は、基本的には勝手に実装して「とりあえずプロトタイプを Erlang/OTP で作ってしまいました」が良いだろう。
それがソースコードが比較的短く、性能が出るのであれば説得材料になり得る。
もはや AWS が存在しているためスケールアウトが容易に出来る時代が来てしまった。ボトルネックはデータベースというパターンが多い。
しかし、今後は費用節約のためにスケールアップが求められる可能性がある。
前述した WhatsApp は数百台のサーバで 4.5 億ユーザを支え、秒間 7000 万リクエストを捌いているとのことだ。
今後、Erlang/OTP は スケールアップ という目的で使われることは多いかも知れない。