More Related Content
Similar to elixir in production (20)
More from Tsunenori Oohara (18)
elixir in production
- 2. Agenda
• 発表の趣旨
• 自己紹介
– 最近のElixir事情
• 運用システム構成
– 利用しているツール/ライブラリ群
• 運用(負荷テスト)時のトラブル(とその地雷処理)
– 事例1.ログ
– 事例2.コネクションプール
– 事例3.アセット
– その他
• まとめ
- 6. 最近のElixir事情
• Programming Elixir 1.2 (Dave Thomas)
– https://pragprog.com/book/elixir12/programming
-elixir-1-2
– Β版
• Programming Phoenix
– https://pragprog.com/book/phoenix/programmin
g-phoenix
– Β版
- 7. 運用システム構成
• 広告配信API/ミニコンテンツ(ゲーム)
– F/W: maru( WAF/API DSL ) / Phoenix( WAF )
– DB: Redis( exredis + poolboy ) / Dynamo( ex_aws )
– Job: exq( + Sidekiq )
– 環境変数: dotenv
– Deploy: exrm / mina / asset_sync(自製)
– テスト: meck / power_assert
– 監視: sentry( raven-elixir ) / monit / 社内監視tool
– プロビジョニング: ansible( 自製galaxy-role )
– インフラ: AWS( EC2 / AutoScaling / ELB / S3 / CF )
- 8. 利用ツール/ライブラリ
• WAF:
– maru: https://maru.readme.io/
• 特徴:
– シンプル/Api DSL(grape like)
• 出来ない事:
– セッション管理/DBコネクション/テンプレート描画
– Phoenix: http://www.phoenixframework.org/
• 特徴:
– フルスタック(一通り揃ってる)/maruに比べると複雑
– アセットコンパイルはbrunch.ioを採用(node/npmが必要)
- 9. 利用ツール/ライブラリ
• DB:
– Redis:
• exredis: https://github.com/artemeff/exredis
• poolboy: https://github.com/devinus/poolboy
– Dynamodb:
• ex_aws: https://github.com/CargoSense/ex_aws
– MySQL/PostgreSQL/Mongodb/etc
• 弊社サービスでは採用していないのですが、恐らく
ecto: https://github.com/elixir-lang/ecto 一択
- 10. 利用ツール/ライブラリ
• Job:
– exq: https://github.com/akira/exq (+ sidekiq)
– http://qiita.com/ohr486/items/9db88866786ee8b
b89d9
• 環境変数:
– dotenv: https://github.com/avdi/dotenv_elixir
- 12. 利用ツール/ライブラリ
• 死活監視/自動再起動
– monit
• DB/ミドルウェア/外部サービスの監視
– supervisor(OTP)
• 言語の一部(OTP)として提供される
• きちんとチューニング/設定しておくと安心できる
– 半年の本番運用で2回程お世話になった
– パラメータの設定不備でプロセスが死亡する事象が発生した
が、自動的にプロセスを監視/再起動して、サービスを落す事
なく復旧/修正まで凌げた
- 13. 利用ツール/ライブラリ
• プロビジョニング:
– ansible + galaxy-role:
https://galaxy.ansible.com/detail#/role/2930
– Erlang/Elixir/Phoenix のバージョンupの頻度はか
なり早いので、自動化しておくべき
– ErlangとElixirのバージョンの相性がある為、両方
のバージョンを指定できると捗る
- 17. 事例1.ログ
• 検証:
– vmstatの結果: boが異常値
$ vmstat -a 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free inact active si so bi bo in cs us sy id wa st
2 0 0 6807288 45796 562724 0 0 21 1242 11712 5338 37 25 30 8 0
1 1 0 6807156 45796 562988 0 0 0 4528 28259 5784 15 15 51 20 0
1 1 0 6806908 45800 563184 0 0 0 4484 28252 5717 15 16 50 20 0
0 1 0 6806660 45796 563384 0 0 0 4548 28171 5843 15 16 50 19 0
2 0 0 6806412 45796 563584 0 0 0 4556 28003 5825 15 15 51 20 0
1 1 0 6806288 45796 563780 0 0 0 4484 28262 5787 15 16 50 20 0
1 1 0 6806040 45796 563984 0 0 0 4488 28604 5868 14 17 50 19 0
2 1 0 6805792 45796 564180 0 0 0 4472 28473 5888 13 18 50 19 0
1 1 0 6805668 45800 564384 0 0 0 4480 28193 5772 15 16 50 19 0
1 1 0 6805420 45796 564580 0 0 0 4472 28356 5746 14 17 50 20 0
2 0 0 6805420 45796 564784 0 0 0 4492 28445 5757 14 16 50 19 0
1 1 0 6805172 45796 564980 0 0 0 4504 28393 5787 15 16 50 20 0
1 1 0 6804924 45796 565184 0 0 0 4456 28411 5671 13 17 50 20 0
2 0 0 6804676 45796 565380 0 0 0 4488 28169 5786 14 15 51 20 0
1 1 0 6804428 45800 565576 0 0 0 4504 28053 5761 13 17 50 20 0
- 20. 事例1.ログ
• 対応
– 本番環境のloggerのbackendをconsoleから変更
– ※ ElixirのLoggerのbackendは公式にはconsoleし
か提供されていない
• https://github.com/elixir-
lang/elixir/tree/master/lib/logger/lib/logger/backends
• https://github.com/onkel-dirtus/logger_file_backend
• https://github.com/basho/lager
– logger_file_backendはカスタマイズに難ありだっ
たのでbackendを自前実装した
- 23. 事例2.コネクションプール
• 状況:
– 各種DBドライバのコネクション管理事情
• PostgreSQL/MySQL/MSSQL/SQLite3/MongoDB
– ecto: https://github.com/elixir-lang/ecto
– コネクション管理(内部的にはpoolboyで実装)を含む
• Redis
– exredis: https://github.com/artemeff/exredis
– クライアントのみ、コネクション管理は含まれない
• Dynamodb
– ex_aws: https://github.com/CargoSense/ex_aws
– APIベースなのでコネクション管理なし
– Read/Write Capacity Unitの設定で担保
- 26. 事例2.コネクションプール
• 対応:
– コネクション管理を含むRedisドライバを使用
• https://github.com/quarkgames/exredis_pool
• https://github.com/le0pard/redis_pool
• 問題点: コネクションプールの設定が貧弱/十分に
チューニングできない
– poolboyでコネクションプールを自前実装
• 参考: たのしいpoolboy(@hagiyatさん)
• http://qiita.com/hagiyat/items/a28683d01223bfc204d
9
- 29. 事例3.アセット
• Phoenixのアセットの参照:
– digest: 静的ファイルを圧縮してmanifestを作成
• phoenix.digest (mixコマンド)
• manifest.jsonに、圧縮前後のファイルパスのmapping
をJSON形式で出力する
– cache_static_manifest != true (config.exs)
• 静的ファイルを priv/static 以下から参照
– cache_static_manifest == true (config.exs)
• manifest.jsonをパースして、ets(ErlangのIn-memoryスト
レージ)にマッピング情報をストア
• 静的ファイル参照時に、圧縮後のファイルを参照させ
る
- 30. 事例3.アセット
• 改善前の手順
– 1. アセットの参照方法をmanifestに
– 2. 圧縮ファイルとmanifest.jsonを作成
• MIX_ENV=prod mix phoenix.digest
– 3. MIX_ENV=prod でアプリを起動
– 4. 2.のマッピング先(圧縮後ファイル)が参照
# config/prod.exs
config :my_app, MyApp.Endpoint,
http: [port: xxxx],
url: [host: “xxxx”],
cache_static_manifest: “priv/static/manifest.json”,
server: true
- 31. 事例3.アセット
• アセット参照の実体(static_path/2)
– Phoenix.Route.Helpers # static_path/2
• https://github.com/phoenixframework/phoenix/blob/
master/lib/phoenix/router/helpers.ex
– MyApp.Web # web ( web/web.ex )
• import MyApp.Router.Helpers
– static_path/2 がimportされて利用可能に
– View/css/javascript # static_path/2
• static_path/2 でアセットを参照
- 36. その他
• 地雷処理の為にやった事/必要だった事
– ドキュメント(英語)を読む
• 日本語の情報はまだまだ不足
– 実装コード(Elixir/Erlang)を読む
• Erlangの参照ライブラリを読むケースはそれなりにある
(ErlangのライブラリをwrapしただけのElixirライブラリ)
– awesome-elixir/awesome-erlangのチェック
• 他の実装ライブラリや、似た様な機能を探す際に便利、
定期的に追いかけておくと何かと捗る
- 37. その他
• 地雷処理の為にやった事/必要だった事
– 地雷処理できる人を増やす活動
• Erlangが読めるように
– Elixir独自の機能はありますが、やはりベースはErlangです
– ErlangをRubyのSyntaxで記述している感じ
• OTPの概念を理解できるように
– OTPの理解無しにElixirのアプリ運用はできない(と感じた)
• 関数型言語を理解する
– 社内勉強会(すごいE本/コップ本読書会)
– Erlangに自信が無い場合は、時雨堂さんにコンサ
ルをお願いすれば良いんじゃないでしょうか