Flask 出現 "Broken pipe" 現象說明:
采用 Flask 原生 WSGI 發布 Web(
app.run())。隨后,發起一個 Request,在 Request 還未返回前停止查詢,並重新發起一個新的 Request。服務端很可能出現類似如下的"Broken pipe"報錯。
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usrb64/python2.7/threading.py", line 811, in __bootstrap_inner
self.run()
File "/usrb64/python2.7/threading.py", line 764, in run
self.__target(*self.__args, **self.__kwargs)
File "/usrb/python2.7/site-packages/werkzeugrving.py", line 659, in inner
srv.serve_forever()
File "/usrb/python2.7/site-packages/werkzeugrving.py", line 499, in serve_forever
HTTPServer.serve_forever(self)
File "/usrb64/python2.7/SocketServer.py", line 238, in serve_forever
self._handle_request_noblock()
File "/usrb64/python2.7/SocketServer.py", line 297, in _handle_request_noblock
self.handle_error(request, client_address)
File "/usrb64/python2.7/SocketServer.py", line 295, in _handle_request_noblock
self.process_request(request, client_address)
File "/usrb64/python2.7/SocketServer.py", line 321, in process_request
self.finish_request(request, client_address)
File "/usrb64/python2.7/SocketServer.py", line 334, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usrb64/python2.7/SocketServer.py", line 649, in __init__
self.handle()
File "/usrb/python2.7/site-packages/werkzeugrving.py", line 216, in handle
rv = BaseHTTPRequestHandler.handle(self)
File "/usrb64/python2.7/BaseHTTPServer.py", line 340, in handle
self.handle_one_request()
File "/usrb/python2.7/site-packages/werkzeugrving.py", line 251, in handle_one_request
return self.run_wsgi()
File "/usrb/python2.7/site-packages/werkzeugrving.py", line 193, in run_wsgi
execute(self.server.app)
File "/usrb/python2.7/site-packages/werkzeugrving.py", line 184, in execute
write(data)
File "/usrb/python2.7/site-packages/werkzeugrving.py", line 152, in write
self.send_header(key, value)
File "/usrb64/python2.7/BaseHTTPServer.py", line 401, in send_header
self.wfile.write("%s: %s\r\n" % (keyword, value))
IOError: [Errno 32] Broken pipe
"Broken pipe" 報錯原因:<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">
"Broken pipe" 的字面意思為 "管道破裂",本質為寫入端反饋時讀端卻關閉,因而造成沒有及時取走管道中的數據,從而引發程序異常。
"Broken pipe" 報錯處理方式:
放棄對 Flask 原生 WSGI 的使用,轉而使用全功能的 WSGI,例如:gunicorn、uWSGI 等。
多種 WSGI 對引發 "Broken pip" 報錯操作的響應對比:
1.Flask 原生 WSGI
采用 Flask 原生 WSGI 的最簡測試程序如下。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
import time
time.sleep(10)
return 'Hello World'
app.run(host='11.4.76.73', port=6001)
調用方式如下。
#
./env/bin/python flasktest.py
當發起一個 Request,在 Request 還未返回前停止查詢,並重新發起一個新的 Request時,WSGI 響應類似如下。
注意:報錯"Broken pipe",
程序崩潰。
2.gunicorn
采用 gunicorn 的最簡測試程序如下。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
import time
time.sleep(10)
return 'Hello World'
調用方式如下。
#
./env/bin/gunicorn -w 1 --log-level 'debug' -b 11.4.76.73:6002 gunicorntest:app
當發起一個 Request,在 Request 還未返回前停止查詢,並重新發起一個新的 Request時,WSGI 響應類似如下。
注意:出現"
Ignoring connection reset"信息,但不影響應用運行。
3.pywsgi
采用 pywsgi 的最簡測試程序如下。
from gevent import monkey
monkey.patch_all()
from flask import Flask
from gevent import pywsgi
app = Flask(__name__)
@app.route('/')
def index():
import time
time.sleep(10)
return 'Hello World'
server = pywsgi.WSGIServer(('11.4.76.73', 6003), app)
server.serve_forever()
調用方式如下。
#
./env/bin/python geventtest.py
當發起一個 Request,在 Request 還未返回前停止查詢,並重新發起一個新的 Request時,WSGI 響應類似如下。
注意:應用正常。
