タスクスケジューリングにZendジョブキューを使用します
コアポイント
ほとんどのWebアプリケーションは、同期通信モデルに従います。ただし、非同期および長期にわたるタスク(レポート生成など)は、非同期実行により適しています。タスクを後でオフロードするか、異なるサーバーで実行する1つの方法は、Zend Server 5で提供されているジョブキューモジュールを使用することです(ただし、コミュニティエディションには含まれていません)。ジョブキューを使用すると、時間、優先度、さらには依存関係に基づいてジョブスケジューリングが可能になります。ジョブは定期的に遅延または実行することができ、最も重要なことに、並行して実行できます!最も重要なことは、Zend Server自体が、そのステータス、実行時間、出力など、ジョブの実行を追跡するための管理GUIを提供することです。ジョブキューモジュールの主な利点は、タスクを並行して実行する機能にあります。 Cron Jobsとは異なり、ジョブキューは以下を許可します
次のリクエストのためにデータを準備(事前に計算)
ジョブキューのAPIは、zendjobqueueクラスで使用できます。ほとんどのタスクを実行するには、Zendjobqueueオブジェクトをインスタンス化し、createhttpjob()メソッドを使用してジョブを作成することにより、ジョブキューサーバーに接続します。
完全なURLの代わりにcreatehttpjob()にパスを通過すると、ホスト名$ _server ["http_host"]の値でジョブが作成されます。 $ _server ["http_host"]は、Cronスクリプトからジョブをスケジュールするときなど、利用できないことに注意してください。
<?php $queue = new ZendJobQueue(); $queue->createHttpJob("http://example.com/jobs/somejob.php");
ジョブパラメーターは、クエリ文字列の一部として、またはcreatehttpjob()の2番目のパラメーターとして配列として渡すことができます。引数が2番目の引数として渡された場合、配列はJSON互換でなければなりません。ジョブコードのパラメーターにアクセスするには、getCurrentJobParams()staticメソッドを使用できます。
<?php // 这两个调用是等效的 $queue->createHttpJob("/jobs/somejob.php"); $queue->createHttpJob("http://" . $_SERVER["HTTP_HOST"] . "/jobs/somejob.php");
その他のジョブオプションは、createhttpjob()の3番目のパラメーターを使用して使用できます。これは、次のキーを含む連想配列です。
失敗(および成功)は、次のように処理できます
<?php $params = ZendJobQueue::getCurrentJobParams();
拡張例
<?php $params = array("p1" => 10, "p2" => "somevalue"); // 一小时后处理 $options = array("schedule_time" => date("Y-m-d H:i:s", strtotime("+1 hour"))); $queue->createHttpJob("http://example.com/jobs/somejob.php", $params, $options); // 每隔一天凌晨1:05处理 $options = array("schedule" => "5 1 */2 * *"); $queue->createHttpJob("http://example.com/jobs/somejob.php", $params, $options);
ユーザーのリクエストに基づいて、Webアプリケーションが一連のレポートを生成して送信する必要があると仮定します。通常、PHPはマルチプロセスをサポートせず、同期通信モデルを使用するため、ユーザーは要求されたすべてのレポートが1つずつ生成されるのを待ってメールを送信する必要があります。この場合のジョブキューを使用すると、ユーザーがアプリケーションの他の操作を実行できるだけでなく(作業が非同期に行われるため)、アプリケーションは複数のレポートを同時に処理できます(ジョブは並行して実行できるため) - ほとんどのレポートはほぼ同時に完了します。 ScheduleReport()関数は、スケジュールされた各レポートに関連付けられたジョブ識別子のリストを返します。この関数では、ZendjobqueueクラスのIsjobqueuedaemonrunning()メソッドは、対応するサービスが実行されているかどうか、ジョブをスケジュールできるかどうかを確認します。レポートの優先順位に応じて、ジョブはすぐにまたは2分後に実行するようにスケジュールできます(多くのレポートが同時に要求された場合、サーバーの負荷を減らすため)。ジョブがスケジュールされた後、そのIDは、すべての成功裏に作成されたジョブのリストに保存されます。ジョブIDを理解することは、ジョブを監視したり、ジョブをキャンセルできるために非常に重要です。スケジュールポート()関数への呼び出しが次のようになります。
前述のように、スケジュールされたジョブもキャンセルできます。ただし、ジョブが進行中に完了します。したがって、要求された優先度が緊急でない場合、ユーザーはスケジュールされたレポートの配信をキャンセルするために2分かかります。
<?php try { doSomething(); ZendJobQueue::setCurrentJobStatus(ZendJobQueue::OK); } catch (Exception $e) { ZendJobQueue::setCurrentJobStatus(ZendJobQueue::STATUS_LOGICALLY_FAILED, $e->getMessage()); }
<?php function scheduleReport($reportList, $recipient) { // 已调度作业列表 $jobList = array(); $queue = new ZendJobQueue(); // 检查Job Queue是否正在运行 if ($queue->isJobQueueDaemonRunning() && count($reportList) > 0) { foreach ($reportList as $report) { $params = array("type" => $report["type"], "start" => $report["start"], "length" => $report["length"], "recipient" => $recipient); $options = array("priority" => $report["priority"]); // 除非优先级为紧急,否则在两分钟内执行作业 if ($report["priority"] != ZendJobQueue::PRIORITY_URGENT) { $options["schedule_time"] = date("Y-m-d H:i:s", strtotime("+2 minutes")); } $jobID = $queue->createHttpJob("http://example.com/jobs/report.php", $params, $options); // 将作业ID添加到已成功调度作业的列表中 if ($jobID !== false) { $jobList[] = $jobID; } } } return $jobList; }
<?php // 设置每日销售报告和每月财务报告的请求 $reportList = array( array("type" => "sales", "start" => "2011-12-09 00:00:00", "length" => 1, "priority" => ZendJobQueue::PRIORITY_URGENT), array("type" => "finance", "start" => "2011-11-01 00:00:00", "length" => 30, "priority" => ZendJobQueue::PRIORITY_NORMAL)); // 调度报告 $jobList = scheduleReport($reportList, "user@example.com"); // 验证报告是否已调度 if (empty($jobList)) { // 显示错误消息 }
もちろん、ジョブキューに代わるものがあります。 Cron、PCNTL_FORK、さらにはPHP/Javaブリッジを介したJavaベースのソリューションでさえ、ニーズに応じて検討する価値があります。 Gearman、Node.js、Rabbitmqなど、より興味深いツールが存在します。
概要
Zend Serverのジョブキューは、PHPでキューと並列処理を処理する唯一の方法ではありませんが、「The PHP Company」でサポートされている非常に簡単なソリューションであり、非常に使いやすいです。 Zendのphpcloudがより成功するにつれて、ジョブキューの採用はより広範になるはずです。この記事でサンプルコードの完全な内容を表示したい場合は、GitHubで見つけることができます。 VarinaとJay Patel/Shutterstockの写真
Zend Queue(FAQ)についてのFAQ
Zendキューの主な機能は何ですか?ZendキューはWebアプリケーションのパフォーマンスをどのように改善しますか?
Zendキューで新しいキューを作成する方法は?
<?php $queue = new ZendJobQueue(); $queue->createHttpJob("http://example.com/jobs/somejob.php");
<?php // 这两个调用是等效的 $queue->createHttpJob("/jobs/somejob.php"); $queue->createHttpJob("http://" . $_SERVER["HTTP_HOST"] . "/jobs/somejob.php");
<?php $params = ZendJobQueue::getCurrentJobParams();
<?php $params = array("p1" => 10, "p2" => "somevalue"); // 一小时后处理 $options = array("schedule_time" => date("Y-m-d H:i:s", strtotime("+1 hour"))); $queue->createHttpJob("http://example.com/jobs/somejob.php", $params, $options); // 每隔一天凌晨1:05处理 $options = array("schedule" => "5 1 */2 * *"); $queue->createHttpJob("http://example.com/jobs/somejob.php", $params, $options);
<?php try { doSomething(); ZendJobQueue::setCurrentJobStatus(ZendJobQueue::OK); } catch (Exception $e) { ZendJobQueue::setCurrentJobStatus(ZendJobQueue::STATUS_LOGICALLY_FAILED, $e->getMessage()); }
<?php $queue = new ZendJobQueue(); $queue->createHttpJob("http://example.com/jobs/somejob.php");
Zendキュー内のキュー内のすべてのメッセージをクリアするには、パージメソッドを使用できます。このメソッドは、キュー内のすべてのメッセージを削除します。例は次のとおりです。
<?php // 这两个调用是等效的 $queue->createHttpJob("/jobs/somejob.php"); $queue->createHttpJob("http://" . $_SERVER["HTTP_HOST"] . "/jobs/somejob.php");
Zendキューのキューのタイムアウト時間を設定するには、SettimeOutメソッドを使用できます。この方法には、キューの名前とタイムアウトの2つのパラメーターが必要です。例は次のとおりです。
<?php $params = ZendJobQueue::getCurrentJobParams();
上記のコードの例は、記事に記載されているZendジョブキューではなく、Zend_Queueに基づいていることに注意してください。 ZendジョブキューのAPIはわずかに異なる場合があるため、Zendサーバーの公式ドキュメントを参照する必要があります。
以上がZendジョブキューを使用したスケジューリングの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。