Maison  >  Article  >  cadre php  >  Essayez comment changer Laravel en version Swoole

Essayez comment changer Laravel en version Swoole

藏色散人
藏色散人avant
2022-12-02 16:29:021138parcourir

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(&#39;LARAVEL_START&#39;, microtime(true));
require __DIR__.&#39;/../vendor/autoload.php&#39;;
$app = require_once __DIR__.&#39;/../bootstrap/app.php&#39;;
$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(&#39;0.0.0.0&#39;, 9501);
$http->on(&#39;Request&#39;, 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(&#39;Request&#39;, 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(&#39;Request&#39;, 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(&#39;/&#39;, function () {
    echo Swoole\Coroutine::getCid(), "<br/>";
    print_r(Swoole\Coroutine::stats());
    Swoole\Coroutine::sleep(10);
    echo "<br/>";
    echo getmypid(), "<br/>";
//    return view(&#39;welcome&#39;);
});

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(
    &#39;worker_num&#39; => 4,
      // &#39;worker_num&#39; => 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(&#39;/a&#39;, 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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer