Upload
takeuchi-yuichi
View
1.430
Download
4
Embed Size (px)
Citation preview
Shinjuku.rb #29 LT?タケユー・ウェブ竹内雄一
Shinjuku.rb #29 LT?
• 竹内 雄一@大宮
• フリーランス WEBエンジニア(受託メイン設計~運用)
• Ruby on Rails 1.1ぐらいから
• そのほかCMS AWS 鯖管など
• むかしつくったもの• rack-ketai … jpmobileがrack対応してなかった時のやつ
• KetaiPost … Movable Typeでメール投稿するやつ
お世話になった本たち@takeyuweb
使ったことがあるgemの話をします
使ったことがあるDaemon関係gem
• activejob• actioncable• aws-flow • serverengine• god• backgroundrb• sidekiq• resque• delayed_job• sucker_punch
いろいろありました。
ActiveJob
• 「Active Jobは、ジョブを宣言し、それによってバックエンドでさまざまな方法によるキュー操作を実行するためのフレームワークです。」
使ったことある人挙手みんなあるよね?あったらこの話いみないね
What’s ActiveJob ?
• Rails標準のキューイング仕様(4.2~)
• 時間のかかる処理を裏でやるやつ
• これまでいろんなgemがありそれぞれのやり方を覚える必要があった• BackgrounDRb / Resque / Delayed Job / Sidekiq / Sucker Punch etc…
• 標準があることで書き方を統一できて嬉しい
ActiveJobはアダプタ
• ActiveJob自体にジョブを記憶したり処理する機能はない
• 他のキューイングシステムとRailsをつなぐ• キューイングシステムがなんであっても同じように書ける
# ジョブの作成class MailMagazineDeliveryJob < ActiveJob::Base
queue_as :defaultdef perform(post)
# 後で実行したい処理をここに書くend
end
# ジョブを登録したいときMailMagazineDeliveryJob.perform_later(post)
ActiveJobのバックエンドシステム
• 実際のジョブキューへの出し入れは他のを使う
• ジョブキューのデータストアもそれぞれなので、用途や目的に応じて使う
• (インラインライナー)• バックエンドを指定しないとき。その場ですぐ実行しちゃう。見せかけだけ。
• Sidekiq• データストアとしてRedisが必要
• Sucker Punch• データストア不要
• その他ResqueやDelayedJobなど昔からあるキューイングシステムをバックエンドとして利用できる!
ActiveJobのバックエンドプロセス
• 一部の例外を除き、バックグラウンド処理用のdaemonプロセス必要• 例外
• インラインライナー• 見せかけだけなので。
• Sucker Punch• 他のデータストアやバックグラウンドプロセスなしに、アプリケーションのプロセスだけで、非同期処理ができちゃうのがウリ。
• バックグラウンドとしてSidekiqを選択したなら• sedis-server• sidekiq -C config/sidekiq.yml
こないだの案件の場合
• AWS• Redisの管理をしたくない
• ワーカーを動かすインスタンスのスケールアウトを可能に
• Amazon Simple Queue Service (SQS)• ジョブキューの出し入れ、排他制御
• 追記ジョブ完了後メッセージを削除しないと、可視性タイムアウト終了後再度落ちてくる
• ジョブキュー専用に設計されてて使いやすく堅牢• Amazon Lambdaなどとの連携も
• フルマネージド• スケールアウトが容易
ActiveJobとAmazon SQSをつなぐ
ActiveJobとAmazon SQSをつなぐ
• aws sdkを使ってアダプタを自作した• Active Job meets Amazon SQS
http://takeyuweb.hatenablog.com/entry/2014/12/11/043515
• ジョブをSQSから取り出してActiveJobのジョブを実行するスクリプトを書く
• job_data = JSON.parse(message[:body])ActiveJob::Base.execute(job_data)
• ただのスクリプトなので、このままでは落ちたら終わり• 永続(サービス)化が必要
※今ならshoryukenというSQSを利用したgemがあるのでそれを使えば多分楽(永続化もある)
スクリプトのサービス化
• プロセス管理ツール• while(true)な感じのスクリプトをサービス化するためのツール(ざっくり
• ロギング、死活監視(落ちてたら起動し直すとか)
• 設定ファイルに起動したいスクリプトや環境変数などを設定して、管理ツールのプロセスを起動すると後は勝手にやってくれる
• daemontools• 古典
• Supervisord• 設定ファイルが割と簡単、yumとかでも入る
• God• 設定ファイルがruby• プロセスのメモリ使用量が一定以上になったら再起動とか、プログラマブルで高度な機能あり
• ググラビリティ低い
• Foreman• Herokuで使うやつ
永続化させたいスクリプトについて
• フォアグラウンドで動くもの(をGodの裏で動かすことになる)
• while(true)なやつ• 色々自前でやる
• Signal.trap(:TERM)とか
• プロセスの実行ログの書き出しやログローテーションとか
• ServerEngine• 「Unicornのような強固なマルチプロセスサーバーを実装するためのフレームワーク」
• ロギング、プロセス管理、ワーカープロセスの並列化 …• うちは複数のスクリプトをそれぞれ永続化したかったので
• フォアグラウンドで動くただのスクリプトにし、別のでプロセス管理
• シグナルの処理やロギングだけ使いたい
ServerEngineでGodで管理するスクリプトを
• プロセス管理はGod(またはSupervisorなど)でやるので要らない
• マルチプロセスは今のところ使ってない(必要になれば考える
• フォアグラウンドで動かしたい
• ロギングはしたい
se = ServerEngine.create(nil, ActivejobWorker, # SQSからデータを取り出してActiveJobジョブを実行するやつ{
daemonize: false, # フォアグラウンドで動かす(trueだとバックグラウンドに)supervisor: false, # プロセス管理機能はなしlog: Rails.root.join(‘log/activejob_worker_server.log’), # 実行ログの書き出し先log_rotate_age: 5, # 5世代分保持log_rotate_size: 1*1024*1024 # 1MBごとにローテート
})se.run
Godの設定
# config/god.rb
ROOT_DIR = ENV['RAILS_ROOT'] || File.expand_path(File.join(File.dirname(__FILE__), '..'))God.pid_file_directory = File.expand_path(File.join(ROOT_DIR, 'tmp/pids')) + '/'
God.watch do |w|w.name = 'activejob_worker_server'w.dir = ROOT_DIRw.uid = 'deploy'w.env = ENV.to_h# 実行するServerEngineなスクリプトw.start = "bundle exec ruby bin/activejob_worker_server“
# STOPコマンド後待機する秒数これを超えたら強制終了w.stop_timeout = 60.seconds# その他メモリ管理とかいろいろ
end
デプロイ
• AWS OpsWorks• カスタムCookbookを書く
• LayerをみてWorker用のやつなら以下• godなどインストール
• デプロイ後の god terminate & god -c ..
まとめ
• ActiveJob使った
• バックエンドにAmazon SQSを使った
• ジョブ実行スクリプトにはServerEngine(の一部機能)を使った
• プロセス管理にはGodを使った
おまけ
• Rails5に搭載される?されない?ActionCableでも通常のRailsアプリとは別にWebSocket用のプロセスを起動する必要がありました。
• Qiitaに記事書いたAction Cable + Flux + React でリアルタイムチャットデモを作ってみたhttp://qiita.com/takeyuweb/items/0c421534e5ad1d2657f7