2017-08-04 78 views
1
請求內存泄漏

我處理程序文件HTTPS與CurlAsyncHTTPClient

# -*- coding:utf-8 -*- 
import sys 
from tornado import gen, web, httpclient 

url = "https://mdetail.tmall.com/templates/pages/desc?id=527485572414" 

class SearchHandler(web.RequestHandler): 
    @gen.coroutine 
    def get(self): 
     async_client = httpclient.AsyncHTTPClient() 
     print sys.getrefcount(async_client) # The first time less than 10, then always bigger than 200 
     req = httpclient.HTTPRequest(url, "GET", headers=headers) 
     req_lists = [async_client.fetch(req) for _ in range(200)] 
     r = yield req_lists 
     print sys.getrefcount(async_client) # always bigger than 200 
     # The longer req_lists, the more memory will be consumed, and never decrease 

配置文件

tornado.httpclient.AsyncHTTPClient.configure(client, max_clients=1000) 

如果我的客戶是「tornado.curl_httpclient.CurlAsyncHTTPClient」,然後,當我訪問我的處理程序broswer ,htop顯示內存增加大約6GB,只要進程運行,內存使用永不減少

如果我設置範圍(200)範圍(500)或更高,內存使用生長更高

如果我的漸變羣是,存儲器勉強增加

我發現只有取https://將有內存問題

我該如何解決與CurlAsyncHTTPClient momory問題?

環境:

Ubuntu 16.10 x64 
python2.7.12 
Tornado 4.5.1 

回答

1

你看到的引用計數預期,因爲max_clients=1000,龍捲風將緩存和重用1000 pycurl.Curl instances,其中的每一個可能hold a reference到客戶端的_curl_header_callback。你可以用objgraph.show_backrefs看到它。

您真的需要max_clients=1000 - 也就是說,多達1000個請求並行嗎? (我希望他們不是全部到同一臺服務器上,就像你的例子一樣!)

無論如何,Curl實例似乎佔用了大量內存。

$ /usr/bin/time -v python getter.py 
6 
207 
^C 
[...] 
    Maximum resident set size (kbytes): 4853544 

當我與鏈接PycURL新鮮內置的libcurl 7.54:

在我的系統(Ubuntu的16.04),我可以使用PycURL對全系統libcurl3-GNUTLS 7.47.0鏈接時重現問題0.1(仍與後端的GnuTLS),我得到一個更好的結果:

$ LD_LIBRARY_PATH=$PWD/curl-prefix/lib /usr/bin/time -v python getter.py 
6 
207 
^C 
[...] 
    Maximum resident set size (kbytes): 1016084 

如果我使用的libcurl與OpenSSL的後端,其結果是更好:

Maximum resident set size (kbytes): 275572 

GnuTLS還有其他內存問題報告:curl issue #1086

因此,如果您確實需要大型max_clients,請嘗試使用由OpenSSL後端構建的更新的libcurl。

+0

非常感謝,但我仍然不明白爲什麼只有**「https://」**請求消耗巨大的內存** CurlAsyncHTTPClient **,但**「http://」**請求不要 – zpoint

+0

@zpoint正如我所說的,高內存使用似乎與libcurl使用的TLS後端(GnuTLS與OpenSSL)有關。當然,TLS僅用於HTTPS,而不用於純文本HTTP。 –

+0

謝謝,我會嘗試最新版本的libcurl – zpoint