プロジェクトでは、バックグラウンドでタスクを実行する必要があることがよくあります。たとえば、メールを送信する場合、ユーザーに成功のプロンプト メッセージを表示できる場合、メール サーバーに接続するまでに 5 ~ 10 秒、さらにはそれ以上かかることがあります。最初に電子メールの送信操作を処理し、その後バックグラウンドでゆっくりと処理することで、明らかにユーザー エクスペリエンスが向上します。
同様のニーズを実現するために、Web プロジェクトでは、よく知られた製品である MemcacheQ や RabbitMQ などのメッセージ キュー (Message Queue) を使用するのが一般的な実装方法です。
端的に言うと、メッセージ キューは最も単純な先入れ先出しキューであり、キューのメンバーはテキストの一部です。メッセージ キューは非常に単純であるため、メッセージ キューを保持すると、これは単にメールを送信するだけのタスクであるため、少し混乱するように感じます。これにより、多くの問題が発生します:
メッセージ キューには文字しか格納できません。文字列型データ、メール送信などの「タスク」をメッセージキュー内の「メッセージ」に変換するにはどうすればよいですか?
メッセージキューはデータの保存と入力のみを担当し、プログラム自体を実行することはできません。 , したがって、メッセージキューからデータを1つずつ取得し、データをタスクに変換して実行する方法を行う必要があります。
メッセージ キューがいつデータを生成するかを予測できないため、タスク実行プログラムには、バックグラウンドに常駐するデーモン プロセスであるメッセージ キューを監視する機能も必要です。
一般的な Web アプリケーション PHP は CGI モードで実行され、メモリに常駐できません。 PHP には CLI モードもあることはわかっていますが、PHP CLI を使用してデーモン プロセスを実装できますか?また、それはどの程度効率的ですか?
デーモンが実行されているとき、Webアプリケーションはバックグラウンドデーモンと対話して、プロセスを開始/終了する機能を実現し、プロセスの実行ステータスを取得できますか?
Resque はこれらの問題を次のように解決します:
実際、上記の問題から、1 つのメッセージキューだけではすべての問題を解決することはできず、新しい役割が必要であることがわかります。介入。 Resque では、バックグラウンド タスクは 3 つの役割によって完了するように抽象化されています:
ジョブ | タスク: たとえば、この記事の例として電子メールを送信する場合、ジョブはバックグラウンドで完了する必要があるタスクです。ジョブに抽象化されます。 Resque では、ジョブはクラスです。
Queue | Queue: Resque では、キューは Redis によって実装されます。 Resque は、キューへのジョブの挿入/キューからのジョブの削除などの機能を実装できるシンプルなキュー マネージャーも提供します。
ワーカー | エグゼキューター: キューからジョブを取り出して実行する責任を負い、デーモン プロセスとしてバックグラウンドで実行できます。
この分割に基づいて、Resque でのバックグラウンド タスクの基本的なプロセスは次のようになります:
バックグラウンド タスクを独立したクラスとして記述し、このクラスがジョブになります。
バックグラウンド プログラムを使用する必要がある場合、システムはジョブ クラスの名前と必要なパラメーターをキューに入れます。
コマンドラインからワーカーを開き、ワーカーが処理する必要があるキューをパラメータで指定します。
ワーカーはデーモンプロセスとして実行され、キューを定期的にチェックします。
キューにジョブがある場合、ワーカーはジョブを取り出して実行します。つまり、ジョブクラスをインスタンス化し、クラス内のメソッドを実行します。
これでバックグラウンドタスクを完了できます。
Resque には、もう 1 つの非常に重要な設計があります。ワーカーは 1 つまたは複数のキューを処理でき、ワーカーのプロセス/スレッドの数を増やすことでキューの実行速度を高速化できます。
php-resqueはプロセスの開発と管理を伴うため、phpのPCNTL関数を使用するため、Linuxでのみ実行でき、PCNTL関数をコンパイルするにはphpが必要であることに注意してください。 。 Windows を使用して同じ作業を実行したい場合、PHP の他の言語バージョンは Windows でのバックグラウンド タスクには非常に適していないことがわかります。
Ubuntu12.04LTS を例に挙げると、apt を使用して Ubuntu によってインストールされた PHP は、デフォルトで設定なしで PCNTL 関数をコンパイルしています。
Composer を使用して php-resque をインストールしますWeb ディレクトリが /opt/htdocs にあると仮定しますapt-get install redis-server
apt-get install curl cd /usr/local/bin curl -s http://getcomposer.org/installer | php chmod a+x composer.phar alias composer='/usr/local/bin/composer.phar'
php-resque也给出了最简单的插入队列实现 demo/queue.php:
if(empty($argv[1])) { die('Specify the name of a job to add. e.g, php queue.php PHP_Job'); } require __DIR__ . '/init.php'; date_default_timezone_set('GMT'); Resque::setBackend('127.0.0.1:6379'); $args = array( 'time' => time(), 'array' => array( 'test' => 'test', ), ); $jobId = Resque::enqueue('default', $argv[1], $args, true); echo "Queued job ".$jobId."\n\n";
在这个例子中,queue.php需要以cli方式运行,将cli接收到的第一个参数作为Job名称,插入名为'default'的队列,同时向屏幕输出刚才插入队列的Job Id。在终端输入:
php demo/queue.php PHP_Job
结果可以看到屏幕上输出:
Queued job b1f01038e5e833d24b46271a0e31f6d6
即Job已经添加成功。注意这里的Job名称与我们编写的Job Class名称保持一致:PHP_Job
php-resque同样提供了查看Job运行状态的例子,直接运行:
php demo/check_status.php b1f01038e5e833d24b46271a0e31f6d6
可以看到输出为:
Tracking status of b1f01038e5e833d24b46271a0e31f6d6. Press [break] to stop. Status of b1f01038e5e833d24b46271a0e31f6d6 is: 1
我们刚才创建的Job状态为1。在Resque中,一个Job有以下4种状态:
Resque_Job_Status::STATUS_WAITING = 1; (等待)
Resque_Job_Status::STATUS_RUNNING = 2; (正在执行)
Resque_Job_Status::STATUS_FAILED = 3; (失败)
Resque_Job_Status::STATUS_COMPLETE = 4; (结束)
因为没有Worker运行,所以刚才创建的Job还是等待状态。
这次我们直接编写demo/resque.php:
<?php date_default_timezone_set('GMT'); require 'job.php'; require '../bin/resque';
可以看到一个Worker至少需要两部分:
可以直接包含Job类文件,也可以使用php的自动加载机制,指定好Job Class所在路径并能实现自动加载
包含Resque的默认Worker: bin/resque
在终端中运行:
QUEUE=default php demo/resque.php
前面的QUEUE部分是设置环境变量,我们指定当前的Worker只负责处理default队列。也可以使用
QUEUE=* php demo/resque.php
来处理所有队列。
运行后输出为
#!/usr/bin/env php *** Starting worker
用ps指令检查一下:
ps aux | grep resque
可以看到有一个php的守护进程已经在运行了
1000 4607 0.0 0.1 74816 11612 pts/3 S+ 14:52 0:00 php demo/resque.php
再使用之前的检查Job指令
php demo/check_status.php b1f01038e5e833d24b46271a0e31f6d6
2分钟后可以看到
Status of b1f01038e5e833d24b46271a0e31f6d6 is: 4
任务已经运行完毕,同时屏幕上应该可以看到输出的Hello!
至此我们已经成功的完成了一个最简单的Resque实例的全部演示,更复杂的情况以及遗留的问题会在下一次的日志中说明。
相关推荐:
利用redis和php-resque实现后台任务 redis 下载 redis 集群 redis可视化工具
以上がphp-resqueの使用手順の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。