Cet article vous donnera des connaissances pertinentes sur Laravel et Swoole. Le contenu principal est de vous apprendre à changer Laravel vers la version Swoole (essayez d'apprendre, il n'est pas recommandé de modifier le projet existant). J'espère que cela sera utile à tout le monde !
Avant-propos
Non recommandé pour l'environnement de production
Créez un nouveau projet Laravel
laravel new swoole-laravel
Changez Laravel en version Swoole
Créez un fichier swoole_server.php dans le répertoire racine de Laravel, puis mettez-le public / Copiez le code dans index.php [Apprentissage recommandé : tutoriel vidéo laravel]
<?php use Illuminate\Contracts\Http\Kernel; use Illuminate\Http\Request; define('LARAVEL_START', microtime(true)); require __DIR__.'/../vendor/autoload.php'; $app = require_once __DIR__.'/../bootstrap/app.php'; $kernel = $app->make(Kernel::class); $response = $kernel->handle( $request = Request::capture() )->send(); $kernel->terminate($request, $response);
La première étape consiste à charger le fichier framework, et il doit être chargé dans le processus principal, sans avoir besoin de sous-processus ou de coroutine. être chargé à nouveau. Par conséquent, il n’est pas nécessaire de toucher aux exigences ci-dessus.
La deuxième étape consiste à démarrer un service HTTP Swoole. Cela a déjà été mentionné à plusieurs reprises. Notez que dans onRequest, nous devrions y mettre le code lié au $kernel.
$http = new Swoole\Http\Server('0.0.0.0', 9501); $http->on('Request', function ($req, $res) use($app) { try { $kernel = $app->make(Kernel::class); $response = $kernel->handle( $request = Request::capture() )->send(); $kernel->terminate($request, $response); }catch(\Exception $e){ print_r($e->getMessage()); } }); echo "服务启动", PHP_EOL; $http->start();
Est-ce suffisant ? Pourquoi ne pas essayer d'abord. Dans des circonstances normales, vous ne pourrez peut-être obtenir aucune entrée ou sortie. Pourquoi ?
La troisième étape consiste à résoudre le problème de saisie. En fait, les variables super globales ne fonctionnent pas dans Swoole, donc les variables telles que $_GET deviendront invalides et les objets liés aux requêtes dans Laravel ne pourront pas obtenir de données. Ce qu'il faut faire? Nous récupérons simplement ces données à partir des paramètres de onRequest, puis les remettons dans $_GET dans la coroutine du processus actuel.
$http->on('Request', function ($req, $res) use($app) { $_SERVER = []; if(isset($req->server)){ foreach($req->server as $k => $v){ $_SERVER[strtoupper($k)] = $v; } } $_GET = []; if(isset($req->get)){ foreach ($req->get as $k => $v){ $_GET[$k] = $v; } } $_POST = []; if(isset($req->post)){ foreach ($req->post as $k => $v){ $_POST[$k] = $v; } } try { $kernel = $app->make(Kernel::class); $response = $kernel->handle( $request = Request::capture() )->send(); $kernel->terminate($request, $response); }catch(\Exception $e){ print_r($e->getMessage()); } });
Les trois morceaux de code ci-dessus résolvent respectivement les problèmes de $_SERVER, $_GET et $_POST. Maintenant, si vous réessayez, les paramètres peuvent être reçus, mais pourquoi la sortie est-elle imprimée sur la console ?
La quatrième étape consiste à résoudre le problème de sortie, à placer toute la sortie du cadre dans le tampon de sortie, puis à utiliser la réponse de Swoole pour revenir.
$http->on('Request', function ($req, $res) use($app) { $_SERVER = []; if(isset($req->server)){ foreach($req->server as $k => $v){ $_SERVER[strtoupper($k)] = $v; } } $_GET = []; if(isset($req->get)){ foreach ($req->get as $k => $v){ $_GET[$k] = $v; } } $_POST = []; if(isset($req->post)){ foreach ($req->post as $k => $v){ $_POST[$k] = $v; } } //把返回放到一个缓冲区里 ob_start(); try { $kernel = $app->make(Kernel::class); $response = $kernel->handle( $request = Request::capture() )->send(); $kernel->terminate($request, $response); }catch(\Exception $e){ print_r($e->getMessage()); } $ob = ob_get_contents(); ob_end_clean(); $res->end($ob); });
Le dernier contenu de ob_start () est également ce que nous avons étudié auparavant, nous ne l'expliquerons donc pas davantage.
Tout le code
start();
À ce stade, notre transformation de framework la plus simple est terminée, essayons l'effet rapidement.
Exécutez
php swoole_server.php
Visitez
http://47.113.xxx.xx:9501/
Essayez l'effet coroutine
Définissez d'abord un itinéraire. Ou on peut modifier directement l'itinéraire par défaut.
Route::get('/', function () { echo Swoole\Coroutine::getCid(), "<br/>"; print_r(Swoole\Coroutine::stats()); Swoole\Coroutine::sleep(10); echo "<br/>"; echo getmypid(), "<br/>"; // return view('welcome'); });
J'ai imprimé un tas de choses, mais elles devraient toutes être familières. Les deux premiers sont la sortie de l'ID de coroutine et des informations de coroutine. Ensuite, nous SwooleCoroutine::sleep () pendant 10 secondes, puis imprimons l'ID de processus.
Ensuite, nous ouvrons le navigateur et nous préparons à accéder aux deux onglets ensemble.
// 第一个访问的页面 1 Array ( [event_num] => 2 [signal_listener_num] => 0 [aio_task_num] => 0 [aio_worker_num] => 0 [aio_queue_size] => 0 [c_stack_size] => 2097152 [coroutine_num] => 1 [coroutine_peak_num] => 1 [coroutine_last_cid] => 1 ) 1468 // 第二个访问的页面 2 Array ( [event_num] => 2 [signal_listener_num] => 0 [aio_task_num] => 0 [aio_worker_num] => 0 [aio_queue_size] => 0 [c_stack_size] => 2097152 [coroutine_num] => 2 [coroutine_peak_num] => 2 [coroutine_last_cid] => 2 ) 1468
L'avez-vous vu ? Chaque événement onRequest ouvre en fait une nouvelle coroutine pour gérer la demande, donc leurs ID de coroutine sont différents. Dans le même temps, la deuxième requête n’attendra pas 20 secondes pour revenir car la première requête est bloquée. Enfin, dans l'état de la coroutine, nous voyons également qu'il y a deux coroutine_nums affichés dans la deuxième requête, indiquant qu'il y a actuellement deux tâches de traitement de coroutines. Au final, les processus sont les mêmes, ils suivent tous le même processus.
Essayez l'effet multi-processus
Par défaut, le code ci-dessus est un processus principal et un processus Worker, puis utilise la capacité coroutine. En fait, cet effet peut tuer instantanément l'effet PHP-FPM ordinaire. Mais nous devons exploiter pleinement les performances des machines multicœurs, c'est-à-dire activer plusieurs processus et utiliser le mode de traitement super puissant multi-processus + multi-coroutine. Le moyen le plus simple consiste à définir directement le nombre de processus pour le service HTTP.
$http->set(array( 'worker_num' => 4, // 'worker_num' => 1,单进程 ));
Maintenant, lancez le serveur et vous pourrez voir quelques processus supplémentaires. Ensuite, nous créons un nouvel itinéraire de test
Route::get('/a', function () { echo Swoole\Coroutine::getCid(), "<br/>"; print_r(Swoole\Coroutine::stats()); echo "<br/>"; echo getmypid(), "<br/>"; });
Visitez maintenant la page d'accueil et cette /a page à nouveau.
// 首页一 1 Array ( [event_num] => 2 [signal_listener_num] => 0 [aio_task_num] => 0 [aio_worker_num] => 0 [aio_queue_size] => 0 [c_stack_size] => 2097152 [coroutine_num] => 1 [coroutine_peak_num] => 1 [coroutine_last_cid] => 1 ) 1562 // 首页二 1 Array ( [event_num] => 2 [signal_listener_num] => 0 [aio_task_num] => 0 [aio_worker_num] => 0 [aio_queue_size] => 0 [c_stack_size] => 2097152 [coroutine_num] => 1 [coroutine_peak_num] => 1 [coroutine_last_cid] => 1 ) 1563 // /a 页面 1 Array ( [event_num] => 2 [signal_listener_num] => 0 [aio_task_num] => 0 [aio_worker_num] => 0 [aio_queue_size] => 0 [c_stack_size] => 2097152 [coroutine_num] => 1 [coroutine_peak_num] => 1 [coroutine_last_cid] => 1 ) 1564
Non, leurs identifiants de processus sont également différents. S'il n'y a pas de blocage, le processus sera commuté en premier. Si tous les processus sont bloqués, les coroutines seront créées dans une boucle pour le traitement en cours.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!