我正在使用Python的requests
库在celery的workers
中进行大量(约10个/秒)的API调用(包括GET,POST,PUT,DELETE)。每个请求需要大约5-10秒完成。
我尝试在具有1000并发的eventlet
池中运行celery工作进程。
由于requests
是阻塞进程,因此每个并发连接都在等待一个请求。
如何使requests
异步化?
我正在使用Python的requests
库在celery的workers
中进行大量(约10个/秒)的API调用(包括GET,POST,PUT,DELETE)。每个请求需要大约5-10秒完成。
我尝试在具有1000并发的eventlet
池中运行celery工作进程。
由于requests
是阻塞进程,因此每个并发连接都在等待一个请求。
如何使requests
异步化?
使用 eventlet monkey patching,使任何纯 Python 库变为非阻塞。
补丁单个库
# import requests # instead do this:
import eventlet
requests = eventlet.import_patched('requests')
可以将 erequests 和 grequests 软件包简化为以下两行。
对一切进行打补丁。
import eventlet
eventlet.monkey_patch() # must execute as early as possible
...
# everything is non-blocking now:
import requests, amqp, memcache, paramiko, redis
更新:关于猴子补丁requests库的已知问题。如果你遇到以下情况:
ImportError: cannot import name utils
然后修改导入行为
requests = eventlet.import_patched('requests.__init__')
来自文档:
有许多项目将Requests与Python的异步框架之一相结合。两个很好的例子是grequests和requests-futures。
特别是对于eventlet,您可以使用erequests。
requests = eventlet.import_patched('requests')
它会报错无法导入utils (from . import utils
) 所以我已经根据https://github.com/eventlet/eventlet/issues/7将其更改为requests = eventlet.import_patched('requests.__init__')
再次感谢 - Maddyeventlet.monkey_patch()
或使用eventlet.import_patched('module_name')
来处理每个具有网络代码的模块。如果您指定了 eventlet 工作类型,Celery 会隐式执行第一种选项。https://github.com/celery/celery/blob/b5b64945daaba87a7d975b1b4fca08b0948b91bb/celery/__init__.py#L99 - temoto