Swoole2.0是一個革命性的版本,它內置了協程的支持。與Go語言協程不一樣,Swoole協程徹底不須要開發者添加任何額外的關鍵詞,直接以過去最傳統的同步阻塞模式編寫代碼,底層自動進行協程調度實現異步IO。使併發編程變得很是簡單。php
最新的版本中,內置協程已支持PHP7,同時兼具了性能和併發能力,Swoole的強大超乎想象。mysql
本文基於Github最新的Swoole2.0.3版本進行了併發壓力測試,來驗證Swoole內置協程的併發能力。nginx
$server = new Swoole\Http\Server('127.0.0.1', 9501, SWOOLE_BASE); $server->set(array('worker_num' => 1)); $server->on('Request', function($request, $response) { $mysql = new Swoole\Coroutine\MySQL(); $res = $mysql->connect(['host' => '127.0.0.1', 'user' => 'root', 'password' => 'root', 'database' => 'test']); if ($res == false) { $response->end("MySQL connect fail!"); return; } $ret = $mysql->query('select sleep(1)'); $response->end("swoole response is ok, result=".var_export($ret, true)); }); $server->start();
代碼很是簡單,使用BASE模式建立一個Http服務器,而且設置進程爲1,收到Http請求後執行一條select sleep(1)
語句,這條SQL模擬了阻塞IO,MySQL的服務器在1秒後返回結果。傳統的同步阻塞程序,啓動1個進程,毫無疑問只能提供1QPS的處理能力。而Swoole2.0協程不一樣,它雖然使用同步阻塞方式編寫代碼,可是底層確是異步IO,即便SQL語言執行時間很長,也能夠提供很大的併發能力。sql
php server.php ps aux|grep server.php htf 13142 0.6 0.2 328480 42268 pts/24 S+ 10:17 0:00 php server.php
ab -c 100 -n 1000 http://127.0.0.1:9501/ This is ApacheBench, Version 2.3 <$Revision: 1706008 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Completed 1000 requests Finished 1000 requests Server Software: swoole-http-server Server Hostname: 127.0.0.1 Server Port: 9501 Document Path: / Document Length: 85 bytes Concurrency Level: 100 Time taken for tests: 10.061 seconds Complete requests: 1000 Failed requests: 0 Total transferred: 233000 bytes HTML transferred: 85000 bytes Requests per second: 99.39 [#/sec] (mean) Time per request: 1006.092 [ms] (mean) Time per request: 10.061 [ms] (mean, across all concurrent requests) Transfer rate: 22.62 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 1.3 0 7 Processing: 1000 1004 4.7 1002 1020 Waiting: 1000 1004 4.7 1002 1020 Total: 1000 1005 5.8 1003 1026 Percentage of the requests served within a certain time (ms) 50% 1003 66% 1004 75% 1005 80% 1006 90% 1016 95% 1020 98% 1022 99% 1022 100% 1026 (longest request)
ab -c 1000 -n 2000 http://127.0.0.1:9501/ This is ApacheBench, Version 2.3 <$Revision: 1706008 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient) Completed 200 requests Completed 400 requests Completed 600 requests Completed 800 requests Completed 1000 requests Completed 1200 requests Completed 1400 requests Completed 1600 requests Completed 1800 requests Completed 2000 requests Finished 2000 requests Server Software: swoole-http-server Server Hostname: 127.0.0.1 Server Port: 9501 Document Path: / Document Length: 19 bytes Concurrency Level: 1000 Time taken for tests: 2.025 seconds Complete requests: 2000 Failed requests: 153 (Connect: 0, Receive: 0, Length: 153, Exceptions: 0) Total transferred: 344098 bytes HTML transferred: 48098 bytes Requests per second: 987.66 [#/sec] (mean) Time per request: 1012.493 [ms] (mean) Time per request: 1.012 [ms] (mean, across all concurrent requests) Transfer rate: 165.94 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 6 6.6 8 18 Processing: 8 166 336.4 68 2006 Waiting: 8 166 336.4 68 2006 Total: 8 173 340.6 83 2022 Percentage of the requests served within a certain time (ms) 50% 83 66% 87 75% 89 80% 90 90% 1021 95% 1087 98% 1092 99% 1093 100% 2022 (longest request)
Length: 153 錯誤是由於MySQL服務器已經沒法支持這麼大併發了,拒絕了swoole的鏈接,所以會拋出錯誤。shell
爲了進行對比,本文還作了php-fpm的測試。一樣使用PHP7,修改php-fpm.conf將php-fpm進程設置爲1。測試的代碼與Swoole的徹底一致,也是執行同一個sleep的SQL語句。 由於php-fpm是真正的同步阻塞,耗時太長,所以只能使用併發10請求100的方式測試。apache
測試代碼:編程
$db = new mysqli; $db->connect('127.0.0.1', 'root', 'root', 'test'); $result = $db->query("select sleep(1)"); if ($result) { print_r($result->fetch_all()); } else die(sprintf("MySQLi Error: %s", mysqli_error($link)));
ab -c 10 -n 100 http://127.0.0.1/mysql.php This is ApacheBench, Version 2.3 <$Revision: 1706008 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 127.0.0.1 (be patient).....done Server Software: nginx/1.10.0 Server Hostname: 127.0.0.1 Server Port: 80 Document Path: /mysql.php Document Length: 69 bytes Concurrency Level: 10 Time taken for tests: 100.086 seconds Complete requests: 100 Failed requests: 0 Total transferred: 24100 bytes HTML transferred: 6900 bytes Requests per second: 1.00 [#/sec] (mean) Time per request: 10008.594 [ms] (mean) Time per request: 1000.859 [ms] (mean, across all concurrent requests) Transfer rate: 0.24 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.1 0 0 Processing: 1002 9558 1636.0 10008 10011 Waiting: 1002 9558 1636.0 10008 10011 Total: 1002 9558 1636.0 10008 10011 Percentage of the requests served within a certain time (ms) 50% 10008 66% 10009 75% 10009 80% 10009 90% 10009 95% 10010 98% 10010 99% 10011 100% 10011 (longest request)
能夠看到Swoole服務器,即便SQL語句要執行1秒才返回結果,併發100的測試中也提供了100qps的能力,併發1000的測試中QPS爲987,但MySQL服務器已經沒法提供服務了。而同步阻塞的php-fpm處理併發10請求100的測試花費了100秒才完成,QPS爲1。服務器
Swoole2.0的內置協程將來可能會顛覆現代軟件的開發模式。swoole