使用gunicorn进行实时流传输

6

我正在尝试从一个Flask/Gunicorn服务器流式传输数据:

while (True):
    result = json.dumps(tweetQueue.get())
    yield result

然而,在流进行了30秒后,gunicorn会超时并停止流。我该如何设置超时时间,以便从服务器向流中发布新数据将重新启动超时,使流不会终止?

谢谢!


1
也许这个 gunicorn 参数是相关的?http://docs.gunicorn.org/en/develop/configure.html#timeout - jaynp
是的,我考虑过了 - 只是设置一个很长的超时时间看起来非常不优雅,并且我找不到完全关闭超时的方法。 此外,理想情况下,如果连接真的断开了,我仍然希望有一个有用的超时,但当发布新数据时,超时会被重置。 - akn320
3个回答

10

在做了进一步的研究后,我会回答自己的问题。

gunicorn server:app -k gevent

这里使用了异步工作者,其优点是在响应请求时使用 Connection: keep-alive。这允许请求无限期地被服务。


这个回答听起来不错,但很遗憾对我没用。我正在使用Python 2.7和gunicorn 0.14.5以及gevent 0.13.6。你在使用哪些版本? - personal_cloud
1
与上面的评论所暗示的不同,这种方法仍然有效。但请记得在尝试之前安装 gevent。作为参考,首先使用 pip install greenlet 安装 greenlet,然后再使用 pip install gevent 安装 GEvent。 - B8vrede

0

为了使你的回答保持“活跃”,你不仅应该提供链接,还应该在回答中加入一些内容,这样即使链接失效,回答也会存在。 - storaged

0
考虑使用内置的BaseHTTPServer而不是gunicorn。以下示例在同一端口上启动100个处理程序线程,每个处理程序通过BaseHTTPServer启动。它可以流畅地运行,支持1个端口上的多个连接,并且通常比gunicorn运行速度快2倍。如果需要,还可以将套接字包装在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://dev59.com/nlYO5IYBdhLWcg3wL-vY
        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)放在虚拟环境中,以避免与其他软件发生冲突。

@Hejazzmann。BaseHTTPServer启动运行更快,并且由于具有更少的错误而更安全。 gunicorn会破坏路径标题,并且对于在人们只是使用“pip”时认为“virtualenv无关紧要”的大型项目将导致错误的多个软件包依赖项。您可以选择,但请不要削减FUD。 - personal_cloud
你不知道你在说什么。BaseHTTPServer是用于构建Web服务器的基类。由于缺乏安全/性能功能,不适用于生产。即使更高级别的SimpleHTTPServer也不推荐使用:“此模块定义了两个类,用于实现HTTP服务器(Web服务器)。通常,此模块不直接使用,而是用作构建功能齐全的Web服务器的基础。请参见SimpleHTTPServer和CGIHTTPServer模块。”(...)“警告:不建议在生产中使用SimpleHTTPServer。它只实现基本的安全检查。”(Python文档) - Hejazzman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接