RailsのActiveJobでSidekiqの代わりにSneakersを利用する

はじめに

Sidekiqは優れたバックグラウンド処理のためのgemです。しかしながら、後ろで動いているのがredisである以上、あまり多くの機能を求めることはできません。一部の機能はRubyのコードによって実装されており、Rubyの言語仕様に引きずられます。

そこで昨今、注目を浴びているのがSneakersです。こちらは後ろでRabbitMQと呼ばれるerlangで書かれたメッセージブローカーが利用されます。巷でメッセージブローカーと言えば、kafkaが有名ですが、RabbitMQもまた非常に優れたブローカーです。

という記事を読んだので、Sneakersを試してみました。

RabbitMQは過去に少しだけ触ったことがあったので、そのタフネス具合には何となく及びがつきます。殺されても殺されても必死に立ち上がってくるerlangのプロセスは、まるでピクミンのような愛らしさすら感じます。

正直、よほど忙しいシステムでない限り、kafkaを利用せずとも、RabbitMQで十分なのではないかな、などと考えていたりします。

実装

RabbitMQのインストールは環境によって異なるので、各々の環境に合わせて適宜インストールして下さい。こちらのインストールで躓くことは、まずないと思われます。centosであれば、yumコマンドで一発です。

$ sudo yum --enablerepo=epel -y install rabbitmq-server

RabbitMQを起動しましたら、次はgemをインストールします。

$ gem install sneakers

config/application.rbを編集することで、ActiveJobのアダプターの指定をsneakersに変更します。また、ActiveJob経由でworkerを呼び出すので、app/jobsに新しいjobを追加します。併せてapp/workersに追加したjobを呼び出す為のworkerも追加しましょう。

最後にworkerを起動するためのRakeタスクを定義します。

定義するとは言っても、Rakefileで必要なファイルをrequireするだけです。とても親切ですね。config/applicationをrequireしている次の行あたりに記述しておけば問題ないでしょう。

require 'sneakers/tasks'

これで準備は完了です。workerを起動します。

$ WORKERS=MyJobWorker bundle exec rake sneakers:run

あとはrails cからMyJob.perform_later()などとして、jobをenqueueします。するとRabbitMQに接続が行われて、キューイングが行われている様子がログから確認できます。

2018-07-09T17:32:58Z p-23978 t-gneflh16c INFO: publishing <{"job_class":"MyJob","job_id":"5ae4391a-53a6-44d4-84ed-982a4474ec2c","provider_job_id":null,"queue_name":"my_job","priority":null,"arguments":[],"executions":0,"locale":"en"}> to [my_job]
Enqueued MyJob (Job ID: 5ae4391a-53a6-44d4-84ed-982a4474ec2c) to Sneakers(my_job)
=> #<MyJob:0x005570d9b1cd40 @arguments=[], @job_id="5ae4391a-53a6-44d4-84ed-982a4474ec2c", @queue_name="my_job", @priority=nil, @executions=0>
2018-07-09T17:32:58Z p-23846 t-gpvltnqp4 DEBUG: [worker-my_job:1:q8yo49][#<Thread:0x0055cb391d8fd0>][my_job][#<Sneakers::Configuration:0x0055cb39bec170>] Working off: "{\"job_class\":\"MyJob\",\"job_id\":\"5ae4391a-53a6-4
4d4-84ed-982a4474ec2c\",\"provider_job_id\":null,\"queue_name\":\"my_job\",\"priority\":null,\"arguments\":[],\"executions\":0,\"locale\":\"en\"}"
Perform!

RabbitQMには非常に優れた管理UIや、とても便利なAPIが付いてきます。RubyのSDKも充実しておりますので、これらをrails側から叩くことが容易であると考えると、なかなか悪くない選択肢なのではないかと思います。

Rails

Posted by poison