Прежде чем говорить о формальном фреймворке Swoole, давайте сначала попробуем изменить обычный фреймворк Laravel на версию Swoole, чтобы посмотреть, сможем ли мы добиться успеха. Конечно, это всего лишь эксперимент, и у нас есть много других вариантов.
Во-первых, нам нужно знать Вход в Где находится файл Ларавел? Если вы хотите изменить его, вы должны изменить его со входа. Обычно мы бы использовали public/index.php Этот файл служит единственной точкой входа для всей программы платформы. Фактически, глядя на его код, он загружается vendor/autoload.php , затем используйте Composer для управления зависимостями фреймворка. Затем, представив bootstrap/app.php , получите объект приложения всей программы.
Если вы мало что знаете о Laravel, вы можете прочитать наши предыдущие статьи и видеоролики из серии Laravel.
Поскольку вход один, то и наш ремонт в основном направлен на этот единственный вход. Давайте попробуем дальше.
Мы можем создать файл swoole_server.php непосредственно в корневом каталоге Laravel, затем скопировать код в public/index.php и удалить комментарии и некоторый бесполезный код. Как показано ниже.
<?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);
Что тогда? Помните, чем Swoole отличается от традиционной разработки на PHP? Просто сосредоточьтесь на этих различиях.
На первом этапе загрузка файла фреймворка определена, и он должен быть загружен в основной процесс. Нет необходимости в подпроцессах или сопрограммах повторно загружать его. Поэтому требование выше трогать не нужно.
На втором этапе нам нужно запустить HTTP из Swoole Сервис, я уже много раз говорил об этом, обратите внимание, что в onRequest , мы должны $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();
Это нормально? Почему бы вам сначала не попробовать. В обычных обстоятельствах вы можете не получить никаких входных или выходных данных. Почему это происходит?
Третий шаг — решить проблему ввода. Фактически, это суперглобальная переменная. Swoole середина не работает, поэтому _GET Такие переменные будут недействительны, Laravel середина Request Ни один из связанных объектов не может получить данные Понятно. Что делать? мы начинаем с onRequest Параметр из середина принимает эти данные и затем помещает их обратно в сопрограмму текущего процесса серединаиз. _GET Просто середина.
$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());
}
});
Вышеупомянутые три фрагмента кода решаются соответственно. _SERVER、_GET и
Четвертый шаг — решить проблему вывода, поместить весь вывод платформы в выходной буфер, а затем использовать Swoole из Response возвращаться.
$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);
});
Окончательно ob_start() это содержимое,Это также контент, который мы изучали ранее,Объяснений не будет. Понятно.
До сих пор,Наше простейшее преобразование кадра завершено Понятно,Спешите попробовать эффект.
Сначала определите маршрут. Или мы можем напрямую изменить маршрут по умолчанию.
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');
});
Я напечатал кучу вещей, но все они мне должны быть знакомы. Первые две — сопрограммы. ID и информация сопрограммы из вывода, то мы Swoole\Coroutine::sleep() Понятно 10 Секунды, распечатайте процесс еще раз ID 。
Затем мы открываем браузер и готовимся к доступу к двум вкладкам вместе.
// Будьте первым, кто посетит страницу
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
Вы видите Понятное? каждый onRequest События фактически открывают новую сопрограмму для обработки запроса, поэтому они являются сопрограммами. ID другой. При этом второй запрос не будет ждать пока заблокируется первый запрос. 20 Наконец в статусе сопрограммы середина мы также видим, что отображается второй запрос середина. coroutine_num Есть два,Это показывает, что в настоящее время существуют две задачи обработки сопрограмм. наконец,Процесс тот же,Все они следуют одному и тому же процессу.
По умолчанию,Приведенный выше код является основным процессом,один Worker процесс, а затем использовать возможности сопрограммы Понятно. На самом деле, этот эффект уже может мгновенно убить обычного человека. PHP-FPM Эффект Понятно. Но нам нужно в полной мере использовать производительность многоядерных машин, то есть мы включаем многопроцессорность и используем режим суперобработки «мультипроцесс + многосопрограмма». Самый простой способ, установить его напрямую HTTP процесс обслуживания Worker Кол-во достаточно.
$http->set(array(
'worker_num' => 4,
));
Теперь запустите сервер и вы увидите несколько процессов. Затем мы создаем новый тестовый маршрут.
Route::get('/a', function () {
echo Swoole\Coroutine::getCid(), "<br/>";
print_r(Swoole\Coroutine::stats());
echo "<br/>";
echo getmypid(), "<br/>";
});
Теперь посетите домашнюю страницу еще раз и это /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
)
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
Не нашел, они из процесса ID Они все разные, да?,если не заблокирован,Приоритет будет отдан процессам переключения,Если все процессы заблокированы,Затем сопрограмма создается в цикле для внутрипроцессной обработки.
Как насчет простого Laravel Преобразование завершено. Если есть какие-то ошибки, вы можете их пока игнорировать. В конце концов, мы здесь только для того, чтобы понять, как просто преобразовать некоторые фреймворки для поддержки. Swoole из формы. Это не должно использоваться в производственной среде.
Так как же нам применить его в производственной среде? Swoole Шерстяная ткань? для Laravel Что касается структуры, мы можем выбрать laravel-swoole компонент, непосредственно Composer Просто установите его. Кроме того, есть LaravelS Это также очень распространено из Laravel Swoole компоненты. ТП из Если это официально, то это доступно Swoole Компоненты расширения. Конечно, лучший выбор — иметь встроенную поддержку. Swoole из фреймворка, например Swoft、easySwoole Подождите, и мы вскоре представим, это и Laravel Очень похоже и много раз использовалось Laravel Компоненты фреймворка Hyperf 。
Интересно, правда?,Основной контент на самом деле является самым базовым контентом, который мы изучили ранее. понять,Мы никогда не говорили об этом Swoole Насколько можно добиться улучшения производительности, давайте воспользуемся сегодняшней возможностью попробовать это. Сначала восстановите домашнюю страницу, то есть выведите дефолтную из Laravel страница. Затем мы узнаем, прежде чем использовать. Серия Ларавел из окружающей среды для сравнения ab тест.
Давайте сначала посмотрим, как обычный фреймворк Laravel повлияет на мою машину.
Эта машина представляет собой всего лишь тестовую среду, никакой настройки не проводилось. 100 одновременно 1000 Запрос примерно 26 секунд, пропускная способность 37 запросов в секунду. Далее давайте рассмотрим ситуацию, когда он тоже есть на этой машине, но с дополнительным слоем виртуальных машин. Swoole После трансформации Laravel Рамка из эффекта. (При написании статьи используется виртуальная машина, а видео будет демонстрироваться непосредственно на локальной машине)
Немного преувеличено,3 секунды на выполнение одного и того же из 100 одновременно 1000 Запросов, пропускная способность 324 запроса в секунду. Десятикратное улучшение производительности – это не то, о чем можно просто говорить! и,У нас пока нет различных операций блокировки, таких как базы данных и удаленные запросы.,Если есть эти операции,Разрыв станет более очевидным.
конечно,На самом деле окружающая среда с обеих сторон различна.,Этот эксперимент не является особенно строгим.,но,Я думаю, вы также заметили разницу в силе между ними. Позже мы изучим структуру,Условно говоря, он будет более стабильным,Также более зрелый,По сравнению с нашей модифицированной версией из,Возможно, разница в производительности не будет слишком большой.,Но стабильность и тому подобное были бы лучше,Не пропустите!
Тестовый код:
https://github.com/zhangyue0503/swoole/tree/main/6.%E6%A1%86%E6%9E%B6/blog