本次测试主要测试计算密集型和io密集型三种技术的并发性能数据,使用ab工具远程连接测试

服务器:centos 7.9

workerman:4.1(select)

swoole:4.8

golang:1.17

测试命令:ab.exe -n10000 -c150 -k http://ip:port/

workerman代码:

<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';

// 创建一个Worker监听2345端口,使用http协议通讯
$http_worker = new Worker("http://0.0.0.0:5345");

// 启动4个进程对外提供服务
$http_worker->count = 4;

// 接收到浏览器发送的数据时回复hello world给浏览器
$http_worker->onMessage = function(TcpConnection $connection, Request $request)
{
    //模拟计算密集型
        // $res = 0;
        // for ($i = 0; $i < 10000; $i++) {
        //       $res += $i;
        // }
        // $connection->send($res);
        
        //模拟io密集型
        usleep(5000);
         $connection->send(file_get_contents('/root/php/thread.c'));
};




// 运行worker
Worker::runAll();

swoole(协程)代码:

<?php


use Swoole\Coroutine\Http\Server;
use function Swoole\Coroutine\run;
Co::set(['hook_flags'=> SWOOLE_HOOK_ALL]); // v4.4+版本使用此方法。
run(function () {
    $server = new Server('0.0.0.0', 8000, false);
    $server->set(array(
        'reactor_num'   => 2,     // reactor thread num
        'worker_num'    => 4,     // worker process num
    
    ));
    $server->handle('/', function ($request, $response) {
        //模拟计算密集型
        // $res = 0;
        // for ($i = 0; $i < 10000; $i++) {
        //       $res += $i;
        // }
        // $response->end($res);
        
        //模拟io密集型
        usleep(5000);
         $response->end(file_get_contents('/root/php/thread.c'));
    });
    $server->start();
});

swoole(非协程)代码:

<?php
$http = new Swoole\Http\Server('0.0.0.0', 8000);
$http->set(array(
    'reactor_num'   => 2,     // reactor thread num
    'worker_num'    => 4,     // worker process num
    
));


$http->on('request', function ($request, $response) {
    //  模拟计算密集型
        // $res = 0;
        // for ($i = 0; $i < 10000; $i++) {
        //       $res += $i;
        // }
        // $response->end($res);
        
        // 模拟io密集型
        usleep(5000);
         $response->end(file_get_contents('/root/php/thread.c'));
});

$http->start();

golang代码:

package main

import (
	"fmt"
	"net/http"
	"os"
	"runtime"
	"time"
)

func indexHandler(w http.ResponseWriter, r *http.Request) {

	//模拟计算密集型
	// ret := 0
	// for i := 0; i < 10000; i++ {
	// 	ret += i
	// }
	// fmt.Fprintf(w, fmt.Sprintf("%d", ret))

	//模拟io密集型
	time.Sleep(time.Microsecond * 5000)
	content, _ := os.ReadFile("/root/php/thread.c")
	fmt.Fprintf(w, string(content))
}

func main() {
	runtime.GOMAXPROCS(4)
	http.HandleFunc("/", indexHandler)
	http.ListenAndServe("0.0.0.0:6006", nil)
}

io密集型测试结果(Requests per second):

workerman:    701

swoole(协程): 2238

swoole(非协程): 709

golang: 2434

计算密集型测试结果(Requests per second):

workerman:   3411

swoole(协程): 2262

swoole(非协程): 3108

golang: 3710

可见在io密集型场景下,协程还是有一定优势的,现实中web服务是偏io密集型的

计算密集型场景下,swoole协程的居然比别的方式差了一截,不知是何原因

总的来说,golang无论是在计算密集还是io密集场景下都要稍优于php的workerman/swoole