Swoole の実際の動作: コルーチンを使用してアプリケーションのパフォーマンスを向上させる方法
インターネット アプリケーションがますます複雑になるにつれて、パフォーマンスがますます重要な問題になってきています。コルーチン用の高性能ネットワーク通信フレームワークである Swoole は、この問題をうまく解決できます。この記事では、Swoole コルーチンの基本概念をいくつか紹介し、例を挙げてコルーチンを使用してアプリケーションのパフォーマンスを向上させる方法を示します。
1. コルーチンとは何ですか?
コルーチンは、単一のスレッドでマルチタスクのコラボレーションを実現し、コルーチン間を自由に移動できる軽量のスレッドです。 Swoole では、コルーチンによって非同期プログラミングの複雑さが簡素化され、コルーチンを通じて、同期コードを書くのと同じように非同期コードを書くことができ、コードの可読性と保守性が向上します。
2. コルーチンの基本的な使い方
Swoole では、コルーチンは swoole_coroutine_create 関数によって作成されます。コードは次のとおりです:
//创建协程 $cid = swoole_coroutine_create(function(){ echo "Hello Coroutine "; }); //若主线程不阻塞,则协程无法执行
コルーチンを作成した後、次のことが必要です。使用する swoole_event_wait 関数は、コルーチンの実行を待機するために使用されます。コードは次のとおりです:
//创建协程 $cid = swoole_coroutine_create(function(){ echo "Hello Coroutine "; }); //等待协程执行 swoole_event_wait();
上記のコードは、コルーチンが正常に実行されたことを示す「Hello Coroutine」を出力できます。
コルーチンでは、swoole_coroutine_yield 関数を使用して、現在のコルーチンを放棄し、他のコルーチンを実行させることもできます。コードは次のとおりです:
$cid1 = swoole_coroutine_create(function(){ echo "Coroutine 1 "; swoole_coroutine_yield(); echo "Coroutine 1 resume "; }); $cid2 = swoole_coroutine_create(function(){ echo "Coroutine 2 "; swoole_coroutine_yield(); echo "Coroutine 2 resume "; }); swoole_coroutine_resume($cid1); swoole_coroutine_resume($cid2); swoole_event_wait();
上記のコードでは、2 つのコルーチンが最初に作成されたプロセスを実行し、swoole_coroutine_resume 関数を使用して 2 つのコルーチンの実行をそれぞれ再開します。コルーチン内で swoole_coroutine_yield 関数が呼び出されるため、コルーチンはそれぞれ「コルーチン 1」と「コルーチン 2」を出力し、両方とも実行を一時停止します。最後に、コルーチンが 1 サイクルを完了すると、CPU を取得し、それぞれ「コルーチン 1 再開」と「コルーチン 2 再開」を出力します。
3. コルーチンの一般的に使用されるスキル
Swoole では、複数のコルーチンの同時実行は、 swoole_coroutine_wait関数と同期処理のコードは以下の通りです。
$tasks = [ "task1" => function () { sleep(1); return "Task 1 Done "; }, "task2" => function () { sleep(1); return "Task 2 Done "; }, ]; $results = []; foreach ($tasks as $name => $task) { $cid = swoole_coroutine_create(function () use ($name, $task, &$results) { $result = $task(); $results[$name] = $result; }); swoole_coroutine_resume($cid); } swoole_coroutine_wait(); print_r($results);
上記のコードでは、まず2つのタスクを定義し、そのタスクを実行する関数にsleep(1)を追加してタスクの実行時間をシミュレートし、次に、foreach ループを使用して 2 つのタスク (コルーチン) を作成し、実行結果を $results 配列に保存し、最後に swoole_coroutine_wait 関数を呼び出してコルーチンの完了を待って実行結果を取得します。
Swoole では、swoole_coroutine_system_exec 関数を使用してシステム コマンドを非同期に実行し、結果を返すことができます。コードは次のとおりです:
function async_exec($cmd) { $fp = popen($cmd, "r"); if ($fp) { while (!feof($fp)) { yield fread($fp, 8192); } pclose($fp); } } $s = microtime(true); $coroutine = async_exec('ls /'); foreach ($coroutine as $stdout) { echo $stdout; } $e = microtime(true); echo "Time used: " . ($e - $s) . "s ";
上記のコードでは、async_exec 関数を使用してシステム コマンドを非同期に実行し、yield を使用して出力結果を徐々に読み取り、最終的にコマンドの実行時間を出力しています。
Swoole にはデータベース接続プール機能が組み込まれており、swoole_mysql コルーチン クライアントを通じてデータベース操作を簡素化し、同時実行効率を向上させることができます。コードは次のとおりです。
$pool = new SwooleCoroutineChannel(10); for ($i = 0; $i < 10; $i++) { $conn = new SwooleCoroutineMySQL(); $conn->connect([ 'host' => '127.0.0.1', 'user' => 'root', 'password' => '123456', 'database' => 'test', ]); $pool->push($conn); } go(function () use ($pool) { $conn = $pool->pop(); $result = $conn->query('select * from users'); //... $pool->push($conn); });
上記のコードでは、まず接続プールを作成し、for ループを使用して 10 個の MySQL 接続を作成し、それらを接続プールに追加します。次に、 go 関数を使用してコルーチンを作成します。接続プールから接続を取り出します。データベース クエリ操作を実行し、最後に接続を接続プールに戻します。接続プールの利点は、接続の作成と破棄によって生じるオーバーヘッドを削減し、データベース操作のパフォーマンスを向上できることです。
4. Swoole を使用してマイクロサービス アプリケーションのパフォーマンスを向上させる例
Swoole には非常に強力なコルーチン プログラミング機能があり、開発者が高性能で同時実行性の高いサーバー側アプリケーションを効率的に作成するのに役立ちます。 。以下では、マイクロサービス アプリケーションを例として、Swoole のコルーチン テクノロジを使用してアプリケーションのパフォーマンスを向上させる方法を示します。
まず、単純なマイクロサービス プログラムを作成します。コードは次のとおりです。
<?php //微服务1 function service1($str) { $result = file_get_contents("http://127.0.0.1:8888/service2?str=".$str); return strtoupper($result); } //微服务2 function service2($str) { return md5($str); } //路由处理 $uri = $_SERVER['REQUEST_URI']; if (preg_match("/^/service1?str=(.*)$/", $uri, $match)) { echo service1($match[1]); } elseif (preg_match("/^/service2?str=(.*)$/", $uri, $match)) { echo service2($match[1]); } else { echo "Unknown Request: ".$uri; }
上記のプログラムは単純なマイクロサービスです。プログラム サービス シミュレーション プログラムは、service1 と service2 の 2 つのサービスを提供します。サービス 1 はサービス 2 を呼び出し、返された結果を大文字に変換し、サービス 2 は入力文字列を MD5 で暗号化して返します。
Swoole を使用してマイクロサービスのコルーチン バージョンを実装します。コードは次のとおりです:
<?php $http = new SwooleHttpServer("0.0.0.0", 8888); $http->on("request", function ($request, $response) { $uri = $request->server['request_uri']; if (preg_match("/^/service1?str=(.*)$/", $uri, $match)) { $result = go(function () use ($match) { $str = $match[1]; $result = await service2($str); return strtoupper($result); }); $response->end($result); } elseif (preg_match("/^/service2?str=(.*)$/", $uri, $match)) { $result = go(function () use ($match) { $str = $match[1]; $result = await service2($str); return $result; }); $response->end($result); } else { $response->end("Unknown Request: ".$uri); } }); $http->start(); async function service1($str) { $result = await service2($str); return strtoupper($result); } async function service2($str) { //模拟异步IO操作 usleep(1000000); return md5($str); }
上記のコードでは、Swoole の HTTP コルーチン サーバーを使用してマイクロサービスを提供し、要求された URI を解析して、対応するサービスを呼び出します。サービス 1 の処理では、サービス 2 のサービスが呼び出されて結果が返されますが、呼び出し方法は go 関数による非同期であり、await キーワードを使用して非同期呼び出し結果を待ちます。各マイクロサービス実装では、非同期 IO 操作を使用して実際のネットワーク IO をシミュレートし、Swoole コルーチンの特性をよりよく反映します。
概要
Swoole は、開発者が効率的で高性能なネットワーク通信プログラムを作成するのに役立つ、非常に強力なコルーチン プログラミング機能を提供します。アプリケーションの実装では、開発者はコルーチン テクノロジを使用して、非同期プログラミングを簡素化し、同時実行効率を向上させることができます。上記の例では、Swoole を使用してマイクロサービスのコルーチン バージョンを実装しました。これにより、アプリケーションのパフォーマンスと保守性が大幅に向上しました。実際の実装では、アプリケーションのパフォーマンスをさらに最適化するために、アプリケーションの特性に基づいて適切な非同期 IO 操作、接続プール、その他のテクノロジを選択することも必要です。
以上がSwoole の動作: コルーチンを使用してアプリケーションのパフォーマンスを向上させる方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。