实现原理

Swoole-2.0基于setjmplongjmp实现,在进行协程切换时会自动保存Zend VM的内存状态(主要是EG全局内存和vm stack)。

Swoole-4.0重构了协程内核,实现了C栈和PHP栈同时保存和切换,支持所有PHP语法。

示例代码

$server = new Swoole\Http\Server('127.0.0.1', 9501, SWOOLE_BASE);

#1
$server->on('Request', function($request, $response) {
	$mysql = new Swoole\Coroutine\MySQL();
	#2
	$res = $mysql->connect([
		'host' => '127.0.0.1',
		'user' => 'root',
		'password' => 'root',
		'database' => 'test',
	]);
	#3
	if ($res == false) {
		$response->end("MySQL connect fail!");
		return;
	}
	$ret = $mysql->query('show tables', 2);
    $response->end("swoole response is ok, result=".var_export($ret, true));
});

$server->start();

运行过程

协程开销

相比普通的异步回调程序,协程多增加额外的内存占用。

压力测试

测试结果:

Server Software:        swoole-http-server
Server Hostname:        127.0.0.1
Server Port:            9501

Document Path:          /
Document Length:        348 bytes

Concurrency Level:      100
Time taken for tests:   0.883 seconds
Complete requests:      10000
Failed requests:        168
   (Connect: 0, Receive: 0, Length: 168, Exceptions: 0)
Total transferred:      4914560 bytes
HTML transferred:       3424728 bytes
Requests per second:    11323.69 [#/sec] (mean)
Time per request:       8.831 [ms] (mean)
Time per request:       0.088 [ms] (mean, across all concurrent requests)
Transfer rate:          5434.67 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       2
Processing:     0    9   9.6      6      96
Waiting:        0    9   9.6      6      96
Total:          0    9   9.6      6      96

Percentage of the requests served within a certain time (ms)
  50%      6
  66%      9
  75%     11
  80%     12
  90%     19
  95%     27
  98%     43
  99%     51
 100%     96 (longest request)