前言在传统的PHPLNMP架构下,一些问题一直困扰着我们。由于PHP程序只能串行执行的特点,在IO密集型应用下,PHP程序只有在IO操作完成后才能执行后续代码,大部分时间都在等待IO,严重影响执行效率,这是非常不合理的。现在有这样一个场景,一个接口需要调用10个第三方Http接口才能拿到所有的数据。假设每次接口调用平均耗时300ms,在传统的PHP串行模式下,需要3秒才能执行完毕。使用基于Swoole的协程Http客户端可以解决这个问题,实现Http请求的并发调用。在实践中,我们使用传统的Http客户端与Swoole协程客户端进行对比。比较的方法是,连续N次请求淘宝首页,比较请求的总响应时间,可以直观的看出并发调用的优势。传统Http客户端显示示例$start=microtime(true);$n=50;for($i=0;$i<$n;$i++){$http=newHttp();$res=$http->get('https://www.taobao.com/');$res->getBody()->getContents();}$end=microtime(true);echobcsub($end,$start,2).PHP_EOL;Swoole协程Http客户端显示例go(function(){$start=microtime(true);//并发请求n$result=[];$clients=[];$n=50;for($i=0;$i<$n;$i++){$cli=new\Swoole\Coroutine\Http\Client('www.taobao.com',443,true);$cli->setHeaders(['Host'=>"www.taobao.com","User-Agent"=>'Chrome/49.0.2587.3','Accept'=>'text/html,application/xhtml+xml,application/xml','Accept-Encoding'=>'gzip',]);$cli->set(['超时'=>2]);$cli->setDefer();$cli->get('/');$clients[]=$cli;}for($i=0;$i<$n;$i++){如果(!$clients[$i]->recv()){继续;$result[]=$clients[$i]->body;}$end=微时间(真);echobcsub($end,$start,2).PHP_EOL;});数据分析calltimesresponsetime(coordinationProcess)responsetime(traditional)101.09s3.64s202.33s7.27s302.89s14.91s503.96s17.57s1007.33s37.23s从上面的数据可以看出协程模式的速度是传统模式的数倍,并且随着调用次数的增加,协程模式的速度优势越来越明显。这就是异步模式在IO密集场景下带来的巨大性能提升,程序的速度已经到了瓶颈,无论怎么优化,速度都没有得到质的提升,所以可以尝试使用Swoole的协程模式,可能会带来意想不到的效果。大多数web场景下,并不是我们的程序执行的慢,而是我们大部分时间都在等待IO结束。不管你怎么优化代码,提升都不明显。不如换个思路,用异步协程来解决IO等待问题。随之而来的改进是巨大的。希望本文对您有所帮助!
