V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xiaobaiyihao
V2EX  ›  程序员

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

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


    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
        9
    rekulas   5 天前
    原生 php 不好搞,考虑加个微服务 api 实现吧,也就半小时就撸出来了
    honkki
        10
    honkki   5 天前
    单独新写一个服务并发请求返回结果呢
    Actrace
        11
    Actrace   5 天前
    楼主要说一下运行环境,是 CLI 还是 CGI 。
    heybuddy
        12
    heybuddy   5 天前 via iPad
    guzzle 可以做并发请求的,好像是用协程实现的
    sagaxu
        13
    sagaxu   5 天前
    curl_multi 是你目前最靠谱的选项,拿 Go 提炼重写服务你就多了个服务治理,引入 Swoole 解决了 1 个简单问题带来了 10 个困难问题更不靠谱
    fiypig
        14
    fiypig   5 天前 via iPhone
    试试 go ?
    zjsxwc
        15
    zjsxwc   5 天前 via Android
    写错:
    “这个具体使用 poll 还是 epoll 哪个得看 curl 的编译参数”

    需要改成

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

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

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

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

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

    Responses are always asynchronous, so that the call to the method returns immediately instead of waiting to receive the response:

    https://symfony.com/doc/current/http_client.html

    用这个没错的,解析 Response 的时候才会阻塞,很好用的。
    liuyibao
        22
    liuyibao   4 天前
    symfony/http-client 搜了下源码,好像是用 yield 实现的,性能应该是可以的,只有 php7 以上能用。php8 增加的 fiber 会更强悍。
    zjsxwc
        23
    zjsxwc   4 天前
    @xiaobaiyihao

    > "@dusu fpm,性能每次请求必须在 300 ~ 400ms 内答应,百万吧,现在的情况就是卡在这个 curl_multi 请求上,> 本身这个接口也是高并发接口,接口内部要去并发请求其他接口"

    300 ~ 400ms 内 百万请求,用什么 php 啊, 你带宽都要 2.5Gbps 了
    zjsxwc
        24
    zjsxwc   4 天前
    @xiaobaiyihao

    > "@dusu fpm,性能每次请求必须在 300 ~ 400ms 内答应,百万吧,现在的情况就是卡在这个 curl_multi 请求上,> 本身这个接口也是高并发接口,接口内部要去并发请求其他接口"

    300 ~ 400ms 内 百万请求,用什么 php 啊, 你带宽都要 6Gbps 了
    xiaobaiyihao
        25
    xiaobaiyihao   4 天前
    @zjsxwc 现在就是怼机器来着,想办法优化
    xiaobaiyihao
        26
    xiaobaiyihao   4 天前
    @liuyibao 这个好像不支持 protobuf
    xiaobaiyihao
        27
    xiaobaiyihao   4 天前
    @zjsxwc 而且这是要求,现在就是达不到这种情况
    Actrace
        28
    Actrace   4 天前
    @xiaobaiyihao 更换到 CLI 下会有更多选择。PHP 内置了不少多线程,事件库,甚至可以用协程。可以单独写成一个服务,驻后台运行。
    changz
        29
    changz   4 天前
    @zjsxwc poll/select 在这种场景下性能不会比 epoll 低。。。
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1194 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 16ms · UTC 17:59 · PVG 01:59 · LAX 10:59 · JFK 13:59
    ♥ Do have faith in what you're doing.