求教。。最近项目做促销,是外卖系统 然后出现 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 站大神多,求帮助
1
simapple 2018-03-27 13:13:26 +08:00
异步处理
|
2
ovear 2018-03-27 13:15:07 +08:00
缓存一下
|
3
explon 2018-03-27 13:17:10 +08:00 via iPhone
系统底层连接数改大
|
7
ovear 2018-03-27 13:27:00 +08:00
@solaro #5 如果是新用户的话,那就把这个定位接口分开来。
全站 502 的话,如果是 lnmp 就加大 phpcgi 的进程数,如果是 lamp,就开 apache 的进程数 外部 curl 降低超时时间,比如说外部 api 2 秒内没返回就快速重试,或者直接报错给客户端。 |
8
eslizn 2018-03-27 13:29:22 +08:00
异步 io,不是异步处理业务
|
9
des 2018-03-27 13:30:24 +08:00 via Android
定位放在前端做?
|
10
zhangfeiwudi 2018-03-27 13:31:41 +08:00
php 不好做异步 可以把这一个模块用 node 重写 或者 楼上说的 加大 php-fpm 的个数 或者加机器
|
11
iRiven 2018-03-27 13:34:22 +08:00 via Android
同楼上,异步处理。
|
12
widdy 2018-03-27 13:38:52 +08:00
难道不应该联系 QQ 地图,加钱么!
|
14
XiaoxiaoPu 2018-03-27 13:51:04 +08:00
@solaro 在消费速度跟不上的情况下,队列会越来越长;不异步的话,等待队列就是 php-fpm 的 worker,是有限的,超出了就会 502,异步处理的话,各种异步框架接管了队列,不会有问题,就是代码逻辑变复杂了
|
15
rootx 2018-03-27 14:03:17 +08:00 via iPhone
走不同的 php 运行池 避免全站 502
|
16
collinswang 2018-03-27 14:52:59 +08:00
联系 QQ 地图,付费加大 QPS
|
17
kimmykuang 2018-03-27 14:57:18 +08:00
自己做 map,异步调用接口做地图
|
18
qinrui 2018-03-27 15:02:50 +08:00 via iPhone
获取 ip,解析地址,这些动作不都在客户端上么?为什么会在服务端超时?
|
19
qinrui 2018-03-27 15:03:32 +08:00 via iPhone
获取坐标,解析地址,不是都在客户端么?为什么服务端会超时?
|
20
tianakong 2018-03-27 16:08:39 +08:00
饿了么?
|
21
gouchaoer 2018-03-27 16:13:21 +08:00 1
首先你在 fpm 里面就不应该用 http 客户端访问第三方接口,这样导致 fpm 卡住,很快所有的 fpm worker 都满了
目前应急办法是开更多的 fpm worker,只要你内存允许,然后把 curl 的超时设置成 1s 之类的短一点的,然后换一个 pqs 更大的接口 长远上来考量的话,换语言肯定不现实,因为现在系统工作的很好就这个接口有问题,像这种需要访问第三方服务的接口你可以考虑用 swoft 或者 swoole 裸写也 ok,反正你只有一个接口,或者干脆换 go 语言,go 语言不存在阻塞问题 |
22
tanszhe 2018-03-27 16:19:38 +08:00 1
通过坐标获取附件的地址 这种业务 直接客户端调吧 不走服务器
|
23
solaro OP @des 微信里的网页,打开的时候要调 qq 地图定位,然后用户点了获取当前定位坐标,然后通过 js 上报给服务器,服务器根据 qq 的 web service 去反解析坐标的地址,就是当前位置了,然后这个 qq web service 不是还有附近推荐地址吗,类似美团那种选择附近地址那样。。所以需要实时的,后端去请求 qq web service 的时候是通过 curl,之前用 file_get_contents 更垃圾
|
24
solaro OP @collinswang 做了企业认证,从 10qps 加到 20qps,垃圾的要死,准备且高德
|
25
solaro OP @tanszhe 因为是壳封装 web,需求要求这么做,坑其实挺多的,一个 web 同时 微信、封壳(安卓、ios )都要用,封壳说白了就是 一个壳带一个 webview,md
|
27
orangeade 2018-03-27 16:58:45 +08:00 via Android
写一个类似 python aiohttp/tornado AsyncHttpclient 的东西
|
28
tanszhe 2018-03-27 17:12:27 +08:00 1
居然看见有那么多换语言的,无语。不管同步异步都是一样的。不过避免把 fpm 连接数占满你可以后台写个 php 的守护进程来单独处理这个业务这样就和其他业务分开了。更好一点的解决方案客户端提前获取用户坐标后端提前获取这个坐标的信息,这样请求可以直接返回不用调取接口了。再你可以把坐标存起来 如果发现用户的坐标和存起来的坐标距离不远就可以用已经存在的坐标信息,这样也不用调取接口了。
|
29
yogogo 2018-03-27 18:01:54 +08:00
反解析坐标地址,客户端不是就能实现了吗?
|
30
whisper219 2018-03-27 19:12:03 +08:00
解析地域信息放在客户端来做
|
31
solaro OP |
32
surfire91 2018-03-28 11:20:32 +08:00
1. 较低超时时间,增加 fpm 处理数量,不过治标不治本
2. 交钱或者换个 qps 更大的地图 api |
34
surfire91 2018-03-28 19:23:35 +08:00
没懂,服务端发 curl 不是必须的吗?该请求请求呗
|
35
solaro OP 8G 内存的 6M 阿里云
解决方案: pm=dynamic pm.start_server = 5 之前调为 10,占用了很多无用的内存 pm.mini_servers = 5 跟 start_server 保持一致 pm.max_servers = 30 之前 为 35,后降低为 30 重启 php-fpm 进程即可 感谢大家 哦对了,所有涉及百度地图的,都替换成高德了。 |
36
solaro OP 业务拆分:curl 请求太频繁导致 php 进程卡住,一个是设置超时时间 10s,另一个是降低 curl 请求数,本质上是改业务,原本大量的 curl 去请求计算两个坐标间的距离,后面改为让前端页面载入高德、qq 地图,把坐标值写再 html 中,让前端页面去调用 js sdk 计算距离。502 再也不粗线了
|
37
solaro OP 挖坟,前几天收到了腾讯地图的微信推送消息,配额提高到比高德还高
``` 现决定将免费配额大幅提升!不同接口提升的幅度不一样,比如开发者们用的最多的地址解析 /逆地址解析接口,调用量免费配额就提升到了 300 万 /日,QPS 也提升到了 1000 次;地点搜索、路线规划、关键词输入提示等常用接口的免费配额提升到了 50 万 /日,QPS 提升到了 200 次。 ``` 可以更友好的在微信公众号里做事了(可惜了,代码迁移成本较高)。 附图: ![微信图片_20190422152533.png]( https://i.loli.net/2019/04/22/5cbd6c9ead7e8.png) |