読者です 読者をやめる 読者になる 読者になる

Hina-Mode

とある呑んだくれエンジニアの気が向いた時に書く戯言

FuelPHPの非同期処理パッケージを(ちょっと前に)自作したので改めて紹介します

FuelPHP Advent Calendar 2015 の17日目を担当します @hinashiki です。よろしくお願いします。
先日は12日目の記事も担当させていただきました。

去年、今年あたりにかけて、FuelPHPのパッケージを幾つか作成したので、一つだけ簡単にさせていただきます。

作成したものはFuelPHPで動かす非同期処理のパッケージです。
既に同様のパッケージについては他の方も作っていらっしゃったのですが

  • 自分のアプリ要件的にbeanstalkを入れるのが難しかった
  • Daemon化するのに別ファイルが必要だった

などの理由から見送らせて頂き、結局自作することにしました。

概要

実際のパッケージはこちらです。
packagistにも入ってますのでcomposerでinstallできます。
一応必要な案内は一通り(拙いですが)README.mdに記載してあります。

尚、利用前提条件として

  • ORMパッケージが利用出来る
  • DBが利用できる(MySQLでのみ、現状は動作確認してます)
  • Cronが利用できる(非同期処理の定期実行のため)

が必要となっています。

使い方

キューの挿入はModel_TaskQueueのsave_queueを利用します。

\Model_TaskQueue::save_queue(
    "Static::method",
    array($arg1, $arg2 ...)
);

第一引数にはstaticなクラスメソッド名を、第二引数には該当メソッドに渡す引数を配列で渡します。
その他の引数は後ほど説明します。
データはDBにINSERTされます。

で、実際のキューの実行はtaskとして処理します

php oil refine queue

実行時、溜まっているキューをDBのID順に引っ張って処理します。
1 taskにつき処理するキューは1つです。

並列処理したい場合にはcronで数秒おきに実行をしたり、複数サーバで処理したりすると良いかもしれません。
例)6秒おきにキュー処理したい場合(1分10回処理)

for i in {1..10}; do FUEL_ENV=production php oil refine queues &> /dev/null & sleep 6; done

オプション説明

上記は飽く迄基本処理であり、「もう少し細かい設定をしたい」場合のオプションが幾つか存在します。
3つほどピックアップして説明させていただきます。

並列処理の限界数指定

先の例の用に数秒に1回処理を抽出すると、サーバ側でタスク処理だけでパンクしてしまう事も、当然あります。
そこで本パッケージでは「1サーバで同時に動かせる限界数」を設定しています。
例) 同時処理限界数が3の時、4つめを動かした時の挙動

$ php oil r queue &
$ php oil r queue &
$ php oil r queue &
$ php oil r queue 
queue limit over.
$ 

という感じで、処理が開始される前に現在処理しているキュー数を確認し、負荷調整を行うことができます。

キューの優先順位の設定

キューには優先順位がつける事が出来ます。

Model_TaskQueue::save_queue() の第四引数で指定ができ、デフォルトは100です。
仮に優先処理したいキューに99などをあてておくと、デフォルトより優先的に処理する事が可能です。

キューの種別単位の同時実行数制限

Aの処理は2つ同時に実行したくない、Bの処理は4つまでしか実行させたくない、などの複数要件が重なる際に有効なオプションです。

config/queue.php に duplicate_type という指定ができ、

'duplicate_type' => array(
  1 => 1, // Aの処理
  2 => 4, // Bの処理
),

と設定すると、Aの処理は1つ、Bの処理は4つの同時処理が限界となります。
※この設定値は並列処理の限界数指定の影響を受けるため、限界値の設定はそれぞれ調整する必要があります。

尚、この種別設定は Model_TaskQueue::save_queue() の第三引数で指定できます。

まとめ

という感じでざっくりしたパッケージを造りました。
パッケージ作るというと
「全員に見られるし恥ずかしい」
「突っ込まれるの怖い」
「後々までの運用に責任持てない」
という不安もあるかと思いますが、出せばどうにかなるという適当感で私は出しちゃってます。

で、こうして外に出しておくと、自分の他の案件の作成時に使い回せますし、
「あー、こういうのないかなぁ」という他の人達の検索にももしかしたらヒットして、そこで役立つこともあるかもしれないので
どんどん外に出していきましょう(個人的にも楽したいのでそうして欲しいです(笑



この投稿は FuelPHP Advent Calendar 2015 の 17日目の記事です。