使用gunicorn进行流式传输
我正在尝试从一个flask/gunicorn服务器进行数据流传输:
while (True):
result = json.dumps(tweetQueue.get())
yield result
但是,在流传输进行到30秒的时候,gunicorn会自动断开我的连接,导致流传输停止。我该如何设置超时时间,让服务器发布新数据到流中时可以重置这个超时时间,这样流就不会被终止呢?
谢谢!
3 个回答
0
可以考虑使用内置的 BaseHTTPServer
,而不是 gunicorn。下面这个例子在同一个端口上启动了100个处理线程,每个处理线程都是通过 BaseHTTPServer
启动的。它可以很好地进行数据流传输,支持在一个端口上同时处理多个连接,而且通常运行速度是 gunicorn 的两倍。如果你需要的话,还可以把你的连接加上 SSL 加密。
import time, threading, socket, SocketServer, BaseHTTPServer
class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
if self.path != '/':
self.send_error(404, "Object not found")
return
self.send_response(200)
self.send_header('Content-type', 'text/html; charset=utf-8')
self.end_headers()
# serve up an infinite stream
i = 0
while True:
self.wfile.write("%i " % i)
time.sleep(0.1)
i += 1
# Create ONE socket.
addr = ('', 8000)
sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(addr)
sock.listen(5)
# Launch 100 listener threads.
class Thread(threading.Thread):
def __init__(self, i):
threading.Thread.__init__(self)
self.i = i
self.daemon = True
self.start()
def run(self):
httpd = BaseHTTPServer.HTTPServer(addr, Handler, False)
# Prevent the HTTP server from re-binding every handler.
# https://stackoverflow.com/questions/46210672/
httpd.socket = sock
httpd.server_bind = self.server_close = lambda self: None
httpd.serve_forever()
[Thread(i) for i in range(100)]
time.sleep(9e9)
如果你还是想使用 gunicorn,记得把它(还有所有相关的包:wsgi、gevent、flask)放在一个虚拟环境(virtualenv)里,这样可以避免和其他软件发生冲突。
11
我在做了一些研究后,决定回答我自己的问题。
gunicorn server:app -k gevent
这里使用了异步工作者,这种方式的好处是可以在处理请求时使用 Connection: keep-alive
。这样一来,请求就可以一直保持连接,不会中断。