python - 线程不足 : UWSGI + Multithreaded Python Application with GeventHTTPClient

标签 python multithreading uwsgi gevent

我目前正在运行一个非多线程的 python Web API,并且在 uWSGI + NGINX 堆栈上取得了很大成功。由于新的操作需求,我实现了一个新的构建,其中包括对外部数据源的多线程请求。但是,当我使用 --enable-threads 在 uWSGI 下部署这个新的多线程构建时,几分钟后,机器耗尽可用线程。

通过使用 ps -eLf | grep <process id>| wc -l 监控线程计数,我能够将问题与我对外部 HTTP 请求使用 geventhttpclient 的情况隔离开来。 。我的应用程序中当前有 2 个工作线程(两个外部请求),因此我注意到,每次我从 API 发出请求时,应用程序线程使用计数都会增加 2。如果我将 geventhttpclient 的使用交换为标准 python Requests 模块仅在这些工作线程之一中,线程数仅增加 1。

注意:我使用 HTTPClient.close() 来关闭每个线程内的连接。

这让我怀疑 geventhttpclient 创建的新线程在多线程 uWSGI 应用程序中使用时不会终止。

有没有一种简单的方法可以绕过这个瓶颈? geventhttpclient 在非多线程 uWSGI 应用程序中的性能非常出色,因此我很乐意继续使用它。

谢谢,如果我可以提供更多信息,请告诉我。

最佳答案

将非阻塞编程(geventhttpclient)与阻塞编程(uWSGI 线程/进程)混合在一起是完全错误的。这是一条一般规则:即使您的应用程序 99% 不阻塞,它仍然会阻塞。 gevent 利用堆栈切换来模拟阻塞编程范例这一事实进一步放大了这一点。

这就像协作多任务处理,由所谓的“gevent-hub”管理。不幸的是,尽管您的 greenlet 能够发出 http 请求,但它们永远不会终止,因为一旦请求结束,gevent hub 将永远不会再次运行。

如果你想维护 geventhttpclient 方法,你必须将 uWSGI 设置为 gevent 模式,但你需要确保你的应用程序使用的所有模块和技术都是 gevent 友好的。

关于python - 线程不足 : UWSGI + Multithreaded Python Application with GeventHTTPClient,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27433087/

相关文章:

python - 如何使用 gmail api 获取我的 gmail 帐户的每封邮件的正文?

c++ - C++生产者使用者陷入僵局

python - 当 uwsgi 构建为整体式(内置插件)并通过 dnf 在 Fedora 上安装时如何使用它?

python - 应用程序上下文可用时的 Flask 回调

python - Flask uWSGI - 导入错误 : No module named request

python - 如何在内置输出上调用 python 声音设备包

python - 在python中将字符串转换为日期时间并与当前时间进行比较

javascript - Jinja2:如何创建多维 javascript 数组?

Java 线程安全 DAO

c# - 当没有更多可用线程时 .ForEach 循环是否阻塞