FreeBSD中Tornado连接未关闭

3 投票
1 回答
910 浏览
提问于 2025-04-17 07:45

我有一个 Tornado 网络服务器,差不多是这样的:

app = tornado.web.Application(handlersList,log_function=printIt)
app.listen(port)
serverInstance = tornado.ioloop.IOLoop.instance()  
serverInstance.start()

处理请求的部分是用 tornado.web.RequestHandler 来做的。当我在 FreeBSD 上运行服务器时,有时候页面或资源加载得很慢。为了调试,我发现当页面在加载时,Tornado 还没有创建请求对象。而查看 netstat 的结果时,我发现有很多连接的状态是 ESTABLISHED。

所以我在想,可能是因为有太多未关闭的连接,操作系统拒绝来自同一会话的新连接。

这可能是原因吗?

我在 get 和 post 函数中写完后没有做任何事情,我是不是应该在返回之前以某种方式关闭连接?

编辑 1:get/post 是同步的(没有 @asynchronous)

编辑 2:通过强制使用 no_keep_alive 暂时解决了这个问题。

class BasicFeedHandler(tornado.web.RequestHandler):

    def finish(self, chunk=None):
        self.request.connection.no_keep_alive = True
        tornado.web.RequestHandler.finish(self, chunk) 

我不确定在客户端关闭连接后,keep_alive 连接是否应该保持这么久,不过这个解决方法有效。
我通过查看 HTTPConnection._finish_request 找到了这个方法,当没有 keep-alive 时,这行代码 self.stream.read_until(b("\r\n\r\n"), self._header_callback) 会执行。在这个上下文中,\r\n\r\n 是什么呢?

1 个回答

1

试试这个:

class Application(tornado.web.Application):
    def __init__(self):
        ...

http_server = tornado.httpserver.HTTPServer(Application(),no_keep_alive=True)
http_server.listen(port)
tornado.ioloop.IOLoop.instance().start()

撰写回答