3

我有一个非常简单的 Python 脚本——flickr.py——将文件上传到 Flickr。它看起来像这样:

#!/usr/bin/python
import sys
import os.path
import flickr_api
KEY = '<key>'
SECRET = '<secret>'
filename = sys.argv[1]
basename = os.path.basename(filename)
flickr_api.set_keys(api_key=KEY, api_secret=SECRET)
flickr_api.set_auth_handler('/home/pi/.flickr/token')
flickr_api.upload(photo_file=filename, title=basename)

效果很好。我打字flickr photo.jpg,它就在我的 Flickr 页面上。

但是,我想限制上传速度,这样我就可以在后台运行它而不会对其他 Internet 流量造成太大影响。所以我跑...

trickle -s -u 10 flickr photo.jpg

...而且,可悲的是,它似乎没有像我希望的那样将上传速度限制为 10kbps。我已经在另一个窗口中打开了 NetHogs 对此进行了测试。最高可达 80kbps,就像我在没有trickle.

我尝试了各种方法——以超级用户身份运行它,在命令前面加上我的 Python 解释器 ( trickle -s -u 10 /usr/bin/python flickr photo.jpg) 的完整路径。似乎没有任何效果。

我已经trickle用这个盒子上的其他程序进行了测试—— wgetscp——它完全按预期工作。我错过了什么?

可能相关说明:这是在 Raspberry Pi 上。

更新:我使用的 Flickr API 模块就是这个......

https://github.com/alexis-mignon/python-flickr-api

...但我只是用这个重写了我的例子......

http://stuvel.eu/flickrapi

......结果相同。

4

2 回答 2

2

TL;博士

OP 问题无法在相同的硬件上重现,因此我认为这是对单位 ( 10 KB/s == 80 kbps) 的误读。一个类似但不完全相同的问题引发了对该问题的赏金,因此我为此提供了一些诊断技术。我已将响应分成几个部分:

  1. 原来的问题
  2. 诊断步骤建议
  3. 假设可能是什么问题使用awscli

1.原始问题(非)再现

我使用 Raspbian OS(无 GUI)设置了一个 Raspberry Pi,其库与 OP 完全相同(所有这些都是sudo为了速度......)

sudo pip install flickr_api
sudo apt-get install nethogs
sudo apt-get trickle

然后,您必须注册一个 Flickr 帐户,创建一个(非商业)应用程序并设置 API 密钥等 - 在此处创建应用程序和获取 api 密钥的说明,或者通过Python包装器,在此处

我找到了一个 1.9MB 的图像,将其命名test.jpg并尝试了以下操作:

  1. /usr/bin/python flickr.py test.jpg
  2. trickle -s -u 10 /usr/bin/python flickr.py photo.jpg

结果

  1. 图片在~3秒内上传,nethogs显示最高上传速度~400KB/s
  2. 图片上传花了一分钟多的时间,并nethogs显示上传速率在13 KB/s(短暂)达到峰值,然后稳定在10.081.

一切都按预期工作

因此,我相信 OP 问题就这么简单:上传限制以每秒trickle字节kB/s( ) 为单位设置,我认为 OP 可能以每秒千字节kbps() 为单位读取速度。因此系数为 8。


2. 然而...类似问题的诊断

@James_pic在这个问题上发布了一个赏金,事实证明他的场景与 OP 不同。特别是,他在上传到 Amazon Web 服务时使用aws-cli

既然如此,我将发布一些进一步的诊断方法。描述如何trickle工作的论文在这里trickle,并描述了一些不起作用的场景:

  1. 当用户不自愿在涓流下运行时
  2. 其次,由于影响较小,Trickle 无法处理静态链接的二进制文件。

2 在这里可能是相关的,所以我将概述一种方法,您可能会开始使用strace. 此站点上还有另一个问题,涵盖strace一般用法和特定用法,以在此处查找正在使用的共享库。

由于我没有可重复的示例aws-cli,因此我将展示我为验证flickr_api案例中的操作所做的工作。

从手册页,strace

拦截并记录进程调用的系统调用和进程接收到的信号。当我们正在调查正在使用哪些系统库时,我们对这些open消息感兴趣,所以我使用了以下内容,实际上是“包装”了上面的命令,strace然后 grepping 的输出open

  1. strace /usr/bin/python flickr.py test.jpg 2>&1 | grep open > strace.out
  2. strace trickle -s -u 10 /usr/bin/python flickr.py test.jpg | grep open > strace_with_trickle.out

最后,我运行了这两个文件的差异:

diff strace_with_trickle.out strace.out

不出所料,trickle输出多行的版本 - 特别是这些:

< open("/lib/arm-linux-gnueabihf/libbsd.so.0", O_RDONLY) = 3
< open("/lib/arm-linux-gnueabihf/libc.so.6", O_RDONLY) = 3
< open("/lib/arm-linux-gnueabihf/libgcc_s.so.1", O_RDONLY) = 3
< open("/usr/lib/trickle/trickle-overload.so", O_RDONLY) = 3
< open("/etc/ld.so.preload", O_RDONLY)    = 3
< open("/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so", O_RDONLY) = 3
< open("/etc/ld.so.cache", O_RDONLY)      = 3

这些行涵盖了trickle-overload.so进程运行时的插入。特别是,我们可以观察到标准套接字库正在使用中并在此处动态加载 - 即libc.so.6adn libbsd.so.0,这给了一些trickle应该工作的信心。

这种技术非常通用 - 使用一个工作案例和一个非工作案例,然后diff生成输出应该会让你走得更远。


3. 最后……awscli假设

我怀疑awscli可能会在上传过程中产生新进程。如果是这种情况,我认为trickle使用该-s选项不会限制那些子进程。您可以在守护程序模式下使用它 - 这可能会更好 - 您可以通过键入来查看如何执行此操作man trickled

本质上-您首先启动守护程序,例如

trickled -u 10

然后“订阅”它,例如

trickle /usr/bin/python flickr.py test.jpg

警告我对这个问题没有可重现的测试用例awscli,所以这是猜测。

于 2015-06-30T09:43:43.497 回答
0

您使用的是哪个发行版?我知道 Ubuntu 的(至少 18.04 和 20.04)的滴流包缺少一些上游修复,例如https://github.com/mariusae/trickle/commit/bb2825a1fe938e303acd5d65508476ca03961d85

我建议你从源代码编译涓流并重试。

这个提交特别将解决 python3 的问题。Python2 显然不使用SOCK_CLOEXECor SOCK_NONBLOCK,因此不受影响。

于 2021-11-27T15:02:42.443 回答