solaro
V2EX  ›  问与答

PHP 高并发的时候 CURL 超时咋办

  •  
  •   solaro · Mar 27, 2018 · 8126 views
    This topic created in 2972 days ago, the information mentioned may be changed or developed.

    求教。。最近项目做促销,是外卖系统 然后出现 502 错误, 因为外卖系统需要调用 qq 地图 定位获取坐标,然后再通过坐标反解析(服务端 CURL 请求 qq service )出附近地址

    排查了业务方面的,没毛病,数据库该优化的都优化了,没有慢查询。 看了 nginx,有几个访问页面请求响应时间都超过 1 秒,有的高达 3 秒。(服务器是阿里云,ping 18ms )

    最后确定了是由服务器端 CURL 请求导致的 php 卡了,那么问题来了: 1.qq 地图只有 20qps (准备换高德,这是后话),老报超限 2.curl 报了几次这个错误( local.ERROR: CURL:'Operation timed out after 5000 milliseconds with 0 out of -1 bytes received'),每次卡几秒,导致全站 502 了。。。

    v 站大神多,求帮助

    37 replies    2019-04-22 15:27:53 +08:00
    simapple
        1
    simapple  
       Mar 27, 2018
    异步处理
    ovear
        2
    ovear  
       Mar 27, 2018
    缓存一下
    explon
        3
    explon  
       Mar 27, 2018 via iPhone
    系统底层连接数改大
    solaro
        4
    solaro  
    OP
       Mar 27, 2018
    @simapple 外卖业务要实时。。。没法异步
    solaro
        5
    solaro  
    OP
       Mar 27, 2018
    @ovear 咋整????缓存一下。。。有缓存了。已定位的有缓存了,主要还是新用户涌进来
    solaro
        6
    solaro  
    OP
       Mar 27, 2018
    @explon 怎么改,求教
    ovear
        7
    ovear  
       Mar 27, 2018
    @solaro #5 如果是新用户的话,那就把这个定位接口分开来。
    全站 502 的话,如果是 lnmp 就加大 phpcgi 的进程数,如果是 lamp,就开 apache 的进程数
    外部 curl 降低超时时间,比如说外部 api 2 秒内没返回就快速重试,或者直接报错给客户端。
    eslizn
        8
    eslizn  
       Mar 27, 2018
    异步 io,不是异步处理业务
    des
        9
    des  
       Mar 27, 2018 via Android
    定位放在前端做?
    zhangfeiwudi
        10
    zhangfeiwudi  
       Mar 27, 2018
    php 不好做异步 可以把这一个模块用 node 重写 或者 楼上说的 加大 php-fpm 的个数 或者加机器
    Erskine
        11
    Erskine  
       Mar 27, 2018 via Android
    同楼上,异步处理。
    widdy
        12
    widdy  
       Mar 27, 2018
    难道不应该联系 QQ 地图,加钱么!
    male110
        13
    male110  
       Mar 27, 2018
    XiaoxiaoPu
        14
    XiaoxiaoPu  
       Mar 27, 2018
    @solaro 在消费速度跟不上的情况下,队列会越来越长;不异步的话,等待队列就是 php-fpm 的 worker,是有限的,超出了就会 502,异步处理的话,各种异步框架接管了队列,不会有问题,就是代码逻辑变复杂了
    rootx
        15
    rootx  
       Mar 27, 2018 via iPhone
    走不同的 php 运行池 避免全站 502
    collinswang
        16
    collinswang  
       Mar 27, 2018
    联系 QQ 地图,付费加大 QPS
    kimmykuang
        17
    kimmykuang  
       Mar 27, 2018
    自己做 map,异步调用接口做地图
    qinrui
        18
    qinrui  
       Mar 27, 2018 via iPhone
    获取 ip,解析地址,这些动作不都在客户端上么?为什么会在服务端超时?
    qinrui
        19
    qinrui  
       Mar 27, 2018 via iPhone
    获取坐标,解析地址,不是都在客户端么?为什么服务端会超时?
    tianakong
        20
    tianakong  
       Mar 27, 2018
    饿了么?
    gouchaoer
        21
    gouchaoer  
       Mar 27, 2018   ❤️ 1
    首先你在 fpm 里面就不应该用 http 客户端访问第三方接口,这样导致 fpm 卡住,很快所有的 fpm worker 都满了
    目前应急办法是开更多的 fpm worker,只要你内存允许,然后把 curl 的超时设置成 1s 之类的短一点的,然后换一个 pqs 更大的接口

    长远上来考量的话,换语言肯定不现实,因为现在系统工作的很好就这个接口有问题,像这种需要访问第三方服务的接口你可以考虑用 swoft 或者 swoole 裸写也 ok,反正你只有一个接口,或者干脆换 go 语言,go 语言不存在阻塞问题
    tanszhe
        22
    tanszhe  
       Mar 27, 2018   ❤️ 1
    通过坐标获取附件的地址 这种业务 直接客户端调吧 不走服务器
    solaro
        23
    solaro  
    OP
       Mar 27, 2018
    @des 微信里的网页,打开的时候要调 qq 地图定位,然后用户点了获取当前定位坐标,然后通过 js 上报给服务器,服务器根据 qq 的 web service 去反解析坐标的地址,就是当前位置了,然后这个 qq web service 不是还有附近推荐地址吗,类似美团那种选择附近地址那样。。所以需要实时的,后端去请求 qq web service 的时候是通过 curl,之前用 file_get_contents 更垃圾
    solaro
        24
    solaro  
    OP
       Mar 27, 2018
    @collinswang 做了企业认证,从 10qps 加到 20qps,垃圾的要死,准备且高德
    solaro
        25
    solaro  
    OP
       Mar 27, 2018
    @tanszhe 因为是壳封装 web,需求要求这么做,坑其实挺多的,一个 web 同时 微信、封壳(安卓、ios )都要用,封壳说白了就是 一个壳带一个 webview,md
    solaro
        26
    solaro  
    OP
       Mar 27, 2018
    @rootx 怎么操作?求指导
    orangeade
        27
    orangeade  
       Mar 27, 2018 via Android
    写一个类似 python aiohttp/tornado AsyncHttpclient 的东西
    tanszhe
        28
    tanszhe  
       Mar 27, 2018   ❤️ 1
    居然看见有那么多换语言的,无语。不管同步异步都是一样的。不过避免把 fpm 连接数占满你可以后台写个 php 的守护进程来单独处理这个业务这样就和其他业务分开了。更好一点的解决方案客户端提前获取用户坐标后端提前获取这个坐标的信息,这样请求可以直接返回不用调取接口了。再你可以把坐标存起来 如果发现用户的坐标和存起来的坐标距离不远就可以用已经存在的坐标信息,这样也不用调取接口了。
    yogogo
        29
    yogogo  
       Mar 27, 2018
    反解析坐标地址,客户端不是就能实现了吗?
    whisper219
        30
    whisper219  
       Mar 27, 2018
    解析地域信息放在客户端来做
    solaro
        31
    solaro  
    OP
       Mar 28, 2018
    @whisper219
    @yogogo

    两位大哥,是微信端的。公众号里点菜单打开 web 站的。。。
    原声版已经再开发了,之前为了兼容壳的坑,等壳废弃了,微信端全部改直接调用微信里自带的定位
    surfire91
        32
    surfire91  
       Mar 28, 2018
    1. 较低超时时间,增加 fpm 处理数量,不过治标不治本
    2. 交钱或者换个 qps 更大的地图 api
    solaro
        33
    solaro  
    OP
       Mar 28, 2018
    @surfire91 那个,服务端大量 curl 咋整
    surfire91
        34
    surfire91  
       Mar 28, 2018
    没懂,服务端发 curl 不是必须的吗?该请求请求呗
    solaro
        35
    solaro  
    OP
       Apr 16, 2018
    8G 内存的 6M 阿里云

    解决方案:
    pm=dynamic
    pm.start_server = 5 之前调为 10,占用了很多无用的内存
    pm.mini_servers = 5 跟 start_server 保持一致
    pm.max_servers = 30 之前 为 35,后降低为 30

    重启 php-fpm 进程即可

    感谢大家

    哦对了,所有涉及百度地图的,都替换成高德了。
    solaro
        36
    solaro  
    OP
       Apr 16, 2018
    业务拆分:curl 请求太频繁导致 php 进程卡住,一个是设置超时时间 10s,另一个是降低 curl 请求数,本质上是改业务,原本大量的 curl 去请求计算两个坐标间的距离,后面改为让前端页面载入高德、qq 地图,把坐标值写再 html 中,让前端页面去调用 js sdk 计算距离。502 再也不粗线了
    solaro
        37
    solaro  
    OP
       Apr 22, 2019
    挖坟,前几天收到了腾讯地图的微信推送消息,配额提高到比高德还高

    ```
    现决定将免费配额大幅提升!不同接口提升的幅度不一样,比如开发者们用的最多的地址解析 /逆地址解析接口,调用量免费配额就提升到了 300 万 /日,QPS 也提升到了 1000 次;地点搜索、路线规划、关键词输入提示等常用接口的免费配额提升到了 50 万 /日,QPS 提升到了 200 次。
    ```

    可以更友好的在微信公众号里做事了(可惜了,代码迁移成本较高)。

    附图:
    ![微信图片_20190422152533.png]( https://i.loli.net/2019/04/22/5cbd6c9ead7e8.png)
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   3138 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 97ms · UTC 13:26 · PVG 21:26 · LAX 06:26 · JFK 09:26
    ♥ Do have faith in what you're doing.