-
建立自定義artisan命令
php artisan make:command SwooleServer //預設在app/Console/Commans目錄下建立SwooleServer.php檔案。可借鑑我的上一遍文章Laravel 5.6 中優雅的管理 swoole 程式程式碼如下:<?php namespace App\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\App; class SwooleServer extends Command { //swoole http server instance private $server; //程式ID private $pid_file; //日誌檔案 private $log_file; /** * The name and signature of the console command. * * @var string */ protected $signature = 'swoole {action}'; /** * The console command description. * * @var string */ protected $description = 'start or stop the swoole http server'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); //指定主程式PID儲存檔案 $this->pid_file = __DIR__ . '/../../../storage/swoole_server.pid'; //日誌檔案儲存 $this->log_file = __DIR__ . '/../../../storage/logs/' . date('Ymd') . '_swoole_server.log'; if (!is_file($this->log_file)) { $resource = fopen($this->log_file, "w"); fclose($resource); } } /** * Execute the console command. * * @return mixed */ public function handle() { //獲取傳遞的操作 $arg = $this->argument('action'); switch ($arg) { case 'start': //檢測程式是否已開啟 $pid = $this->getPid(); if ($pid && \Swoole\Process::kill($pid, 0)) { $this->error("\r\nswoole http server process already exist!\r\n"); exit; } $this->server = new \Swoole\Http\Server("0.0.0.0", 9501); $this->server->set([ 'worker_num' => 8, 'daemonize' => 1, 'max_request' => 1000, 'dispatch_mode' => 2, 'pid_file' => $this->pid_file, 'log_file' => $this->log_file, 'log_level' => 3, //日誌等級 notice ]); //繫結操作類回撥函式 $app = App::make('App\Handles\SwooleServerHandle'); $this->server->on('workerstart', array($app, 'onWorkerStart')); $this->server->on('request', array($app, 'onRequest')); $this->info("\r\nswoole http server process created successful!\r\n"); $this->server->start(); break; case 'stop': if (!$pid = $this->getPid()) { $this->error("\r\nswoole http server process not started!\r\n"); exit; } if (\Swoole\Process::kill((int)$pid)) { $this->info("\r\nswoole http server process close successful!\r\n"); exit; } $this->info("\r\nswoole http server process close failed!\r\n"); break; default: $this->error("\r\noperation method does not exist!\r\n"); } } //獲取pid private function getPid() { return file_exists($this->pid_file) ? file_get_contents($this->pid_file) : false; } }
-
編寫操作類SwooleServerHandle
<?php /** * Created by PhpStorm. * User: kite */ namespace App\Handles; class SwooleServerHandle { //header Server 全域性變數的對映關係 private static $headerServerMapping = [ 'x-real-ip' => 'REMOTE_ADDR', 'x-real-port' => 'REMOTE_PORT', 'server-protocol' => 'SERVER_PROTOCOL', 'server-name' => 'SERVER_NAME', 'server-addr' => 'SERVER_ADDR', 'server-port' => 'SERVER_PORT', 'scheme' => 'REQUEST_SCHEME', ]; public function onWorkerStart($serv,$worker_id) { require __DIR__.'/../../vendor/autoload.php'; require_once __DIR__.'/../../bootstrap/app.php'; } public function onRequest($request,$response) { //server資訊 $_SERVER =[]; if (isset($request->server)) { foreach ($request->server as $k => $v) { $_SERVER[strtoupper($k)] = $v; } } //header頭資訊 if (isset($request->header)) { foreach ($request->header as $key => $value) { if (isset(self::$headerServerMapping[$key])) { $_SERVER[self::$headerServerMapping[$key]] = $value; } else { $key = str_replace('-', '_', $key); $_SERVER[strtoupper('http_' . $key)] = $value; } } } //是否開啟https if (isset($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] === 'https') { $_SERVER['HTTPS'] = 'on'; } //request uri if (strpos($_SERVER['REQUEST_URI'], '?') === false && isset($_SERVER['QUERY_STRING']) && strlen($_SERVER['QUERY_STRING']) > 0 ) { $_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING']; } //全域性的 if (!isset($_SERVER['argv'])) { $_SERVER['argv'] = isset($GLOBALS['argv']) ? $GLOBALS['argv'] : []; $_SERVER['argc'] = isset($GLOBALS['argc']) ? $GLOBALS['argc'] : 0; } //get資訊 $_GET = []; if (isset($request->get)) { foreach ($request->get as $k => $v) { $_GET[$k] = $v; } } //post資訊 $_POST = []; if (isset($request->post)) { foreach ($request->post as $k => $v) { $_POST[$k] = $v; } } //檔案請求 $_FILES =[]; if (isset($request->files)) { foreach ($request->files as $k => $v) { $_FILES[$k] = $v; } } //cookie $_COOKIE=[]; if (isset($request->cookie)) { foreach ($request->cookie as $k => $v) { $_COOKIE[$k] = $v; } } ob_start();//啟用快取區 \Illuminate\Http\Request::enableHttpMethodParameterOverride(); $kernel = app()->make(\Illuminate\Contracts\Http\Kernel::class); $laravelResponse = $kernel->handle( //Create an Illuminate request from a Symfony instance. $request = \Illuminate\Http\Request::createFromBase(new \Symfony\Component\HttpFoundation\Request($_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER, $request->rawContent())) ); $laravelResponse->send(); $kernel->terminate($request, $laravelResponse); $res = ob_get_contents();//獲取快取區的內容 ob_end_clean();//清除快取區 //輸出快取區域的內容 $response->end($res); } }
3.使用php artisan swoole start即可開啟服務,在nginx配置代理即可加速你的Restful api介面.
4.在centos7 單核 2G記憶體下的測試結果如下:
未使用swoole的吞吐量只有2.44
使用了swoole的吞吐量提升到了56.19且加大併發數吞吐量都可以維持一個水平