1. PHP にはなぜ非同期操作が必要なのでしょうか?
一般的にPHPは、Webページ表示などの短時間の作業に適しており、画像のリサイズやビッグデータのインポート、EDMやSMSの送信など、時間のかかる操作を一括で行う場合には楽に操作できます。タイムアウトが発生します。無限のタイムアウトなどを設定できると言えます。また、PHP には fastcgi という動作モードがあることも知っておく必要があります。PHP は無期限にタイムアウトしないため、fastcgi がタイムアウトしないという意味ではありません。 fastcgi がタイムアウトしないようにするには、運用担当者や保守担当者と話し合うことをお勧めします...
この時点で、非同期操作が機能します。これはノンブロッキング操作であるため、操作はすぐに戻ります。その後、バックグラウンドでゆっくりと作業します。タイムアウトするかどうかは関係ありません。現在のプロセス/スレッドでは作業していません。素晴らしいと思いませんか? しかし、実は落とし穴でもあります...
2. PHP は非同期操作を実装できますか?
答えは「はい」ですが、インターネット上のさまざまな純粋な PHP 実装は少し扱いにくいです。ソケット モード、一時停止プロセス モード、さらにはプロセスを直接フォークするものもあります。とても良いですね、あらゆる種類の神々が魔法の力を発揮します。運用担当者や保守担当者が見たら、間違いなく×××××されるでしょう。Webサーバーが殺されなければおかしいでしょう...
この非同期操作を実現する他の良い方法はありますか?はい、あとはプラグインを有効にする方法を考えるだけです。 PECL の主流のプラグイン ソリューションを確認してください。××MQ (メッセージ キュー) が多数あります。その中で、Gearman というプラグインが目に留まりました。詳しくは紹介しません。クリックして接続してください(紹介文を参照)。
3. Gearman を選ぶ理由
他に何もなければ、多くのクライアントがあり、多くの言語でクライアントをサポートしているため、ワーカーを作成するのにほとんどの言語を使用できます。個人的には、Shenma を使って好きなようにワーカーを書くことができる言語論争に非常に腹を立てています。データ永続性のサポート (つまり、キューがデータベース媒体に保存されるため、障害回復が容易です) とクラスターのサポート (実際、多くの ××MQ がこれらの機能を備えています) があります。 PECL には拡張機能があり、純粋な PHP で実装された拡張機能もあります。ともあれ、このギアマンは長生きしており、諸々の問題は基本的に解決されている。
4. 基本的な考え方
Gearman プラグインを使用すると、はるかに簡単になります。これは、gearman にタスクを送信し、実行されたタスクを送信して、ワーカーが PHP cli を呼び出して PHP コードを実行するのを待つことを意味します。
私は Python ワーカーを作成しました (なぜ Python を使用するのかは聞かないでください。1. Python を知っています。2. Linux にランタイムをインストールする必要はありません。) 独自のアイデアに基づいて PHP ワーカーを作成できます。 、でもまあ、私は PHP を実行しているワーカーをあまり信用していません。他の言語の場合は、Java、node.js、または他の言語を使用してワーカーを実装してみることができます。 Golang でワーカーを書くことに興味のある友人は、私に連絡してください。
phpasync_worker_py
申し訳ありませんが、コメントはありません。構成ファイルと py スクリプト。基本的な機能は、呼び出しパラメーターを分析して、PHP Cli を呼び出すことです。それだけです。 py スクリプトを実行するには、python gearman モジュールを自分でインストールしてください。
次に、PHP 部分に移動してテスト コードを開始します:
<?php require_once 'PHPAsyncClient.php'; date_default_timezone_set('Asia/Shanghai'); class AsyncTest { const LOG_FILE = '/debug.log'; static public function run() { if (PHPAsyncClient::in_callback(__FILE__)) { self::log('php Async callback'); PHPAsyncClient::parse(); return; } if (PHPAsyncClient::is_main(__FILE__)) { self::log('main run'); $async_call = PHPAsyncClient::getInstance(); $async_call->AsyncCall('AsyncTest', 'callback', array( 'content' => 'Hello World!!!', ), array( 'class' => 'AsyncTest', 'method' => 'callback', 'params' => array( 'content' => 'Hello Callback!', ), ), __FILE__); return; } } static public function callback($args) { self::log('AsyncTest callback run'); self::log('AsyncTest callback args:'.print_r($args, true)); } static public function log($content) { $fullname = dirname(__FILE__).self::LOG_FILE; $content = date('[Y-m-d H:i:s]').$content."\n"; file_put_contents($fullname, $content, FILE_APPEND); } } AsyncTest::run();
静的メソッドは 3 つだけで、1 つはデバッグ用のログ メソッドで、その他はリテラルです。この例は、この呼び出しメソッドの予備的な印象です。次に、PHP のすべてのソース コードを直接アップロードします:
php_async.zip
それから、Gearman は win 環境ではインストールできないと言う人が多いかもしれません...そこで、Java バージョンの Gearman サーバーも置きます。
java-gearman-service-0.6.6.zip
5. 結論
Rhinoceros と同じくらい大きなものを設定した後 (Gearman をインストールし、Py スクリプトを実行する必要があります)、基本的に PHP に非同期呼び出し機能を持たせることができました。 もちろん、必要な状態維持機能もあります。自分たちで実装する。したがって、この解決策は実際には良くなく、複雑すぎることがわかりました。 Web コールバックを行うには、いくつかの Web サービス メソッドを使用する方がよいでしょう (問題は、Web コールバックもタイムアウトしてしまうことです...)。続報に注意してください。