More Related Content Similar to Phoenixを使った案件でリリースまでに起きた問題と対応 Similar to Phoenixを使った案件でリリースまでに起きた問題と対応 (20) Phoenixを使った案件でリリースまでに起きた問題と対応6. ライブラリを探す場合の注意点
● 探す場合はawesome elixirだけではなく、awesome erlang & hex.pmも調べる
○ Elixirのライブラリでも載ってないものがある
○ ErlangのライブラリならElixirから簡単に使える
● 動的にAtomを生成するライブラリに注意
○ AtomはGCの対象外
○ 値が限定されないユーザー入力をそのようなライブラリの入力にすると、そのうち ”no more index
entries in atom_tab (max=1048576)”が出て「Beam」がCrashする
● 場合によってはPortとかNIFも利用できる
8. ● コーディングルール
○ niftyn8/elixir_style_guide: A community driven style guide for Elixir
○ 今の案件では Credo をルール&ツールとして利用
● Brunch から Gulp&Webpack に変更
● 多言語対応はWebバックエンドではなくWebフロントエンド側でi18nextで対応
● ユニットテスト実行時に、対象の関数の正常処理・エラー処理のコードの実行を確
認したいので coverex でカバレッジを取得。ただし、マクロ部分はチェック対象にな
らない
● サービス初期はサーバのログを多めに設定
○ http://qiita.com/snowball/items/10eaf0c9e0fd39187019
○ 念のためリクエストBodyも出力しておこう(伏線)
本格的に開始すると・・・決めることは多い
9. @spec を書いて、Erlangの Dialyzer を利用した Dialyxir を使ってチェック。
結構スルーされるパターンがあるが、コーディング後にたまにこれでバグに気づく。無い
よりは断然いい。
今の案件では Dialyze を利用。@specで関数名・引数名をもう一度書くのが面倒なの
で、Macro Utility Library の Croma のdefunを利用。
$ mix dialyzer | egrep -v "put_new_layout|put_layout|The call _@4:'params'()
|router.ex:[1-9]+: The call _@[1-9]:" | grep -v '_@' | grep -v 'Elixir.Phoenix.
Controller.Pipeline' | grep -v phoenix_controller_pipeline | grep -v 'Elixir.Phoenix.
Router.Helpers # Phoenix依存のワーニングなどを排除
問題2. コンパイル時の型チェックが無い
11. 依存ライブラリの追加時に mix.exs の deps/0 には追加したが application/0 の
applications への追加が漏れていた・・・
その場合の挙動は
● ”mix test”ではエラーにならない
● exrmなどでリリースパッケージ化したものを動作させた場合に、モジュールを呼び
出している場所がエラーを起こす
そのため、リリースパッケージで動作させた動作確認サーバでしか問題が起きなかった
問題3. 500エラー(1)の原因
12. 問題3. 500エラー(1)の対策
$ mix help compile.app
2度と問題が起きないように、deps/0 から dev/test only のものを除いて取得する関数
を作り、それに logger を追加したものを applications に設定するようにmix.exsを修
正。大体こんな感じ
• :applications - all applications your application depends on at
runtime. For example, if your application depends on Erlang's :crypto, it
needs to be added to this list. Most of your dependencies must be added as
well (unless they're a development or test dependency). Mix and other tools
use this list in order to properly boot your application dependencies
before starting the application itself.
15. 問題4. 500エラー(2)の原因と対策
Hackneyのコードを読むと、レスポンスに対して hackney.body/1 を呼びださないと
Conenctionが解放されず、Connection Poolに戻らないようになっている
HTTPoisonでは、304, 204のレスポンスに対しては、レスポンスのBodyがないために、
hackney.body/1 を呼んでいなかった。
HTTPoisonを暫定修正して利用することで解決。
後でHTTPoisonにPullRequestしようと思ってたら、後日修正されていた。
https://github.
com/edgurgel/httpoison/commit/8d6d0a5207219d57390b603f53919a8b488ea0fe
17. まとめ: 教訓
万一の障害に対して備えておくと、安心できるソフトウェア開発ライフを過ごせます
● 自動監視の対象を増やしておく
○ 死活監視・リソース監視などに加えて、ステータスコード・エラーログ・レスポンスタイムなども忘れず
に監視対象にしておく
● サービス初期にはログ出力の対象を増やしておく
○ 簡単に問題を再現できるだけの情報が欲しい
● 障害が起きても致命的なデータが消失しない設計にする
● デバッグ方法を調べておく
○ リモートコンソール、 Observer、Reconなどを使っておく
● Erlangを勉強しておく
○ Elixirのデバッグツールは少なく、運用のための情報も少ない
○ デバッグ時には結局 Erlangで書かれたソースを読んだり修正したりする必要がある