Python aiohttp 异步 需要同时请求同域名下 8000 个 URL(对方网站无并发限制)把结果拼接返回,要求总耗时最短, 8000 个同时发还是先发 1000 个,不等待结果,间隔 0.1 秒再发下一批快?

121 天前
 drymonfidelia
爬虫,所有同行爬的都比我们快,不知道为什么
别人 1 秒更新,我们上了 10 台服务器还是慢别人 3 秒
2414 次点击
所在节点    程序员
43 条回复
so1n
121 天前
一个请求一个 task 不就异步了?可以并发 n 个
drymonfidelia
121 天前
@so1n 并发 8000 个要 3 秒多的话才能全爬完一组 8000 个,但是单请求一个耗时只有 0.15 秒
业务实时更新接近 9 万个 URL 的数据,同行不知道怎么做到的延迟不到一秒,我们用了 10 台服务器都做不到
drymonfidelia
121 天前
爬的是国外的站,对方的站套了 cdn 不知道是什么机房,已经选了测试出来的耗时最短的云买服务器爬了
drymonfidelia
121 天前
对方套的是 akamai 的 cdn ,测试出来 azure 耗时最短
locoz
121 天前
什么使用场景会需要实时更新近 9W 个 URL 的数据,还有同行以秒级差距进行竞争,并且同行的时效性还能被看到…你确定你这情况不是 XY 问题导致的吗…
drymonfidelia
121 天前
@locoz 具体场景不方便公开,但差不多就是库存监控,有 90000 个商品,上货时间没办法提前知道,我们永远比同行慢 3 秒
drymonfidelia
121 天前
上货=>补货
drymonfidelia
121 天前
没有 API 能一次性查多个商品库存
GeekGao
121 天前
不知道你们具体的实现,但是多台机器也需要调度过程的。例如 10 台机器,每台 1000 并发。但是还是要根据机器配置来设置,得测。

CPU 、内存和网络带宽。CPU 的处理能力、内存的大小以及网络的带宽和延迟都会影响并发性能的。
phrack
121 天前
单个请求 0.15 秒是并发为 1 的情况下计算的吧?
8000 个并发的时候,假设你说的 3 秒,这应该是从你程序代码里计算的吧,还得细化,
1. 从程序调了 API 发出这个包到这个包从内核发出去的时间差
2. 从内核上包发出去之后,接收到对方服务器返回包的时间差
3. 从内核接收到包,到程序解析完这个包的时间差

还有几个可能需要细化的地方,思路就是得判断这 3 秒到底花在哪里了,3 秒相对 0.15 秒长太多了,为什么并发 8000 的时候多出来了这么多。

现在的计算机这么牛逼处理 8000 并发我感觉轻轻松松(我瞎估计的哈),如果是这样呢那就是对方 CDN ,WAF 之类的给 IP 限速了,虽然你说了没有限制但我感觉不太可能呢。
drymonfidelia
121 天前
@GeekGao 纯发请求消耗不了多少 CPU 和内存吧, azure 带宽至少 1Gbps, 看起来是足够了
@phrack 确实是在代码里通过全部请求收到返回-首个请求发送前时间, 精确到毫秒计算的. 从内核发出的时间要怎么看, 在服务器上抓包么?
phrack
121 天前
@drymonfidelia 那你这样算还有一个地方得细化,你得计算每个请求花的时间而不是从所有请求完成后减去第一个请求发送时间,然后先看一下这 8000 个请求花的时间的总体统计分布,基于时间的统计分布(有个问题是先发出去的包是有可能后到对方服务器的,这个还得考虑进去,有办法可以做到先发的先到,也可以做到 8000 个请求几乎同时到,具体搜索 last-byte-sync, single-packet-attack )

反正你就是得先判断这 3 秒里面到底发生了什么,不然就是瞎猫抓耗子,碰巧某个解决方案成功了你还是不知道到底怎么回事。
phrack
121 天前
@drymonfidelia 要在服务器上抓包,怕影响性能也可以上级路由器镜像流量在另一台服务器抓,不过我感觉影响不大。
drymonfidelia
121 天前
其实是某拍卖平台的自动出价系统, 需要实时监控价格有没有被超过, 高峰期最多有 9 万条链接接近截止时间, 延迟 3 秒体验影响很大的, 同行能做到实时
平台本身推送但是延迟还不止 3 秒
@locoz
lesismal
121 天前
暂时想到几点,OP 可以参考下:
1. 多用一些出口 IP ,对方没有限制并发可能是不直接报错但对单 IP 高频可能也有频率限制
2. 是每个请求一个短链接吗?还是 keepalive 的复用长连接?如果是 keepalive 复用长连接,http 1.x 很多不支持 pipeline 的所以要请求-响应然后才发下一个这就比较慢了,如果是 http2.0 又有 4 层线头阻塞的问题、并发量大了也是慢的很,所以也确认清楚这个
3. py 的实现是怎样的,for 循环发送 8000 个? 10 台机器每个节点 for 循环 800 个?这个 for 循环调用所有请求一共多久?请求回来再处理、虽然是异步的但是处理响应的代码是 py 的吧?有没有把这部分也统计上?
4. 对比下其他语言的实现?比如 go ,如果姿势 http 请求也是比较容易的
5. 会不会有订阅机制、竞品订阅了实时收到通知?

实在不行加上抓包分析下网络吧
lesismal
121 天前
再不济,加钱请技术咨询来协助定位、开发
lovelylain
120 天前
@drymonfidelia 补货时间没法提前知道,于是你们不停访问页面判断有没有补货,中间不带 sleep ?这算 ddos 了吧,有 sleep 的话没办法保证你 sleep 的那间隙没补货啊。
Hopetree
120 天前
我觉得你可以先 100 ,然后 1000,2000...8000 试探,看看到底是从多少并发开始变慢的
opengps
120 天前
有没有可能,对方已经压测到极限了,你才过来加上你的压力。注意压崩了要负责的
shuax
120 天前
有没有可能加上缓存,带上 etag 什么的,没变化就快速返回,或者 GET 之前先 HEAD 一下,看看有没有变动。根据我的经验,并发过多以后反而会变慢,可能竞争加大了,我习惯开 128 个并发。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1017387

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX