测试环境:centos7.9 1h2g服务器 php7.4
测试项目:每个框架写好一个接口A,然后接口A的内容是请求外部的一个接口B,接口B是一个会阻塞10s的接口,外部使用200并发同时请求框架内的接口A,然后请求框架暴露出的一个不会阻塞的接口C,测试接口C的响应时间。
备注:接口地址在线上测试时全部替换成服务器地址了,这里用本地接口代替显示
接口B代码使用golang的gin框架进行模拟:
r.GET("/ping", func(c *gin.Context) {
time.Sleep(10 * time.Second)
c.JSON(200, gin.H{
"message": "pong",
})
})
200并发测试代码也同样使用golang的gin框架进行测试:
r.GET("/testCurl", func(c *gin.Context) {
//group := sync.WaitGroup{}
num := 0
for i := 0; i < 200; i++ {
//group.Add(1)
go func() {
resp, err := http.Get("http://127.0.0.1:9999/test")
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(num, string(body))
num++
//group.Done()
}()
}
//group.Wait()
})
laravel8 使用PHP原始curl进行请求测试:
代码:
Route::get("/test",function (){
$headerArray =array("Content-type:application/json;","Accept:application/json");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://127.0.0.1:8080/ping");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_HTTPHEADER,$headerArray);
$output = curl_exec($ch);
curl_close($ch);
//$output = json_decode($output,true);
return $output;
});
webman使用原生curl进行请求测试:
代码:
Route::get("/test",function (\Webman\Http\Request $request){
$headerArray =array("Content-type:application/json;","Accept:application/json");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://127.0.0.1:8000/ping");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_HTTPHEADER,$headerArray);
$output = curl_exec($ch);
curl_close($ch);
return $output;
});
Route::get("/index",function (){
return json("ok");
});
webman使用http-client异步客户端请求测试:
代码:
Route::get("/test",function (\Webman\Http\Request $request){
$http = new Workerman\Http\Client();
$connection = $request->connection;
$http->get('http://127.0.0.1:8000/ping', function ($response)use ($connection) {
$connection->send(new Chunk($response->getBody()));
$connection->send(new Chunk('')); // 发送空的的chunk代表response结束
}, function ($exception) {
echo $exception;
});
return response()->withHeaders([
"Transfer-Encoding" => "chunked",
]);
});
Route::get("/index",function (){
return json("ok");
});
gin框架请求测试:
代码:
r.GET("/test", func(c *gin.Context) {
resp, err := http.Get("http://127.0.0.1:8000/ping")
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
c.JSON(200, string(body))
})
r.GET("/index", func(c *gin.Context) {
c.JSON(200, "ok")
})
框架 | 第一次(响应时间) | 第二次 | 第三次 | 第四次 | 第五次 |
laravel | 39.39s | 39.81s | 40.25s | 39.81s | 39.57s |
webman(20进程) | 7.59s | 1m29s | 1m39s | 1m38s | 1m45s |
webman(100进程) | 18.47s | 9.2s | 9.53s | 18.72s | 9.2s |
webman(200进程) | 175ms | 9.32s | 19.22s | 151ms | 138ms |
webman(异步请求) | 91ms | 160ms | 82ms | 80ms | 80ms |
gin | 73ms | 73ms | 73ms | 77ms | 74ms |