我将CentOS 7与uwsgi(2.0.17.1),uwsgi-plugin-python2(2.0.17)和Flask(1.0.2)一起使用。
我有一个运行很多shell命令的flask应用程序。其中一些会无限期地挂起。我在下面以其中的一个为例,很容易复制。 我在线程模式下使用uwsgi。
#!/usr/bin/python
from flask import Flask
import subprocess
app = Flask(__name__)
@app.route("/test/")
def test():
print 'state 1'
p = subprocess.Popen(['ntpdate', '-u', '0.pool.ntp.org'],close_fds=True)
print 'state 2'
out, err = p.communicate()
print 'state 3'
print 'output: {}'.format(out)
print 'error: {}'.format(err)
return 'finish'
uwsgi命令:
#uwsgi --ini uwsgi.conf --http-socket:8001
uwsgi conf文件:
[uwsgi]
#virtual env's base folder
base = /root/plaground
home = /usr/
#cmd options
bin = /usr/sbin/uwsgi
#python module to import
module = app:app
pythonpath = /root/playground
catch-exceptions = true
plugins-dir = /usr/lib64/uwsgi/
plugins = python
need-app = true
master = true
threads = 10
启动uwsgi后,对/ test路由的第一个请求成功完成,第二个请求停留在命令行执行并永久保留响应。
第一个呼叫输出:
state 1
state 2
21 Sep 16:02:48 ntpdate[19943]: adjust time server 78.46.53.11 offset -0.000224 sec
state 3
output: None
error: None
第二个呼叫输出:
state 1
state 2
第二次调用后ps aux输出:
# ps aux | grep ntpdate
root 20820 0.0 0.0 23632 1516 pts/3 S<+ 16:03 0:00 ntpdate -u 0.pool.ntp.org
strace -p 20820输出:
# strace -p 20820
strace: Process 20820 attached
restart_syscall(<... resuming interrupted call ...>) = 0
poll([{fd=3, events=POLLIN}, {fd=4, events=POLLIN}], 2, 60000) = 0 (Timeout)
poll([{fd=3, events=POLLIN}, {fd=4, events=POLLIN}], 2, 60000) = 0 (Timeout)
处理fd列表:
# ls -l /proc/20820/fd
total 0
lr-x------ 1 root root 64 Eyl 21 16:05 0 -> /dev/null
lrwx------ 1 root root 64 Eyl 21 16:05 1 -> /dev/pts/3
lrwx------ 1 root root 64 Eyl 21 16:03 2 -> /dev/pts/3
lrwx------ 1 root root 64 Eyl 21 16:05 3 -> socket:[463358]
lrwx------ 1 root root 64 Eyl 21 16:05 4 -> socket:[463359]
lsof输出:
# lsof -p 20820
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ntpdate 20820 root cwd DIR 253,0 53 17726086 /root/playground
ntpdate 20820 root rtd DIR 253,0 244 64 /
ntpdate 20820 root txt REG 253,0 110240 224413 /usr/sbin/ntpdate
ntpdate 20820 root mem REG 253,0 106848 361769 /usr/lib64/libresolv-2.17.so
ntpdate 20820 root mem REG 253,0 31824 31549 /usr/lib64/libnss_dns-2.17.so
ntpdate 20820 root mem REG 253,0 62184 31551 /usr/lib64/libnss_files-2.17.so
ntpdate 20820 root mem REG 253,0 19896 142588 /usr/lib64/libattr.so.1.1.0
ntpdate 20820 root mem REG 253,0 90664 142317 /usr/lib64/libz.so.1.2.7
ntpdate 20820 root mem REG 253,0 19776 95386 /usr/lib64/libdl-2.17.so
ntpdate 20820 root mem REG 253,0 2173512 95380 /usr/lib64/libc-2.17.so
ntpdate 20820 root mem REG 253,0 20032 142590 /usr/lib64/libcap.so.2.22
ntpdate 20820 root mem REG 253,0 2512832 190324 /usr/lib64/libcrypto.so.1.0.2k
ntpdate 20820 root mem REG 253,0 164240 95374 /usr/lib64/ld-2.17.so
ntpdate 20820 root 0r CHR 1,3 0t0 5078 /dev/null
ntpdate 20820 root 1u CHR 136,3 0t0 6 /dev/pts/3
ntpdate 20820 root 2u CHR 136,3 0t0 6 /dev/pts/3
ntpdate 20820 root 3u sock 0,7 0t0 463358 protocol: UDP
ntpdate 20820 root 4u sock 0,7 0t0 463359 protocol: UDPv6
如果我在外壳或flask内置Web服务器上尝试ntpdate命令,则不会发生此问题。 我在uwsgi github(https://github.com/unbit/uwsgi/issues/1034)页面上发现了类似的问题,但是此修复不能解决我的问题。
我也使用uwsgi参数close-on-exec和close-on-exec2进行了尝试。这些也没有运气。
感谢您的帮助。