Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
running web app on elixir
Next

6

Share

Phoenixを使った案件でリリースまでに起きた問題と対応

tokyo.ex 2

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

Phoenixを使った案件でリリースまでに起きた問題と対応

  1. 1. Phoenixを使った案件で リリースまでに起きた問題と対応 雪岡 重信 @ndruger
  2. 2. 自己紹介 ● 所属: 株式会社ACCESS ● 担当: Webフロントエンド・Webバックエンド・インフラ
  3. 3. プロジェクト ● 2015/7に開始。2015/12にファーストリリース ● Webバックエンド ○ 言語: Elixir ○ フレームワーク: Phoenix ● Webフロントエンド ○ 設計: SPA ○ 言語: EcmaScript 2015 ○ ライブラリ: React ○ パッケージ管理: Webpack
  4. 4. AWS 構成 Browser ELB S3・CloudFront Smart Phone Application Baas DB: MongoDBApplication Server Phoenix
  5. 5. 問題1: 欲しい機能のライブラリが無い 問題: 繰り返しの日時の検索の機能があるので、WebAPIで繰り返しを表現するフォー マットとして iCalender(RFC2445 or RFC5545)を使いたいが、その時点ではElixirのラ イブラリがなかった 対応: Webバックエンドでは、iCalenderフォーマットのうち、案件で必要なケースのみをパース するコードを書いて対応。 Webフロントエンドでは、iCalenderに対応したrruleを利用。
  6. 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も利用できる
  7. 7. Phoenixでプロジェクト開始!
  8. 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. 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. コンパイル時の型チェックが無い
  10. 10. 問題3. 500エラー(1)の発生 AWS CloudWatchからELBの5xxエラー検出のメールが来た。 動作確認用サーバのログを確認すると、新規に実装したWeb APIが、単純な内容の HTTPリクエストに対して500エラーを起こしていた 「おかしい。私の実装したプログラムにバグなんてあるはずがない。Web APIのユニット テストで正常・異常ケースを書いているので、単純なリクエストで発生するバグはないは ずなのに・・・」と思ったら、ローカルで試すと再現しない
  11. 11. 依存ライブラリの追加時に mix.exs の deps/0 には追加したが application/0 の applications への追加が漏れていた・・・ その場合の挙動は ● ”mix test”ではエラーにならない ● exrmなどでリリースパッケージ化したものを動作させた場合に、モジュールを呼び 出している場所がエラーを起こす そのため、リリースパッケージで動作させた動作確認サーバでしか問題が起きなかった 問題3. 500エラー(1)の原因
  12. 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.
  13. 13. AWS CloudWatchからELBの5xxエラー検出のメールが来た。 動作確認用サーバのログを見ると、特定のWebAPIへのリクエストで発生するわけでは なく、ある程度の期間ごとに、異なるWebAPIへのリクエストでエラーで発生している模 様。 ローカルではすぐには再現できなかった。 どうしよう。 問題4. 500エラー(2)の発生
  14. 14. Elixir/Erlangならば大丈夫。 Elixir/Erlangでは動作中のアプリに対してリモートコンソールで簡単にアタッチが可能。 また、Erlangではプロダクション環境向けに安全な問題解析ができるライブラリのRecon がある。 動作確認サーバで動作しているErlangアプリケーションにアタッチして、プロセスの数を 確認すると 300個程度と起動時より多めだった。 recon_traceで関数をトレースしていくと、外部へのHTTPS通信に利用している HTTPoison が内部で使っているErlangライブラリの Hackney でConnection Poolが上 限まで使われている。 問題4. 500エラー(2)の原因調査
  15. 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
  16. 16. リリース後に発生していたら、センサーのデータの受信に失敗して、センサーのデータが 消えていた? → 大丈夫。IoTのデータ送信では消えてはいけないデータは下記のように扱う場合が 多い 1. センサーが、取得したデータを不揮発メモリーのキューに入れる 2. データ送信時にキューの先頭のデータを読み込み、サーバに送信する 3. サーバが成功を返した場合) センサーはデータをキューから削除する 4. サーバがエラーを返した場合) キューから削除しない。一定時間持ってから2に戻 る MQTTでのQoS1相当の挙動 問題4. 500エラー(2)がもしリリース後に起きてたら
  17. 17. まとめ: 教訓 万一の障害に対して備えておくと、安心できるソフトウェア開発ライフを過ごせます ● 自動監視の対象を増やしておく ○ 死活監視・リソース監視などに加えて、ステータスコード・エラーログ・レスポンスタイムなども忘れず に監視対象にしておく ● サービス初期にはログ出力の対象を増やしておく ○ 簡単に問題を再現できるだけの情報が欲しい ● 障害が起きても致命的なデータが消失しない設計にする ● デバッグ方法を調べておく ○ リモートコンソール、 Observer、Reconなどを使っておく ● Erlangを勉強しておく ○ Elixirのデバッグツールは少なく、運用のための情報も少ない ○ デバッグ時には結局 Erlangで書かれたソースを読んだり修正したりする必要がある
  • masarukojo

    Nov. 9, 2017
  • piacere_ex

    Oct. 9, 2017
  • EisukeKuwahata

    Jun. 7, 2016
  • pmonster

    May. 23, 2016
  • KazuhiroSasaki

    May. 23, 2016
  • KanSakamoto

    May. 23, 2016

tokyo.ex 2

Views

Total views

3,140

On Slideshare

0

From embeds

0

Number of embeds

1,468

Actions

Downloads

0

Shares

0

Comments

0

Likes

6

×