我有一个使用nginx,uwsgi和gevent的设置。在测试设置处理过早客户端断开连接的能力时,我发现uwsgi没有及时响应。
这就是我在python代码中发现断开连接的方法:
While True:
if 'uwsgi' in sys.modules:
import uwsgi #@UnresolvedImport
fileDescriptor = uwsgi.connection_fd()
if not uwsgi.is_connected(fileDescriptor):
logger.debug("Connection was lost (client disconnect)")
break
因此,当uwsgi发出连线丢失信号时,我就会摆脱这个循环。还可以在循环底部调用gevent.sleep(2)来防止锤击CPU。
有了这个,我有nginx记录这样的紧密连接:
2016/08/16 19:23:23 [info] 32452#0: *1 epoll_wait() reported that client prematurely closed connection, so upstream connection is closed too while sending to client, client: 192.168.56.1, server: <removed>, request: "GET /myurl HTTP/1.1", upstream: "uwsgi://127.0.0.1:8070", host: "<removed>:8443"
nginx在生成此日志条目时立即意识到断开连接,它在客户端断开连接的毫秒内。然而uwsgi似乎并没有意识到这种断开,直到几秒钟,有时差不多一分钟,至少在通知我的代码方面:
DEBUG - Connection was lost (client disconnect) - 391 ms[08/16/16 19:24:04 UTC])
通过daemonize创建的uwsgi.log文件表明它在nginx之前看到了它的某个时刻,但不知何故等了半分钟才真正告诉我的代码:
[pid: 32208|app: 0|req: 2/2] 192.168.56.1 () {32 vars in 382 bytes} [Tue Aug 16 19:23:22 2016] GET /myurl => generated 141 bytes in 42030 msecs (HTTP/1.1 200) 2 headers in 115 bytes (4 switches on core 999
这是我在nginx中的设置:
upstream bottle {
server 127.0.0.1:8070;
}
server {
listen 8443;
ssl on;
ssl_certificate /etc/pki/tls/certs/server.crt;
ssl_certificate_key /etc/pki/tls/private/server.key;
server_name <removed>;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
include uwsgi_params;
#proxy_read_timeout 5m;
uwsgi_buffering off;
uwsgi_ignore_client_abort off;
proxy_ignore_client_abort off;
proxy_cache off;
chunked_transfer_encoding off;
#uwsgi_read_timeout 5m;
#uwsgi_send_timeout 5m;
uwsgi_pass bottle;
}
}
对我来说很奇怪的部分是来自uwsgi的时间戳是如何说它在nginx做的时候看到了它,但是直到我的代码看到它~30秒之后它才会写入该条目。从我的角度来看,uwsgi基本上是在撒谎或锁定它,但我找不到任何错误。
感谢任何帮助。我试图从nginx中删除任何缓冲和延迟而没有任何成功。