Maison >développement back-end >tutoriel php >PHP 每小时百万级的curl请求服务器 丢失数据

PHP 每小时百万级的curl请求服务器 丢失数据

WBOY
WBOYoriginal
2016-06-06 20:47:061277parcourir

直接详细说明下场景:

服务器A会通过 curl 将数据转发到服务器B 上,服务器A 每小时转发量在百万级。
curl 请求的是服务器B上的 一个 0字节的文件 , 只要把请求记录在服务器B的nginx日志里就可以了。
现在通过两边的数据比对, 发现数据一天会丢几千条,一小时会丢一两百条。
服务器A 用curl_errno(),甚至加了curl_getinfo()判断返回的是否是200 都没有记录到curl报错
这部分丢失的curl请求, 想请教大家有什么好的分析思路跟经验可以借鉴的。

补充: 服务器间用的内网dns解析,排除了 dns解析超时的故障

求大神们支招了

回复内容:

直接详细说明下场景:

服务器A会通过 curl 将数据转发到服务器B 上,服务器A 每小时转发量在百万级。
curl 请求的是服务器B上的 一个 0字节的文件 , 只要把请求记录在服务器B的nginx日志里就可以了。
现在通过两边的数据比对, 发现数据一天会丢几千条,一小时会丢一两百条。
服务器A 用curl_errno(),甚至加了curl_getinfo()判断返回的是否是200 都没有记录到curl报错
这部分丢失的curl请求, 想请教大家有什么好的分析思路跟经验可以借鉴的。

补充: 服务器间用的内网dns解析,排除了 dns解析超时的故障

求大神们支招了

合并请求是个好的思路,并发处理过多的话,不仅是B服务器,A服务器也不见得能按照期望去处理。

或者也可以使用队列来处理,每秒并发可以控制一个量级下去请求B服务器。

  • 首先你没贴代码没办法帮你“猜”答案,以为简单的描述文字就能代替代码逻辑万万不可,我们写代码的人扣的是1和0的区别,靠描述没办法猜的。

  • 对于任何对精确度有要求的请求方式(例如你这个简单的计数),最好都不要直接用Curl,网络的不确定性是一点,如果你要发送数据给另一台主机,至少发送方要确认对方收到消息是不是?从设计程序的角度来讲,你放个空文件,与向数据库插入信息却不确认成功与否有何区别?

  • 我不懂看PHP源码,以有限的知识猜测一下,百万级的请求数大约280qps,你只交代了A服务器是转发服务器,但没有说明A服务器是多线程还是单线程,是apache模块还是cgi方式执行,并发多少,我只能告诉你,在任何并发数量下,PHP error出现的的概率都是有的,随着并发数的提高,程序无Bug的情况下3xx, 4xx, 5xx错误也都会出现,这是web服务器负载过大的正常响应,我的直觉是你没对A机进行精确统计,错误的认为服务器A所有的请求都成功执行了。这部分丢失的请求不是CURL错误,是PHP错误,所以你用CURL函数处理不到。

如果非要沿用现在的方法,建议B机接口返回成功码和失败码,A机凭借返回的code去logging。

如果我说错了,你仍然要从请求数和http请求上着手改善(不知道为什么,直觉就是不靠谱,哪怕你把B机改成纯MySQL的内存表都会比这种方式靠谱)。另外还有两点想法,1是开启CURL的多线程(不建议用CURL了),或者干脆给PHP加个多线程扩展,将PHP以守护进程运行,消除web服务器的并发瓶颈! 2是把数据分块吧,这非常重要,这种类似日志的东西,实时性没那么高,在A机积攒一万条发一次不行么?我曾抓Twitter数据,从华盛顿发往北京就是这样打包发。

以前做过实验,一次并发50个左右的请求,比较稳定。多了就开始丢失请求了。不知道为什么。

何不考虑先使用A服务器将B服务器需要的日志形式写入A服务器的磁盘某个角落,然后每分钟curl一次B服务器,让B服务器抓A服务器这一分钟的数据记录,然后写入B服务器nginx日志集?

这样每小时请求60次,甚至两边通信可做失败重传,大大减轻高并发下的网络丢包现象。具体通信时间间隔可根据每次通信传输的数据量来定,比如控制一次curl只传输1MB的内容,以保证通信正常完成。

仅提供一个思路,写这种脚本也是要花时间的,酌情考虑。

如果单纯只是记录请求的日志,建议使用UDP传输吧

合每秒才 300 左右的请求。
nginx 每秒处理 1W 请求应该不成问题。

所以,问题肯定出在 curl 上。curl 虽然负有盛名,但真的不怎么好使。

建议还是自己拼 HTTP 请求吧。

为什么要curl去?如果仅仅是为了留下日志的话。那在a的nginx上开个location。proxy到b。页面script src到a的这个location

敢问题主,你们服务器之间这样打点之后的日志分析入库是如何实现的?另,我觉得丢失数据是一定会发生的,几百万条一条也不丢失几乎都是科研而不是工程了。我同题主一样需要这样的打点并写入mysql。题主能跟我讲下现有你们的架构吗?

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn