PHP 并发请求有没有更好的方法

2021-09-14 14:46:29 +08:00
 xiaobaiyihao
PHP 请求多个 URL,除了用 curl_multi 函数,有没有效率更高的方法,感觉 curl 是 fork 进程来请求,效率感觉不是很高
2979 次点击
所在节点    程序员
29 条回复
zjsxwc
2021-09-14 15:46:35 +08:00
curl_multi 是基于 io 的 poll-select 的吧,没开多进程
https://github.com/curl/curl/blob/1b70748e862eaa4d2ae4b8e1d34bc3b47540af22/lib/multi.c#L2543
xiaobaiyihao
2021-09-14 16:33:39 +08:00
@zjsxwc 有没有更好的方法,现在性能卡在这里
Gunn27
2021-09-14 16:56:38 +08:00
你是要做异步请求吗? swoole 了解一下
JaguarJack
2021-09-14 17:00:51 +08:00
`composer require spatie/async` 可以了解下
zjsxwc
2021-09-14 17:11:56 +08:00
@xiaobaiyihao epoll 事件是操作系统级别的性能了,还慢,那只有加带宽了
fkdtz
2021-09-14 17:52:13 +08:00
那必须上协程啊,PHP 可以上 swoole 或者直接用 swoft
xiaobaiyihao
2021-09-14 18:03:14 +08:00
@JaguarJack 今天了解下
@zjsxwc 上不了 swoole,老项目又大不敢动扩展这些
zjsxwc
2021-09-14 19:26:05 +08:00
我错了,


php 的 curl multi 居然不是基于 epoll 的

虽然 libcurl 库对与 io 复用库是不可知的,可以让开发者在 c 代码里对 socket 使用自己实现的 io 复用库,但 libcurl 库也自带提供了基于 poll 与 select 的两种方式,这个方法名就有两个别名 curl_multi_wait 与 curl_multi_poll,这个具体使用 poll 还是 epoll 哪个得看 curl 的编译参数,当然性能都不能和 epoll 方式相提并论,

悲剧的是在 php 的 curl 拓展中 php 就使用了这个 curl_multi_wait 方法,而没有使用 epoll 方式相关的代码,所以 php 的 curl multi 比 epoll 慢也是正常,当然 poll 与 select 再拉垮仍旧比顺序执行快。

参考:
php curl 拓展提供的 php 方法 curl_multi_select 就是直接调用 libcurl 的 curl_multi_wait 函数: https://github.com/php/php-src/blob/master/ext/curl/multi.c#L185

libcurl 里默认提供的 curl_multi_wait 函数实现依赖的 curl_poll 函数代码中只用 poll 或者 select 而没有 epoll:
https://github.com/curl/curl/blob/52fab72397687467650093c86e5479cb1d759042/lib/select.c#L329
rekulas
2021-09-14 21:18:29 +08:00
原生 php 不好搞,考虑加个微服务 api 实现吧,也就半小时就撸出来了
honkki
2021-09-14 21:27:17 +08:00
单独新写一个服务并发请求返回结果呢
Actrace
2021-09-14 21:33:21 +08:00
楼主要说一下运行环境,是 CLI 还是 CGI 。
heybuddy
2021-09-14 21:37:04 +08:00
guzzle 可以做并发请求的,好像是用协程实现的
sagaxu
2021-09-14 21:39:50 +08:00
curl_multi 是你目前最靠谱的选项,拿 Go 提炼重写服务你就多了个服务治理,引入 Swoole 解决了 1 个简单问题带来了 10 个困难问题更不靠谱
fiypig
2021-09-14 21:45:10 +08:00
试试 go ?
zjsxwc
2021-09-14 22:09:33 +08:00
写错:
“这个具体使用 poll 还是 epoll 哪个得看 curl 的编译参数”

需要改成

“但 libcurl 库也默认自带提供了一个基于 poll 或 select 的两种实现的方式,这个方法有两个功能一样的别名 curl_multi_wait 与 curl_multi_poll,起具体实现使用 poll 还是 select 哪个得看 curl 的编译参数”
gBurnX
2021-09-14 23:26:12 +08:00
你想拿 PHP 做高性能,出发点就是错的。哪怕是用 java 撸个微服务都比 PHP 好。
dusu
2021-09-15 08:54:47 +08:00
cli 还是 fpm ?
效率低是几十万还是几千万页面需要在多久时间内请求完?
资源消耗配置有什么要求?
没指标没实践光靠感觉去评价
只能引来一堆语言党 解决不了问题
NjcyNzMzNDQ3
2021-09-15 09:09:20 +08:00
稳定,不安扩展就 curl_muiti,我用 cli 做好资源回收,服务器 4cpu/4g 内存的机子每秒 100 请求都不耗费资源

推荐这个库 composer require chuyskywalker/rolling-curl

设置好地址、并发数,等回调就好了

其他的 phper 楼上都说了,借用#17 的话

-----
没指标没实践光靠感觉去评价
只能引来一堆语言党 解决不了问题
star7th
2021-09-15 09:35:33 +08:00
感觉你需要异步 http 请求。试着用这个 https://github.com/star7th/htq
xiaobaiyihao
2021-09-15 09:53:09 +08:00
@JaguarJack 这个 fock 进程,性能更加扛不住
@Actrace php-fpm,这个可以换的倒是没大问题,就是不能换语言
@fiypig 不能换语言
@dusu fpm,性能每次请求必须在 300 ~ 400ms 内答应,百万吧,现在的情况就是卡在这个 curl_multi 请求上,本身这个接口也是高并发接口,接口内部要去并发请求其他接口

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/801763

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX