如何优雅的提升轮询速度

1. 运行环境

1). 当前使用的 Laravel 版本?

laravel9.6

2). 当前使用的 php/php-fpm 版本?

PHP 版本:8.1

3). 当前系统

Ubuntu 20.4

4). 业务环境

生产环境

2. 问题描述?

库里有20万台设备信息,需要不停的请求接口更新设备最新使用状态,请求接口的并发为10QPS,如何在占用最小的情况下,快速的轮询设备状态。

《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 23

为什么不考虑 Websocket ?

6个月前 评论
vscodeyyds (楼主) 6个月前
MArtian (作者) 6个月前
vscodeyyds (楼主) 6个月前
MArtian (作者) 6个月前
vscodeyyds (楼主) 6个月前
MArtian (作者) 6个月前
goStruct

用laravel自带的队列并发请求好了

6个月前 评论
vscodeyyds (楼主) 6个月前

你这边有 20 万台设备,但请求接口的并发限制为 10QPS,然后 20万台设备的每一台都需要快速的轮询接口查询设备状态,是这意思吗?快速是指多长时间更新一次?

6个月前 评论
vscodeyyds (楼主) 6个月前
php_yt (作者) 6个月前
vscodeyyds (楼主) 6个月前

我总感觉不对劲。是不是这么回事: 库里有20万台设备,这些设备是某些物联网设备之类的,比如家庭监控,智能门锁,火警报警器之类的,某国企提供的,他们有自己的系统自己的管理方式,就象一个黑盒,无从知道里面的具体情况是什么,也无从干涉比如改支持 websocket 之类的,但是,这些设备,都有唯一地址或者标识,都提供一个查询接口,可以对它通过某种方式,比如 http 请求,向其询问这些设备本身工作正常不正常。这个 10 QPS 也是这些设备的限制,每秒不能请求超过10次。

如果是物联网设备, 10QPS 足够了,题主的挑战可能是在1秒内发送20万个 http 请求并处理 20万请求得到20万的响应并入库,这个更有挑战性。如果要耗尽这10QPS,题主每秒要发200万请求。

可是物联网设备一般都是主动请求,主动向网关报备状态的。

所以我还是不理解场景到底是什么。

6个月前 评论
vscodeyyds (楼主) 6个月前
qufo (作者) 6个月前

主要是看对面的硬件设备的通信协议是啥,如果是mqtt那就简单了,订阅好主题,定时上报,统一处理就好了,而且对于实时更新设备状态,这个需求可以考虑一下,因为很多数据都无意义,只有打开设备连接即主动读取的时候才有意义;

如果还是传统的http,常规做法是使用轮询,按照你的描述是对方提供查询设备状态的API接口去查询,但是会存在很多问题:

1、多少秒轮询一次?如果遇到网络故障或者延迟,上一次轮询还没有结束,下一次又开始了要怎么处理冲突? 2、如果因为网络故障卡住了导致后续查询无法进行,要如何处理?

我的意见是:

1、其实本身这个需求就有很大的问题,20万台设备,就算处理能力能达到要求,数据量也大的惊人。既然是提供的三方API查询,本质上还是查询的对方的数据库,实时更新状态这个需求可不可以更改,改为2小时或者一天n次这样去处理?当有需要查看一台或者多台设备的时候再使用轮询,这样效率会不会更高一些?

2、优化数据存储,如我所说,绝大部分数据都是无用数据,那么这个时候可以使用mongodb去维护设备状态(物联网一般都是用mongo来保存设备状态),每次读取就去更新设备状态,记录更新时间,而我设定好的时间(例如每天的8点,14点,17点,22点)这些时间点读取的数据才计入到读取记录里,不然一个月数据量就爆炸了。

6个月前 评论

发20W的请求都要一个小时了吧

6个月前 评论
qufo 6个月前
  1. 你自己服务器的带宽限制
  2. 短时间大批量请求,协程或者异步请求 如果用传统框架试试用这个: guzzle http 批量请求
6个月前 评论
skarner

每秒钟只能更新10台设备的信息,20万 / 10(qps) / 60(秒) / 60(分) = 5.56 (小时)

即楼主这边的设备最大延迟就是5.56个小时

性能的瓶颈不在楼主这边,而是在接口提供方

楼主的需求应该是如何最大化的利用这10QPS去及时获取到最新的设备信息

把设备编号1,2,3,4,5...N,只需要把10的QPS打满即可(最好留一点余量,以防超频请求失败)

第一秒获取 1-10

第二秒获取11-20

。。。。

到了第N后指回1即可

6个月前 评论
skarner (作者) 6个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!