如题,业务需要同一时间请求多个第三方,abc
1> 如果a先返回,判断结果,正确的话,就将结果返回下游。业务结束。
2> 如果a返回错误,就看第二快返回的结果,如果c第二快返回,结果正确,就把c结果返回下游。业务结束。
之前使用 curl_multi 由于这函数本身的bug,一直循环,导致 超时。
理论上说,有几个第三方,就发送几次请求,而这个函数,会重复多次。
只能选天然支持并发的语言。比如go。
但依然不甘心,这些好用的框架,为啥不出个这种功能,类似go的协程呢??
期待大佬解决。
curl_multi 不会有bug,可能你用法不对。
我记得这个问题你发过帖子,下面有人回复了curl_multi用法,类似下面这样,你试下
这样会使服务器cpu占用率100%
CPU使用率
100%
为了避免100%,就需要人为设置usleep休眠。
但实际业务,对时效性要求很严,比如250毫秒。
这样大多数数据,就超时了。
还有一点,即使就一个url, do 循环内也会循环好多次。
按道理,有几个url,就循环几次。
这就属于curl_multi 函数本身的bug了吧。
所以,这种方法实际并不可行。
等下,忘记加multi_select了
为啥不支持类似swool协程呢?
想确定,swool协程可以实现这种需求吗,
golang的话,for循环就自带异步请求了。
这样就可以根据url数量来使用多个 单次curl请求了。
想用协程就用Swoole做event-loop. workerman/webman可以用swoole当event-loop,
Fiber比较新,8.1才支持,要跟进需要时间
加了一行 curl_multi_select($mh); 再试下
好的
加上之后依旧是100%,大佬
这个已经放弃了。webman使用swool协程,可以实现这种需求吗,之前没用过workerman,请大佬贴代码。。
https://www.workerman.net/q/3529
https://www.workerman.net/q/3540
多用搜索
这都是基于workerman,写的。之前没有用过这个。有没有webman版本的呀
加上 curl_multi_select($mh); 按道理不会消耗太多cpu才对。
https://www.workerman.net/page/update
webman 1.2.5 有 event-loop设置,config/server.php 里设置成设置'event_loop' => Workerman\Events\Swoole::class 则是用swoole作为底层,可以使用swoole的协程。我对swoole不熟悉,不清楚怎么和webman配合做的你的需求。
你这个接口可能要用worekrman来做了。
嗯,其实需求就是 同一时间请求多个上游,看谁先返回,判断返回结果。
由于整个过程需要300毫秒之内完成。所以 需要根据上游的数量来 同时发出 curl 动作。然后对比结果。
如果for循环的话,需要等待全部上游都返回结果值。这样就超时了。
我对swool协程也不是很清楚。不确定能不能实现这个需求??
curl_multi 原本是最适合的。但可能是本身存在的bug,导致 cpu 一直100% 。
打印下 curl_multi_select($mh); 的结果,看下都有什么值。
中间用usleep(1)来释放CPU, curl_multi这个不是BUG,官方有说明,是本身执行逻辑就如此
好的,如果使用workderman的话,用swool协程可以不用使用 curl_multi了吗
建议看下swoole的文档
@nitron 好吧。看来curl_multi有些时候还是要配合sleep。
@webman_fans ,用webman自定义进程写这个接口,用不到协程。等下我写个demo给你。
@walkor 没办法,大多建议usleep 100,但是题主这个要求300ms的,这个usleep值就有点太高,部分设置成1的似乎效果也还行
@walkor 自定义进程的话,可以通过程序实现吗,比如有2个上游,我就在这次请求种自定义两个进程,来分别用单次的curl 请求;
如果有3个上游,我就自定义3个进程来请求。
这种需求,可以实现吗?
不用那么麻烦,试下下面这个我写的例子。
如果我对swool和协程也不熟悉,不确定能不能实现。
反正现在的curl_multi 坑很多。
1是使用usleep, 本来就要求实效性很紧张的,有些需要200毫秒之内返回,还要减掉处理其他逻辑的时间,所以留给curl的时间就不多了。
2 do { 循环内,会有几千次的无效循环,才会为true,才会进行下一步},这就造成无谓的浪费了。
3 按理说,几个上游url,就请求几次。
4 这属于函数本身的bug了。
安装workerman/http-client
composer require workerman/http-client
新建 process/Api.php
配置 config/process.php
重启webman
在nginx里加一个转发配置
nginx加一个配置,将原有api请求路径的转发到 1234 端口
大佬,是这样的,我可以在程序里直接调这个方法吗,因为,上游返回之后,不是直接返回客户端的,还需要进行一些逻辑处理,才会返给客户端。
还需要回到原来的主程序中去。拼接其他的参数,才能返回客户端。
@walkor
请求上游接口的时候,也需要从主程序里,组织参数,post请求。
那你就在你原来程序里curl调用这个1234端口
怎么这么像 rpc,只不过是本地的过程调用。。
然后中间又多了一个curl调用的消耗-__,- ,反正这种涉及第三方系统调用的需求,只要中间网络有问题就GG
foreach ($urls as $url) 我看这里用了 循环,这里的循环是需要等到上一个返回之后,才会执行下一个吗,还是异步执行的呢。
@walkor
异步的
这个httpclient是异步的
嗯,调用这个方法,除了curl,webman本身有什么机制可以更快的调用吗
一般来说网络调用用什么方法速度都差不多,瓶颈不在方法,在网络。
因为,这个文件就在我本地。我这么直接调用它。
在app/controller里调用 process里的函数
或者能不能做成通用函数,写进 app/function里
@walkor @nitron
它属于不同进程,不能文件调用。性能最好的办法就是把逻辑都写在这个自定义api进程里。
直接用你原来程序里curl调用这个1234端口,本掉调用网络消耗可以忽略不计
不能在程序里,直接调用这个function,只能curl到1234端口
总之结论就是
好的,尝试一下
大佬们,config里的 count 这个值,跟 urls 的个数是相关的吗,需要调成一样的吗,还是两个无关的量。
比如有10个上游链接,config里的这个count值,需要改成10吗
count是开启的进程数
和url数量无关,它是进程数,cpu的1-3倍都行。
好的,多谢大佬们
大佬,还有一个问题,foreach 中请求,默认的超时时间,是多少
怎么自定义这个超时时间
比如自定义 260毫秒
@walkor
比如自定义post的请求数据大小
http-client没有设置post数据大小的地方。post数据大小你可以自己计算,用 strlen(http_build_query($post))。
设置超时这么设置