我有一个Python日志处理程序spawns a new thread for each log entry,并在新线程内将日志发送到另一台服务器。但是,我发现请求会间歇性地超时。如果我禁用处理程序,问题就会消失。为什么Gunicorn同步工作者在产卵线程时会挂起?
我试过其他WSGI服务器(WSGIUtils,WSGIRef),我无法重现此问题。
任何想法?
我正在使用同步工作者和Django 1.6在Debian上运行Gunicorn 19.3。
我有一个Python日志处理程序spawns a new thread for each log entry,并在新线程内将日志发送到另一台服务器。但是,我发现请求会间歇性地超时。如果我禁用处理程序,问题就会消失。为什么Gunicorn同步工作者在产卵线程时会挂起?
我试过其他WSGI服务器(WSGIUtils,WSGIRef),我无法重现此问题。
任何想法?
我正在使用同步工作者和Django 1.6在Debian上运行Gunicorn 19.3。
我认为这是GIL Global Interpreter Lock的另一种情况。假设这种情况:
看起来不错,对。但是如果线程更快地完成工作呢?然后你得到:
并取决于线程拥有哪个锁或者调用哪个OS函数,线程可能不会释放GIL一段时间,这会阻止工作人员或至少阻止完全交付响应。
查看代码时,我看到您正在为每条日志消息创建一个SSL连接。 SSL非常非常,很昂贵。不要这样做。相反,创建一个工作线程,该工作线程一旦打开SSL套接字并保持打开状态。当你写入套接字时,python库应该释放GIL,以便其他代码可以工作。但是我不确定在打开套接字时Python是否会释放锁。
请求周期期间是否正在进行日志记录?当它正在等待将日志推出到套接字时,您确定没有阻塞该线程吗? – andrefsp
我不确定新线程如何干扰gunicorn,但是为每条日志消息创建一个新线程非常昂贵。尝试创建一个队列,并在队列中处理日志条目的工作线程。日志系统的其余部分可以进入应该非常快的队列。 –
@andrefsp:是的,线程中的函数可能需要很长时间才能完成,但为什么这会影响完成请求所需的时间? – Gustavo