求一个可以限制 post 上传文件速率库

2014-10-31 17:00:28 +08:00
 Zuckonit
requests好像不能限制post上传文件的速率?
7508 次点击
所在节点    Python
22 条回复
ss098
2014-10-31 17:25:25 +08:00
浏览器客户端向服务器发送数据应该不可以限制,但服务器可以限制下载速度,因为发送多少数据是由服务器决定的,但客户端即浏览器发送数据到服务器时倘若服务器限度,但实际上已经有网络数据到达服务器,所以限制是没有用的。

个人理解,若有纰漏,欢迎指正。
zhengkai
2014-10-31 17:34:54 +08:00
为什么要限制上传……这需求太奇怪了

可以在 nginx 上设定限速(limit_req)
ryd994
2014-10-31 18:17:53 +08:00
@ss098 也有办法,利用TCP协议,延迟ACK
mengskysama
2014-11-01 00:16:16 +08:00
@ss098 从服务器下载和客户端上传完全是一回事,TCP连接在建立之后两端是一样的,没有这种关系。

@ryd994 ...延迟ACK岂不是要改协议层,延迟ACK对端会认为超时重发,信道效率更低了这有什么意义呢。

撸主可以尝试curl 加上limit-rate参数,或者hack urllib3的filepost.py在FILEIO做一些修改。
软件的限速原理都是连接缓冲区实现的,即在套接字控制read/wirte的字节数,P2P上的优先权算法实现也是通过树来设置一个合理的字节数)。
ss098
2014-11-01 00:23:16 +08:00
@ryd994
@mengskysama

感谢指正我的错误理解
ryd994
2014-11-01 10:50:18 +08:00
还有就是TCP窗口小一点
ryd994
2014-11-01 10:53:49 +08:00
@mengskysama 如果稳定的加上一个延迟的话,TCP完全能够处理,延迟大不是问题,随机性才是
ryd994
2014-11-01 11:04:31 +08:00
@mengskysama 事实上就是让客户重发,但是别忘了TCP是有拥塞算法的,重发之后就会降速。也就是说给客户端一个拥塞的假象
ryd994
2014-11-01 11:10:33 +08:00
@mengskysama 缺德一点也可以不改协议层,ipfilter 限制频率drop就行
mengskysama
2014-11-01 12:37:01 +08:00
@ryd994 我没有见到一个软件是这样做的,nginx,libtorrent,transmission等等。您不觉得这是用大炮打鸟吗,我要维持一个速度岂不是要不断丢包?明显不是这样做的。如果在win下面动协议层至少需要ndis,没有软件带这么玩的吧。
ryd994
2014-11-01 17:08:18 +08:00
@mengskysama 丢包只会drop开始那一段超速的,然后客户端的拥塞算法就会认为网络上发生拥塞,发送速度就下来了,然后后面就会一直稳定在这个速率上,既然不超速就不会发生drop。所以尽管浪费了开头那段,但是后面的包是完全没影响的。这只是在无法修改服务器代码时的一种workaround而已。

更文明的办法是调整窗口大小。ack会带上window size。这就是正规的flow control:
http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Flow_control
你说的控制读socket本质上就是这个,没读走的数据还留在系统缓冲区里,然后ack回去的window size就小了,发送方就会控制速度了。这部分都是系统tcp栈做好的轮子。
如果自己写服务器的话,确实这样做才是正解。
如果写的只是应用的话就该查http服务器的文档。

@zhengkai 你说的limit_req是限制请求频率而非传输速率。应当使用upload_limit_rate:
http://wiki.nginx.org/HttpUploadModule#upload_limit_rate
mengskysama
2014-11-01 17:46:14 +08:00
@ryd994 第一个TCP拥塞算法里只有遇到丢包才会减小窗口对吧?意味着后面我要不断丢包来保持速度,您觉得合理吗?

第二个,窗口大小和缓冲区大小没有直接联系,窗口大小是拥塞算法给的,这是种特例,就是BUF<CWND
ryd994
2014-11-01 18:05:58 +08:00
@mengskysama …………正常的连接也是不停地拥塞,减速,拥塞,减速好吧…………也就是说本来硬件丢掉的,现在软件丢掉而已,是等效的。不是说合不合理,而是说这是你无法控制代码时的唯一方法。

窗口大小不只是拥塞算法给,也会由接收方在ACK中指定,这就叫flow control啊……
http://www.tcpipguide.com/free/t_TCPWindowSizeAdjustmentandFlowControl-2.htm
缓冲区里的数据会减少ack回去的window size,这就是你之前说的方法的实际过程啊,您是不是在4层待太久了,有空也该来三层看看啊。
mengskysama
2014-11-01 18:20:47 +08:00
@ryd994 一般丢包发生在信道比较窄的时候,你用400K信道传输40K基本上不会丢包。
ryd994
2014-11-01 18:24:33 +08:00
@mengskysama 那前提是你只有这点发送啊……如果不额外指定,发送方有什么理由不用满带宽呢?
ryd994
2014-11-01 18:25:29 +08:00
@mengskysama 传输设备hold不住的时候就会扔掉啊
mengskysama
2014-11-01 18:26:20 +08:00
@ryd994 你说的由接收方在ACK中指定,接收方在ACK中指定没错的,但是接收方怎么确定这个大小的,就是通过拥塞算法。
http://baike.baidu.com/view/4521733.htm?fr=aladdin
mengskysama
2014-11-01 18:27:58 +08:00
@ryd994 po主要的就是限速啊,如果在理论完美的链路上限速20K,还要不断靠丢包来达到效果我认为不合适吧、
mengskysama
2014-11-01 18:31:25 +08:00
反正不管怎么说都是减小cwnd就对了。
mengskysama
2014-11-01 18:31:45 +08:00
这点上我们2说的是一样的。

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

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

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

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

© 2021 V2EX