昨天在v2ex上分享了PHP7.3+Swoole4.4/Go1.13/MixPHP2.2/Beego1.12性能对比。不少网友对此提出质疑。不想引起争议,一时冲动,跟网友打赌10元。Questions这次的主要问题是:测试中没有数据库查询:大家觉得加入dbquery会很不一样,但是我觉得benchmark测试helloworld代表的是天花板,还是有一定意义的。db查询的性能很方便。我猜mix和beego的性能应该接近,我还没开始测试,等着看结果吧。测试未序列化:在本次测试中,我还加入了json序列化。ab测试不适合做高并发测试:我详细列举了很多例子,试图说明在相同的环境下,不同的压力下,强弱值会发生变化,但结果不变。这基本上是一个物理原理。既然无法说服对方,那我这次就用wrk测试。当然,测试中没办法保证条件绝对一致,但结果还是可以参考环境硬件CPU:Intel(R)Core(TM)i7-8700CPU@3.20GHzCPU(s):12Mem:15GLinux版本3.10.0-957.10。1.el7.x86_64数据库:本地测试命令wrk-d120-t4http://127.0.0.1:*/连接池最大空闲:5最大连接:50线程为了最大化公平,这次两个框架都使用1线程测试MixPHP2.2代码:为了公平起见,我删除了配置中的所有默认中间件,这在之前的测试中没有被删除。*/classIndexController{/***索引*@paramServerRequest$request*@paramResponse$response*@returnResponse*/publicfunctionindex(ServerRequest$request,响应$response){/**@var数据库$db*/$db=context()->get('database');$result=$db->prepare('select*fromtestlimit1')->queryAll();$content=json_encode($result);返回ResponseHelper::html($response,$content);}}启动方式/usr/local/php-7.3.12/bin/phpmix/bin/mix.phpweb-d进程[nobody@~]$ps-ef|grepmix.phpnobody259721018:36?00:00:00/usr/local/php-7.3.12/bin/phpmix/bin/mix.phpweb-d响应内容[nobody@~]$curlhttp://127.0.0.1:9501/[{"id":1,"name":"3"}]测试结果:多次测试,9936.36~10080.25左右[nobody@~]$wrk-d120-t4http://127.0.0.1:9501/Running2m测试@http://127.0.0.1:9501/4个线程和10个连接线程统计平均标准偏差最大+/-标准偏差延迟806.18us501.04us51.95ms97.58%Req/Sec2.53k245.915.92k79.283%912in2.00m,218.21MBreadRequests/sec:10080.25Transfer/sec:1.82MBCPUstatus:稳定在99.3~99.7%PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND25972nobody20011669921267094.:41.11phpBeego1.12代码:使用runtime.GOMAXPROCS(1)来限制线程数。packagemainimport("encoding/json""github.com/astaxie/beego""github.com/astaxie/beego/orm"_"github.com/go-sql-driver/mysql"_"hello/routers""runtime")typeTeststruct{Idint`orm:"column(id)"json:"id"`Namestring`orm:"column(name)"json:"name"`}funcinit(){orm.RegisterModel(new(Test))orm.RegisterDriver("mysql",orm.DRMySQL)maxIdle:=5maxConn:=50orm.RegisterDataBase("default","mysql","*****@tcp(***:3306)/test?charset=utf8&loc=Asia%2FShanghai&parseTime=true",maxIdle,maxConn)}typeIndexControllerstruct{beego.Controller}func(c*IndexController)Index(){o:=orm.NewOrm();}varrow[]*Testo.Raw("select*fromtestlimit1").QueryRows(&row);js,_:=json.Marshal(row)c.Ctx.Output.Body(js)}funcmain(){runtime.GOMAXPROCS(1)//限制使用的线程数beego.Router("/index",&IndexController{},"*:Index")beego.Run()}启动方式屏蔽输出,不让日志影响性能。nohup./gobeego_linux>/dev/null2>&1&进程[nobody@~]$ps-ef|grepbeenobody273161018:37?00:00:00./gobeego_linuxresponsecontent[nobody@~]$curlhttp://127.0.0.1:8989/index[{"id":1,"name":"3"}]测试结果:测试了很多次,大约16306.15~16327.19[nobody@~]$wrk-d120-t4http://127.0.0.1:8989/indexRunning2mtest@http://127.0.0.1:8989/index4个线程和10个连接线程StatsAvgStdevMax+/-StdevLatency521.18us427.56us29.46ms92.23%Req/Sec4.10k260.694.74k79.96%2.00m中的1959389个请求,310.19MBreadRequests/sec:16327.19MB:stableatCPU:5status/sec约99.7~100.3%。PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND27316nobody200114736106605008S100.30.10:39.87gobeego_linux修改执行模式有网友评论:beegodev模式性能会变差,重新测试修改执行模式改为prod测试发现prod的性能比dev高2666左右。Requests/sec[nobody@tmp]$catconf/app.confappname=hellohttpport=8989runmode=prod测试结果[nobody@~]$wrk-d120-t4http://127.0.0.1:8989/indexRunning2mtest@http://127.0.0.1:8989/index4个线程和10个连接ThreadStatsAvgStdevMax+/-StdevLatency453.55us427.00us29.69ms93.22%Req/Sec4.77k328.515k82.71%2279372requestsin2.00m,299.98MBreadRequests/sec:18993.39Transfer/sec:2.50MB为了避免测试数据在不同时间浮动,还要测试MixPHP[nobody@tmp]$wrk-d120-t4http://127.0.0.1:9501/Running2mtest@http://127.0.0.1:9501/4个线程和10个连接线程统计AvgStdevMax+/-StdevLatency821.18us347.98us20.65ms89.92%Req/Sec2.47k227.035.80k81.13%1181243requestsin2.00m,212.91MBreadRequests/sec:9835.54Transfer/sec:1.77MB去掉序列化,只测试数据库有网友评论:PHP的json_encode可能是性能不好的原因,所以重新测试MixPHP代码修改*/classIndexController{/***Index*@paramServerRequest$request*@paramResponse$response*@returnResponse*/公共函数索引(ServerRequest$request,Response$response){/**@varDatabase$db*/$db=context()->get('database');$result=$db->prepare('select*fromtestlimit1')->queryAll();$content='你好,世界!';//不序列化returnResponseHelper::html($response,$content);}}测试结果[nobody@tmp]$wrk-d120-t4http://127.0.0.1:9501/运行2m测试@http://127.0.0.1:9501/4个线程和10个连接线程统计平均标准偏差最大+/-标准偏差延迟819.22us309.68us23.65ms87.91%Req/Sec2.47k221.663.07k76.21%1179327requestsin2.00m,203.57MBreadRequests/sec:9827.51Transfer/sec:1.70MBBeego代码修改packagemainimport("encoding/json""github.com/astaxie/beego""github.com/astaxie/beego/orm"_"github.com/go-sql-driver/mysql"_"hello/routers""runtime")typeTeststruct{Idint`orm:"column(id)"json:"id"`名称字符串`orm:"column(name)"json:"name"`}funcinit(){orm.RegisterModel(new(Test))orm.RegisterDriver("mysql",orm.DRMySQL)maxIdle:=5maxConn:=50orm.RegisterDataBase("default","mysql","*****@tcp(***:3306)/test?charset=utf8&loc=Asia%2FShanghai&parseTime=true",maxIdle,maxConn)}typeIndexControllerstruct{beego.Controller}func(c*IndexController)Index(){o:=orm.NewOrm();varrow[]*Testo.Raw("select*fromtestlimit1").QueryRows(&row);js:=[]byte("hello,world!")//不序列化c.Ctx.Output.Body(js)}funcmain(){runtime.GOMAXPROCS(1)//限制使用的线程数beego.Router("/index",&IndexController{},"*:Index")beego.Run()}测试结果[nobody@tmp]$wrk-d120-t4http://127.0.0.1:8989/indexRunning2m测试@http://127.0.0.1:8989/索引4个线程和10个连接线程统计AvgStdevMax+/-StdevLatency436.00us363.84us24.06ms92.74%Req/Sec4.94k319.795.99k79.62%2358720requestsin2.00m,292.43MBreadRequests/sec:19652.80Transfer/sec:2.44MB综合测试结果,mix综合性能比beego数据库查询+序列化低38.3%,beego更胜一筹,但是很有可能mixdynamicscriptinglanguage可以做到这一点(我只能这样安慰自己,但这也是事实),显然我赌输了我愿意承认框架线程数CPU值PHP7.3.12+Swoole4.4.14+MixPHP2.2199.3~99.7%9936.36~10080.25Go1.13.4+Beego1.12.1199.7~100.3%16306.15~16327.19开启beegoprod模式并更改模式后,beego性能提升测试结果表明,mix的综合性能比beego数据库查询+序列化低48.2%。框架线程数PHP7.3.12+Swoole4.4.14+MixPHP2.219835.54Go1.13.4+Beego1.12.1118993.39去掉序列化,只测试数据库去掉序列化后,测试结果变化很小,说明序列化是在这个测试中的影响是非常小的,也就是说,相对于db查询,序列化对整体性能的影响比我们想象的要小很多。框架线程数PHP7.3.12+Swoole4.4.14+MixPHP2.219827.51Go1.13.4+Beego1.12.1119652.80
