Closed spyth closed 6 years ago
如果内存匀速增长的话,可能是内存泄露了,你可以通过火焰图来看看。
ping @spyth ,你是通过resty-cli来测试的?有没有尝试用最新的openresty+ab/wrk/jmeter等进行测试?
pong @anjia0532 ; 一开始是在生产环境的 openresty 上发现的,上线了几个钟服务器就内存爆了重启。openresty 是最新版本。我没有用 ab 去测试,不过有简单写了个脚本发模拟请求就复现了。 上面的脚本我之前有生成了个火焰图 perf.svg.zip,不知道生成的对不对。
真是不太好意思,最近一段时间比较忙,并且后来我们换用了ipip.net的ip库,所以就不怎么用maxminddb了。不过看你的火焰图不太明显,最好是新起一个openresty(排除其他因素的影响),只通过ab/wrk压测ip(ip最好是随机ip,防止ip缓存),并记录火焰图,可以看出瓶颈在哪。
同时,根据你的描述,应该是内存泄露.可以通过春哥开源的 https://github.com/openresty/stapxx#sample-bt-leaks 和 https://github.com/openresty/openresty-systemtap-toolkit#ngx-leaked-pools 进行调试。
或者如果你不是很着急的话也可以等我稍后有空的时候再跟踪此问题。
MMDB_get_entry_data_list . 沒有 release
entry_data_list
extern void MMDB_free_entry_data_list(MMDB_entry_data_list_s *const entry_data_list);
補進流程上 就會清 memory 了
@znikang 感谢指点,开始我也以为是未进行垃圾回收导致的(我是java程序员。。。) 但是加了回收后(参考 https://github.com/maxmind/libmaxminddb/blob/master/doc/libmaxminddb.md#mmdb_free_entry_data_list ),依然存在内存泄露问题,后来根据火焰图分析,发现核心问题是不断初始化导致的问题。不是指针未回收。据此将对象重用即可解决。通过
cat server.conf
server {
listen 80;
server_name 127.0.0.1;
location / {
content_by_lua_block{
local cjson = require 'cjson'
local geo = require 'resty.maxminddb'
if not geo.initted() then
geo.init("/path/to/GeoLite2-City.mmdb")
end
local res,err = geo.lookup(ngx.var.arg_ip or ngx.var.remote_addr) --support ipv6 e.g. 2001:4860:0:1001::3004:ef68
if not res then
ngx.log(ngx.ERR,'failed to lookup by ip ,reason:',err)
end
ngx.say("full :",cjson.encode(res))
if ngx.var.arg_node then
ngx.say("node name:",ngx.var.arg_node," ,value:", cjson.encode(res[ngx.var.arg_node] or {}))
end
}
}
}
cat test.lua
wrk.method = "GET";
wrk.body = "";
logfile = io.open("wrk.log", "w");
request = function()
ip = tostring(math.random(1, 255)).."."..tostring(math.random(1, 255)).."."..tostring(math.random(1, 255)).."."..tostring(math.random(1, 255))
path = "/?ip=" .. ip
return wrk.format(nil, path)
end
response = function(status,header,body)
logfile:write("\nbody:" .. body .. "\n-----------------");
end
wrk -t10 -c10 -d60s -s ./test.lua --latency http://127.0.0.1
docker run --rm -v `pwd`:/data williamyeh/wrk -s test.lua --latency http://127.0.0.1
内存一直保持在0.x%-1%左右
附件是0.4和0.5的火焰图对比。
@spyth 你可以用0.5的测一下
呵呵 把它放在 lua init 搞定了
@znikang 恩,放在 init_by_lua*也可以,是我在readme.md里写的demo误导了大家。 用
local geo = require 'resty.maxminddb'
if not geo.initted() then
geo.init("/path/to/GeoLite2-City.mmdb")
end
适用性更强一些,既可以放到init 初始化 ,也可以在access_by_lua,log_by_lua,content_by_lua处直接使用。
Hi,不知道是不是调用的方式不对,查询的时候内存会一直不断增长。
下面是我写的脚本,可以重现。 环境是:CentOS 7.5.1804, openresty/1.13.6.2
$ resty test.lua