【发布时间】:2012-09-19 12:22:14
【问题描述】:
我有一个设置,其中 Tornado 被用作工人的一种传递方式。 Tornado 收到请求,将请求发送给 N 个工作人员,汇总结果并将其发送回客户端。这工作正常,除非由于某种原因发生超时 - 然后我有内存泄漏。
我有一个类似于这个伪代码的设置:
workers = ["http://worker1.example.com:1234/",
"http://worker2.example.com:1234/",
"http://worker3.example.com:1234/" ...]
class MyHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def post(self):
responses = []
def __callback(response):
responses.append(response)
if len(responses) == len(workers):
self._finish_req(responses)
for url in workers:
async_client = tornado.httpclient.AsyncHTTPClient()
request = tornado.httpclient.HTTPRequest(url, method=self.request.method, body=body)
async_client.fetch(request, __callback)
def _finish_req(self, responses):
good_responses = [r for r in responses if not r.error]
if not good_responses:
raise tornado.web.HTTPError(500, "\n".join(str(r.error) for r in responses))
results = aggregate_results(good_responses)
self.set_header("Content-Type", "application/json")
self.write(json.dumps(results))
self.finish()
application = tornado.web.Application([
(r"/", MyHandler),
])
if __name__ == "__main__":
##.. some locking code
application.listen()
tornado.ioloop.IOLoop.instance().start()
我做错了什么?内存泄漏从何而来?
【问题讨论】:
-
我不喜欢这个
if len(responses) == len(workers):- 你确定应用程序总是在这里吗?尝试记录批量请求和成功尝试的尝试。 -
@Nikolay:对,AFAIK,Tornado 使用回调来表示成功和错误。因此,我很确定,无论有多少工人失败,它总会得到那么多回应。我不确定当客户端取消请求时会发生什么。
-
另外,如果你有超过 10 名工人,并且他们都因超时而死亡 - 你有一段时间龙卷风无法创建新连接 - 我不知道它现在的行为如何。尝试使用
max_clients参数。 -
在这种情况下我会使用
Queue,因为它是线程安全的,它会在所有作业完成时告诉您。 -
你怎么知道你有内存泄漏?您的服务器内存是否已满,或者是分析提醒了您该问题吗?
标签: python asynchronous memory-leaks tornado