当前位置:首页 > 运维 > 正文内容

php Swoole和FPM性能对比

MuWind10个月前 (07-18)运维100

早闻Swoole因其持久化的特性有高性能高并发和语法简单的特点,突发奇想试着把汇率API项目的API部分用Swoole处理,在这里对比一下两者的性能差异

服务器配置:image.png

E5 2650V2 4核心 KVM虚拟化无超开

8G内存

程序代码和运行在SATA SSD内进行

系统:CentOS 7.9

PHP版本:8.1开启JIT,FPM使用opache

压测机配置:

image.png

i5 10400F+16G内存,好吧其实就是我自己的电脑。

压测程序:https://github.com/link1st/go-stress-testing

首先是php内置函数1w发测试:

FPM代码:

<?php
echo 'use PHP-FPM.#'.mt_rand(1000,9999);

Swoole代码在异步模式下的代码:

<?php
$http = new Swoole\Http\Server('0.0.0.0', 9501);
$http->on('Request', function ($request, $response) {
    $response->header('Content-Type', 'text/html; charset=utf-8');
    $response->end('<h1>Hello Swoole. #' . mt_rand(1000, 9999) . '</h1>');}
);
$http->start();

FPM测试结果:

image.png

Swoole异步测试结果:

image.png

Swoole异步下tp99对比FPM有了三倍的性能提升

接下来是Swoole协程模式下,下面是代码:

<?php
use Swoole\Coroutine\Http\Server;
use function Swoole\Coroutine\run;

run(function () {
    $server = new Server('127.0.0.1', 9502, false);
    $server->handle('/', function ($request, $response) {
        $response->end('<h1>Hello Swoole. #' . rand(1000, 9999) . '</h1>');
    });
    $server->start();
});

测试结果:

image.png

和异步模式下几乎无差别。

接下来是redis取值+循环输出数组,PHP-FPM代码如下:

<?php
$redis_config=array(
	'host' => "127.0.0.1", //数据库服务器
	'port' => 6379, //数据库端口
);
$arraylist = array("GBP", "HKD", "USD", "CHF", "DEM", "FRF", "SGD", "SEK", "DKK", "NOK", "JPY", "CAD", "AUD", "EUR", "MOP", "PHP", "THB", "NZD", "KRW", "RUB", "MYR", "TWD", "ESP", "ITL", "NLG", "BEF", "FIM", "INR", "IDR", "BRL", "AED", "ZAR", "SAR", "TRY", "time");
$redis = new Redis();
$redis->pconnect($redis_config['host'],$redis_config['port']);
$arList = $redis->mget($arraylist);
$array_result=array();
foreach($arList as $k => $v){
    $currency = $arraylist["$k"];
    $array_result[$currency] = $v;
}
print_r(json_encode($array_result));

Swoole:

httpServer.php:

<?php
use Swoole\Coroutine;
$http = new Swoole\Http\Server('0.0.0.0', 9501);
Coroutine::set(['hook_flags'=> SWOOLE_HOOK_ALL]);
ini_set('memory_limit','-1');
include_once('api/autoload.php');
$http->set([
    'buffer_output_size' => 128 * 1024 * 1024, //必须为数字
]);
$http->on('Request', function ($request, $response) {
    if ($request->server['path_info'] == '/favicon.ico' || $request->server['request_uri'] == '/favicon.ico') {
        $response->end();
        return;
    }
    list($controller, $action) = explode('/', trim($request->server['request_uri'], '/'));
    //根据 $controller, $action 映射到不同的控制器类和方法。
    if (method_exists($controller,$action)){
        $result_route = (new $controller)->$action($request, $response);
        $response->end($result_route);
    }else{
        $response->header('Content-Type', 'text/html; charset=utf-8');
        $response->end("API服务正常,请求内容不存在");
    }
});
$http->start();

/api/autoload.php

<?php
// API自动加载器
spl_autoload_register(function ($class) {
    include $class.'.php';
  },false);

/api/exchangeRate.php

<?php
/**
 * 汇率操作功能类 
 */
include(dirname(__DIR__).'/db/db.php');
class exchangeRate{
    public function index($request, $response){
        $arraylist = array("GBP", "HKD", "USD", "CHF", "DEM", "FRF", "SGD", "SEK", "DKK", "NOK", "JPY", "CAD", "AUD", "EUR", "MOP", "PHP", "THB", "NZD", "KRW", "RUB", "MYR", "TWD", "ESP", "ITL", "NLG", "BEF", "FIM", "INR", "IDR", "BRL", "AED", "ZAR", "SAR", "TRY", "time");
        $redis = new redisController();
        $arList = $redis->mget($arraylist);
        $array_result=array();
        foreach($arList as $k => $v){
            $currency = $arraylist["$k"];
            $array_result[$currency] = $v;
        }
        return json_encode($array_result);
    }

/db/db.php

<?php
include_once(dirname(__DIR__).'/db/redisController.php');

/db/redisController.php

<?php
/**
 * Redis操作类
 */
class redisController{
    public function mget($keys){
        include('config.php');
        $redis = new Redis();
        $redis->pconnect($redis_config['host'],$redis_config['port']);
        $value = $redis->mget($keys);
        return $value;
    }
}

测试结果:

FPM:

image.png

tp99:6.1s 但是已经出现502了(意味着有部分请求FPM是无响应的)

image.png

tp99:3s,无502,4s处理完所有请求

Swoole原理:

php中用swoole框架写好代码,在cli模式下启动后swoole会常驻后台,这样就达到了持久化,性能天生就比fpm高……

同时启动的时候就将php代码加载完毕转为机器码,对比fpm处理一次请求就要加载一次代码然后再处理的效率要高。

Swoole使用C++编写,支持一键协程化,自然效率高于FPM

“php Swoole和FPM性能对比” 的相关文章

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。