20
Shinjuku.rb #29 LT? タケユー・ウェブ 竹内雄一

Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

Embed Size (px)

Citation preview

Page 1: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

Shinjuku.rb #29 LT?タケユー・ウェブ竹内雄一

Page 2: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

Shinjuku.rb #29 LT?

• 竹内 雄一@大宮

• フリーランス WEBエンジニア(受託メイン設計~運用)

• Ruby on Rails 1.1ぐらいから

• そのほかCMS AWS 鯖管など

• むかしつくったもの• rack-ketai … jpmobileがrack対応してなかった時のやつ

• KetaiPost … Movable Typeでメール投稿するやつ

お世話になった本たち@takeyuweb

Page 3: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

使ったことがあるgemの話をします

Page 4: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

使ったことがあるDaemon関係gem

• activejob• actioncable• aws-flow • serverengine• god• backgroundrb• sidekiq• resque• delayed_job• sucker_punch

いろいろありました。

Page 5: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

ActiveJob

• 「Active Jobは、ジョブを宣言し、それによってバックエンドでさまざまな方法によるキュー操作を実行するためのフレームワークです。」

Page 6: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

使ったことある人挙手みんなあるよね?あったらこの話いみないね

Page 7: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

What’s ActiveJob ?

• Rails標準のキューイング仕様(4.2~)

• 時間のかかる処理を裏でやるやつ

• これまでいろんなgemがありそれぞれのやり方を覚える必要があった• BackgrounDRb / Resque / Delayed Job / Sidekiq / Sucker Punch etc…

• 標準があることで書き方を統一できて嬉しい

Page 8: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

ActiveJobはアダプタ

• ActiveJob自体にジョブを記憶したり処理する機能はない

• 他のキューイングシステムとRailsをつなぐ• キューイングシステムがなんであっても同じように書ける

# ジョブの作成class MailMagazineDeliveryJob < ActiveJob::Base

queue_as :defaultdef perform(post)

# 後で実行したい処理をここに書くend

end

# ジョブを登録したいときMailMagazineDeliveryJob.perform_later(post)

Page 9: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

ActiveJobのバックエンドシステム

• 実際のジョブキューへの出し入れは他のを使う

• ジョブキューのデータストアもそれぞれなので、用途や目的に応じて使う

• (インラインライナー)• バックエンドを指定しないとき。その場ですぐ実行しちゃう。見せかけだけ。

• Sidekiq• データストアとしてRedisが必要

• Sucker Punch• データストア不要

• その他ResqueやDelayedJobなど昔からあるキューイングシステムをバックエンドとして利用できる!

Page 10: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

ActiveJobのバックエンドプロセス

• 一部の例外を除き、バックグラウンド処理用のdaemonプロセス必要• 例外

• インラインライナー• 見せかけだけなので。

• Sucker Punch• 他のデータストアやバックグラウンドプロセスなしに、アプリケーションのプロセスだけで、非同期処理ができちゃうのがウリ。

• バックグラウンドとしてSidekiqを選択したなら• sedis-server• sidekiq -C config/sidekiq.yml

Page 11: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

こないだの案件の場合

• AWS• Redisの管理をしたくない

• ワーカーを動かすインスタンスのスケールアウトを可能に

• Amazon Simple Queue Service (SQS)• ジョブキューの出し入れ、排他制御

• 追記ジョブ完了後メッセージを削除しないと、可視性タイムアウト終了後再度落ちてくる

• ジョブキュー専用に設計されてて使いやすく堅牢• Amazon Lambdaなどとの連携も

• フルマネージド• スケールアウトが容易

Page 12: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

ActiveJobとAmazon SQSをつなぐ

Page 13: Shinjuku.rb #29 ActiveJobで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があるのでそれを使えば多分楽(永続化もある)

Page 14: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

スクリプトのサービス化

• プロセス管理ツール• while(true)な感じのスクリプトをサービス化するためのツール(ざっくり

• ロギング、死活監視(落ちてたら起動し直すとか)

• 設定ファイルに起動したいスクリプトや環境変数などを設定して、管理ツールのプロセスを起動すると後は勝手にやってくれる

• daemontools• 古典

• Supervisord• 設定ファイルが割と簡単、yumとかでも入る

• God• 設定ファイルがruby• プロセスのメモリ使用量が一定以上になったら再起動とか、プログラマブルで高度な機能あり

• ググラビリティ低い

• Foreman• Herokuで使うやつ

Page 15: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

永続化させたいスクリプトについて

• フォアグラウンドで動くもの(をGodの裏で動かすことになる)

• while(true)なやつ• 色々自前でやる

• Signal.trap(:TERM)とか

• プロセスの実行ログの書き出しやログローテーションとか

• ServerEngine• 「Unicornのような強固なマルチプロセスサーバーを実装するためのフレームワーク」

• ロギング、プロセス管理、ワーカープロセスの並列化 …• うちは複数のスクリプトをそれぞれ永続化したかったので

• フォアグラウンドで動くただのスクリプトにし、別のでプロセス管理

• シグナルの処理やロギングだけ使いたい

Page 16: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

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

Page 17: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

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

Page 18: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

デプロイ

• AWS OpsWorks• カスタムCookbookを書く

• LayerをみてWorker用のやつなら以下• godなどインストール

• デプロイ後の god terminate & god -c ..

Page 19: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

まとめ

• ActiveJob使った

• バックエンドにAmazon SQSを使った

• ジョブ実行スクリプトにはServerEngine(の一部機能)を使った

• プロセス管理にはGodを使った

Page 20: Shinjuku.rb #29 ActiveJobでSQS使ったのとその永続化についての話

おまけ

• Rails5に搭載される?されない?ActionCableでも通常のRailsアプリとは別にWebSocket用のプロセスを起動する必要がありました。

• Qiitaに記事書いたAction Cable + Flux + React でリアルタイムチャットデモを作ってみたhttp://qiita.com/takeyuweb/items/0c421534e5ad1d2657f7