当前位置: 首页 > 后端技术 > PHP

Curl在Swoole协程中的解决方法

时间:2023-03-29 14:41:09 PHP

众所周知,在Swoole应用中,不推荐使用Curl,因为Curl会阻塞进程。本文将用实际的代码和数据,以最直观的方式让你明白为什么。最后会给出Curl在Swoole中的解决方案。不想看分析的可以直接拉到最后。比起雨润的套路,我不喜欢那些虚构的文章,还是自己写比较实用。下面直接跑代码,用数据看看为什么不推荐在Swoole中使用Curl。为了偷懒,我直接用YurunHttp的Curl和SwooleHandler代替了那些又臭又长的Curl代码。代码composer.json{"require":{"yurunsoft/yurun-http":"~3.0"}}server.phpon('workerstart',function(){\Swoole\Runtime::enableCoroutine();});$http->on('request',function($request,$response){睡眠(1);//假设各种处理时间1秒$response->end($request->get['id'].':'.date('Y-m-dH:i:s'));});$http->start();test.phpget('http://127.0.0.1:9501/?id='。$我);//请请求地址var_dump($response->body());$通道->推(1);});}for($i=0;$ipop();}$channel->close();echo'coroutinehttpclienttime:',(microtime(true)-$time).'s',PHP_EOL,PHP_EOL;//curlecho'curl:',PHP_EOL,PHP_EOL;$time=微时间(真);YurunHttp::setDefaultHandler(\Yurun\Util\YurunHttp\Handler\Curl::class);//切换为CurlHandler$channel=new\Swoole\Coroutine\Channel;for($i=0;$iget('http://127.0.0.1:9501/?id='.$i);//请请求地址var_dump($response->body());$channel->push(1);});}for($i=0;$ipop();}$channel->close();回声'卷曲时间:',(microtime(true)-$time).'s',PHP_EOL,PHP_EOL;});运行第一次运行,需要执行composerupdate,安装依赖,运行phpserver.php,启动服务器,运行phptest.php,启动Client运行结果coroutinehttpclient:string(22)》1:2019-09-1108:35:54"string(22)"0:2019-09-1108:35:54"string(22)"2:2019-09-1108:35:54"协程http客户端时间:1.0845630168915scurl:string(22)"0:2019-09-1108:35:55"string(22)"1:2019-09-1108:35:56"string(22)"2:2019-09-1108:35:57》curltime:3.0139901638031s结果分析上面代码在服务端延迟1秒后返回结果,模拟实际业务的耗时从客户端的耗时可以看出,三者Curl的请求总共需要3多秒,而协程客户端只需要1多秒。因为在前面的请求中,Curl在等待返回内容的过程中不能做其他事情。协程客户端在等待返回内容的同时,挂起当前协程,然后执行其他协程中的代码。解决方案CoroutineHttpClient使用Swoole自带的协程客户端实现,适合有一定基础的开发者使用。文档:https://wiki.swoole.com/wiki/...Guzzle-Swoole在我们的项目中,我们可能很少会直接写curl,但是我们会用到很多第三方库(比如某云的SDK)有用。这些第三方库通常使用Guzzle作为Http客户端,而Guzzle的底层也是使用Curl实现的。雨润专门针对该场景开发了Guzzle-Swoole包。引入后,这些SDK无需修改一行代码即可轻松支持协程。使用方法Execute命令直接安装依赖:composerrequireyurunsoft/guzzle-swoole~1.1全局设置处理器:request('GET','http://www.baidu.com',['verify'=>false,]);var_dump($response->getStatusCode());});手动指定Swoole处理器:useGuzzleHttp\Client;使用GuzzleHttp\HandlerStack;使用Yurun\Util\Swoole\Guzzle\SwooleHandler;go(function(){$handler=newSwooleHandler();$stack=HandlerStack::create($handler);$client=newClient(['handler'=>$stack]);$response=$client->request('GET','http://www.baidu.com',['verify'=>false,]);var_dump($response->getBody()->__toString(),$response->getHeaders());});YurunHttpYurunHttp是一个开源的支持链式操作的PHPHTTP类库,简单易用支持GET、POST、PUT、DELETE、UPDATE等所有常见请求方式,支持浏览器级Cookies管理,上传下载,设置和读取headers,Cookies,请求参数,失败重试,速度快limit、proxy、certificates等,3.0版本完美支持Curl和Swoole协程;3.2版本支持SwooleWebSocket客户端。使用方法直接执行命令安装依赖:composerrequireyurunsoft/yurun-http~3.2get('http://www.baidu.com');echo'html:',PHP_EOL,$response->body();}截至发稿,Swoole4.4新增的hookCurl仍是实验性功能。虽然雨润贡献了该功能的部分代码,但是由于兼容性工作量大,不支持的OPTION太多,个人暂时不建议使用hookCurl。大家在使用Guzzle-Swoole和YurunHttp的时候有什么问题可以在群里问我(QQ群:17916227)。

最新推荐
猜你喜欢