当前位置:K88软件开发文章中心编程语言PHPSwoole → 文章内容

Swoole Coroutine协程支持

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-15 15:55:04

sleep(1)'); $httpclient = new Swoole\Coroutine\Http\Client('0.0.0.0', 9599); $httpclient->setHeaders(['Host' => "api.mp.qq.com"]); $httpclient->set([ 'timeout' => 1]); $httpclient->setDefer(); $httpclient->get('/'); $tcp_res = $tcpclient->recv(); $redis_res = $redis->recv(); $mysql_res = $mysql->recv(); $http_res = $httpclient->recv(); $response->end('Test End');});$server->start();实现原理Swoole2.0基于setjmp、longjmp实现,在进行协程切换时会自动保存Zend VM的内存状态(主要是EG全局内存和vm stack)。示例代码$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();此程序仅启动了一个1个进程,就可以并发处理大量请求。程序的性能基本上与异步回调方式相同,但是代码完全是同步编写的运行过程调用onRequest事件回调函数时,底层会调用C函数coro_create创建一个协程(#1位置),同时保存这个时间点的CPU寄存器状态和ZendVM stack信息。调用mysql->connect时发生IO操作,底层会调用C函数coro_save保存当前协程的状态,包括Zend VM上下文以及协程描述信息,并调用coro_yield让出程序控制权,当前的请求会挂起(#2位置)协程让出程序控制权后,会继续进入EventLoop处理其他事件,这时Swoole会继续去处理其他客户端发来的RequestIO事件完成后,MySQL连接成功或失败,底层调用C函数core_resume恢复对应的协程,恢复ZendVM上下文,继续向下执行PHP代码(#3位置)mysql->query的执行过程与mysql->connect一致,也会进行一次协程切换调度所有操作完成后,调用end方法返回结果,并销毁此协程协程开销相比普通的异步回调程序,协程多增加额外的内存占用。Swoole2.0协程需要为每个并发保存zend stack栈内存并维护对应的虚拟机状态。如果程序并发很大可能会占用大量内存,取决于C函数、ZendVM 调用栈深度协程调度会增加额外的一些CPU开销压力测试环境:Ubuntu16.04 + Core I5 4核 + 8G内存 PHP7.0.10脚本:ab -c 100 -n 10000 http://127.0.0.1:9501/测试结果:Server Software: swoole-http-serverServer Hostname: 127.0.0.1Server Port: 9501Document Path: /Document Length: 348 bytesConcurrency Level: 100Time taken for tests: 0.883 secondsComplete requests: 10000Failed requests: 168 (Connect: 0, Receive: 0, Length: 168, Exceptions: 0)Total transferred: 4914560 bytesHTML transferred: 3424728 bytesRequests 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] receivedConnection Times (ms) min mean[+/-sd] median maxConnect: 0 0 0.2 0 2Processing: 0 9 9.6 6 96Waiting: 0 9 9.6 6 96Total: 0 9 9.6 6 96Percentage 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)

上一页  [1] [2] 


Swoole Coroutine协程支持