大家,最近几天我遇到了一个奇怪的问题,这真的让我发疯了。
我正在使用 nginx + uwsgi + django 在生产中部署站点。该站点每天有大约 3 亿个请求,最大并发为每秒 4000 个,我前面有 4 个 nginx,后端有 6 个 uwsgi,nignx 通过 tcp 与 uwsgi 通信.
几个月来表现不错。但是有一天uwsgi突然不工作了。它在下面抛出消息:
HARAKIRI: --- uWSGI worker 72 (pid: 23094) WAS 管理请求 /2/article/v2/stream/?detail=1&image=1&count=20&max_behot_time=1358697136&latitude=39.914651254102&longitude=116.45855261839&city=&device_platform=220&channel_app_name=&version news_article&openudid=474604a56e33a44f&uuid=353769056450763&os_api=16&device_type=GT-N7100&os_version=4.1.1 自 2013 年 1 月 21 日星期一 23:07:51 起 ---
从上面的消息看来,由于 django 应用程序中有一个很长的请求,uwsgi 会杀死自己。但是我检查了我的应用查看时间并进行了调试,我确信我的应用非常快(大约 100 毫秒处理一个请求)。
令我惊讶的是,我发现 nginx 向 uwsgi 抛出了很多连接时间,因为 uwsgi 反复杀死自己并且队列已满。
所以我 strace uwsgi 进程,我发现 uwsgi 在写系统调用时被阻塞,直到它杀死它:
writev(8, [{"HTTP/1.1", 8}, {" ", 1}, {"200 OK", 6}, {"\r\n", 2}, {"Vary", 4}, {":", 2}, {"Cookie", 6}, {"\r\n", 2}, {"Content-Type", 12}, {":", 2}, {"text/html ; charset=utf-8", 24}, {"\r\n", 2}, {"\r\n", 2}], 13) = 73
write(8, "{\"has_more\": true, \"message\": \"s"..., 24005
在我的理解中,uwsgi 在 tcp 中使用了 Nonblocking 模式,它永远不会被阻塞。我google了很长时间,尝试了很多次,但没有任何帮助。
最后,我更改了我的部署模式,我在前面使用4个nginx监听80端口并使用http_proxy到6个nginx端口81,nginx 81端口与uwsgi通信vai unix文件sock。经过这次尝试,uwsgi从未阻塞并且所有没关系。
谁能告诉我为什么 uwsgi 在我认为不应该发生的 write syscall 中被阻止?或者在什么情况下通过 tcp 与 nginx 通信时 uwsgi 会被阻止?
非常感谢