昨天在 v2ex 分享了一下 PHP7.3+Swoole4.4 / Go1.13 / MixPHP2.2 / Beego1.12 性能對比 被不少網友質疑,本不想引發爭端,但一時衝動和網友打賭了 10 塊錢。php
本次主要質疑的是:html
固然測試沒辦法作到條件絕對一致的,但結果仍是能夠參考的
硬件mysql
數據庫:linux
測試命令git
wrk -d 120 -t 4 http://127.0.0.1:*/
鏈接池github
線程數web
1
個線程測試代碼:爲了公平,我把配置裏的默認中間件都移除了,以前測試沒有移除。sql
<?php namespace App\Web\Controllers; use App\Common\Helpers\ResponseHelper; use Mix\Http\Message\ServerRequest; use Mix\Http\Message\Response; /** * Class IndexController * @package App\Web\Controllers * @author liu,jian <coder.keda@gmail.com> */ class IndexController { /** * Index * @param ServerRequest $request * @param Response $response * @return Response */ public function index(ServerRequest $request, Response $response) { /** @var Database $db */ $db = context()->get('database'); $result = $db->prepare('select * from test limit 1')->queryAll(); $content = json_encode($result); return ResponseHelper::html($response, $content); } }
/usr/local/php-7.3.12/bin/php mix/bin/mix.php web -d
[nobody@~]$ ps -ef | grep mix.php nobody 25972 1 0 18:36 ? 00:00:00 /usr/local/php-7.3.12/bin/php mix/bin/mix.php web -d
[nobody@~]$ curl http://127.0.0.1:9501/ [{"id":1,"name":"3"}]
9936.36~10080.25
左右[nobody@~]$ wrk -d 120 -t 4 http://127.0.0.1:9501/ Running 2m test @ http://127.0.0.1:9501/ 4 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 806.18us 501.04us 51.95ms 97.58% Req/Sec 2.53k 245.91 5.92k 79.28% 1210639 requests in 2.00m, 218.21MB read Requests/sec: 10080.25 Transfer/sec: 1.82MB
99.3~99.7%
左右。PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 25972 nobody 20 0 1166992 12368 4064 R 99.7 0.1 2:41.11 php
代碼:使用 runtime.GOMAXPROCS(1)
限制了線程數。數據庫
package main import ( "encoding/json" "github.com/astaxie/beego" "github.com/astaxie/beego/orm" _ "github.com/go-sql-driver/mysql" _ "hello/routers" "runtime" ) type Test struct { Id int `orm:"column(id)"json:"id"` Name string `orm:"column(name)"json:"name"` } func init() { orm.RegisterModel(new(Test)) orm.RegisterDriver("mysql", orm.DRMySQL) maxIdle := 5 maxConn := 50 orm.RegisterDataBase("default", "mysql", "*****@tcp(***:3306)/test?charset=utf8&loc=Asia%2FShanghai&parseTime=true", maxIdle, maxConn) } type IndexController struct { beego.Controller } func (c *IndexController) Index() { o := orm.NewOrm(); var row []*Test o.Raw("select * from test limit 1").QueryRows(&row); js, _ := json.Marshal(row) c.Ctx.Output.Body(js) } func main() { runtime.GOMAXPROCS(1) // 限制使用線程數 beego.Router("/index", &IndexController{}, "*:Index") beego.Run() }
爲了避免讓日誌影響到性能,屏蔽輸出。json
nohup ./gobeego_linux > /dev/null 2>&1 &
[nobody@~]$ ps -ef| grep bee nobody 27316 1 0 18:37 ? 00:00:00 ./gobeego_linux
[nobody@~]$ curl http://127.0.0.1:8989/index [{"id":1,"name":"3"}]
16306.15~16327.19
左右[nobody@~]$ wrk -d 120 -t 4 http://127.0.0.1:8989/index Running 2m test @ http://127.0.0.1:8989/index 4 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 521.18us 427.56us 29.46ms 92.23% Req/Sec 4.10k 260.69 4.74k 79.96% 1959389 requests in 2.00m, 310.19MB read Requests/sec: 16327.19 Transfer/sec: 2.58MB
99.7~100.3%
左右。PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 27316 nobody 20 0 114736 10660 5008 S 100.3 0.1 0:39.87 gobeego_linux
有網友評論:beego dev 模式性能會差一些,因而從新測試
prod
測試發現 prod
比 dev
性能高大概 2666
Requests/sec
[nobody@tmp]$ cat conf/app.conf appname = hello httpport = 8989 runmode = prod
[nobody@~]$ wrk -d 120 -t 4 http://127.0.0.1:8989/index Running 2m test @ http://127.0.0.1:8989/index 4 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 453.55us 427.00us 29.69ms 93.22% Req/Sec 4.77k 328.51 5.70k 82.71% 2279372 requests in 2.00m, 299.98MB read Requests/sec: 18993.39 Transfer/sec: 2.50MB
爲避免不一樣時間的測試數據浮動,同時也再測試一下 MixPHP
[nobody@tmp]$ wrk -d 120 -t 4 http://127.0.0.1:9501/ Running 2m test @ http://127.0.0.1:9501/ 4 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 821.18us 347.98us 20.65ms 89.92% Req/Sec 2.47k 227.03 5.80k 81.13% 1181243 requests in 2.00m, 212.91MB read Requests/sec: 9835.54 Transfer/sec: 1.77MB
有網友評論:PHP 的 json_encode 多是性能差的緣由,因而從新測試
代碼修改
<?php namespace App\Web\Controllers; use App\Common\Helpers\ResponseHelper; use Mix\Http\Message\ServerRequest; use Mix\Http\Message\Response; /** * Class IndexController * @package App\Web\Controllers * @author liu,jian <coder.keda@gmail.com> */ class IndexController { /** * Index * @param ServerRequest $request * @param Response $response * @return Response */ public function index(ServerRequest $request, Response $response) { /** @var Database $db */ $db = context()->get('database'); $result = $db->prepare('select * from test limit 1')->queryAll(); $content = 'hello, world!'; // 不序列化 return ResponseHelper::html($response, $content); } }
測試結果
[nobody@tmp]$ wrk -d 120 -t 4 http://127.0.0.1:9501/ Running 2m test @ http://127.0.0.1:9501/ 4 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 819.22us 309.68us 23.65ms 87.91% Req/Sec 2.47k 221.66 3.07k 76.21% 1179327 requests in 2.00m, 203.57MB read Requests/sec: 9827.51 Transfer/sec: 1.70MB
代碼修改
package main import ( "encoding/json" "github.com/astaxie/beego" "github.com/astaxie/beego/orm" _ "github.com/go-sql-driver/mysql" _ "hello/routers" "runtime" ) type Test struct { Id int `orm:"column(id)"json:"id"` Name string `orm:"column(name)"json:"name"` } func init() { orm.RegisterModel(new(Test)) orm.RegisterDriver("mysql", orm.DRMySQL) maxIdle := 5 maxConn := 50 orm.RegisterDataBase("default", "mysql", "*****@tcp(***:3306)/test?charset=utf8&loc=Asia%2FShanghai&parseTime=true", maxIdle, maxConn) } type IndexController struct { beego.Controller } func (c *IndexController) Index() { o := orm.NewOrm(); var row []*Test o.Raw("select * from test limit 1").QueryRows(&row); js := []byte("hello, world!") // 不序列化 c.Ctx.Output.Body(js) } func main() { runtime.GOMAXPROCS(1) // 限制使用線程數 beego.Router("/index", &IndexController{}, "*:Index") beego.Run() }
測試結果
[nobody@tmp]$ wrk -d 120 -t 4 http://127.0.0.1:8989/index Running 2m test @ http://127.0.0.1:8989/index 4 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 436.00us 363.84us 24.06ms 92.74% Req/Sec 4.94k 319.79 5.99k 79.62% 2358720 requests in 2.00m, 292.43MB read Requests/sec: 19652.80 Transfer/sec: 2.44MB
測試結果 mix 比 beego 數據庫查詢+序列化的綜合性能要低 38.3%
,beego 更加優秀,不過 mix 動態腳本語言能作到這樣也是蠻能夠了(我只能這樣安慰本身,但也是事實),顯然我打賭輸了,願賭服輸。
框架 | 線程數 | CPU | 數值 |
---|---|---|---|
PHP 7.3.12 + Swoole 4.4.14 + MixPHP 2.2 | 1 | 99.3~99.7% | 9936.36~10080.25 |
Go 1.13.4 + Beego 1.12.1 | 1 | 99.7~100.3% | 16306.15~16327.19 |
更換模式後 beego 性能獲得了顯著提高,測試結果 mix 比 beego 數據庫查詢+序列化的綜合性能要低 48.2%
。
框架 | 線程數 | 數值 |
---|---|---|
PHP 7.3.12 + Swoole 4.4.14 + MixPHP 2.2 | 1 | 9835.54 |
Go 1.13.4 + Beego 1.12.1 | 1 | 18993.39 |
移除序列化後測試結果變化很是小,說明序列化在這個測試中影響很小,也就是序列化相對於 db 查詢來講,對總體性能影響比咱們想象的要小不少。
框架 | 線程數 | 數值 |
---|---|---|
PHP 7.3.12 + Swoole 4.4.14 + MixPHP 2.2 | 1 | 9827.51 |
Go 1.13.4 + Beego 1.12.1 | 1 | 19652.80 |