一次线上db连接泄漏问题排查

一次db连接泄漏问题排查

  • 预备知识
  • 问题描述
  • 问题定位
  • 问题验证
  • 问题修复
  • 其它
预备知识
  • recon库的使用,详见<<erlang in danger>>
  • mongodb-erlang库

问题描述

最近从监控平台发现db的可用连接数长时间没有回复到初始值,怀疑是有db连接泄漏。截图如下

屏幕快照 2016-10-12 下午6.02.04.png

登录到终端后,执行
<pre>
mongo_comm:get_info().
</pre>

确实验证了这个问题,长时间可用的连接维持在26,甚至更低,而连接池初始大小为30,正常情况下,应该回归到30

问题定位

  • 首先排查最近发布的代码,使用git diff命令,查看最近三次发布的变化。发现均没有修改mongodb的模块
  • 其次怀疑是频繁使用mongo,导致恰好执行命令查看可用的连接的时候,都有进程在使用连接,那么需要验证使用的数据库连接进程号是不是每次都是一样的,如果每次都是一样的,那么肯定就是泄漏了。
    • erlang节点终端使用
      <pre>
      lists:map(Fun,gen_server:call(mongo_pool_be_logic, get_all_workers)) -- gen_server:call(mongo_pool_be_logic, get_avail_workers)
      </pre>
      erlang节点中,使用命令找出使用的进程pid,发现结果总是如下
      <pre>
      [<0.1610.0>,<0.1596.0>,<0.1613.0>,<0.1614.0>,<0.1599.0>,
      <0.1601.0>,<0.1586.0>,<0.1602.0>,<0.1604.0>,<0.1589.0>,
      <0.1605.0>]
      </pre>
      看来确实有连接泄漏(此时连接归还的策略是fifo,还不是lifo.如果是lifo,还不能证明问题所在),现在的问题是要如何找到哪个进程使用这个conn而且又没有归还,最好还要找到调用的方法。
  • 看了看源码,不支持调用的信息的存储。只有自己写一个简单的ets表来存储调用的上下文。思路是:在获取conn之后,记录调用方的pid和进程上下文;归还连接的时候,从ets表中删除。如果发现了没有归还的连接,立刻调用ets:tab2list()来查看数据,即可定位。
    <pre>
    -spec insert({Conn :: pid(), Pid :: pid(), Current :: term()}) -> ok.
    insert({Conn, Pid, Current}) ->
    ets:insert(?POOLNAME_ETS, {Conn, Pid, Current}).
    -spec delete(Conn :: pid()) -> ok.
    delete(Conn) ->
    ets:delete(?POOLNAME_ETS, Conn).
    </pre>
  • 修改代码
    <pre>
    get_conn() ->
    Conn = mongo_pool:checkout(?POOLNAME),
    insert({Conn, self(), recon:info(self(), 'current_stacktrace')}),
    {ok, Conn}.
    get_info() ->
    mongo_pool:status(?POOLNAME).
    close_conn(Conn) ->
    delete(Conn),
    mongo_pool:checkin(?POOLNAME, Conn).
    </pre>

问题验证

  • 重新部署后,过了半个小时,发现开始有未归坏的连接了,立刻进入终端执行
    <pre>
    ets:tab2list(ets_mongo_pool_be_logic)
    </pre>
    结果如下
    <pre>
    ets:tab2list(ets_mongo_pool_be_logic).
    [{<0.1606.0>,<0.2923.0>,
    {current_stacktrace,[{recon,proc_info,2,
    [{file,"src/recon.erl"},{line,231}]},
    {mongo_comm,get_conn,0,
    [{file,"src/mongo/mongo_comm.erl"},{line,51}]},
    {mongo_exchange,get_order,2,
    [{file,"src/mongo/mongo_exchange.erl"},{line,53}]},
    {exchange_manager,buy,2,
    [{file,"src/manager/exchange_manager.erl"},{line,51}]},
    {gen_server,try_handle_call,4,
    [{file,"gen_server.erl"},{line,629}]},
    {gen_server,handle_msg,5,
    [{file,"gen_server.erl"},{line,661}]},
    {proc_lib,init_p_do_apply,3,
    [{file,"proc_lib.erl"},{line,240}]}]}}.
    </pre>

已经找到了调用方了mongo_exchange:get_order/2。
查看源代码,发现果然有问题
<pre>
get_order(id, Id) ->
{ok, Conn} = mongo_comm:get_conn(),
case mongo:find_one(Conn, ?COLLECTION_ORDER, {'_id', Id}) of
{} -> no_order;
{Ans} ->
bson_to_order(Ans)
end;
</pre>
代码中缺少了关闭连接的方法调用!

问题修复

  • mongo_exchange:get_order加上close_conn方法后,发布,问题修复,截图如下
屏幕快照 2016-10-13 上午9.35.09.png

其它

  • mongodb驱动写法可以优化下:调用方不必每次调用前手动获取conn,调用后手动归还conn
  • 可视化监控非常重要,就是程序员的眼睛。没有这个,就是瞎子
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,646评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,608评论 18 399
  • **冬,与众老师赴济南,偶有闲暇,不堪众人聒噪,幸离千佛山不远,遂游之,有是记。 我只身一人,攀险石,走狭路,探险...
    东营王建军阅读 176评论 0 2
  • 想想,所以成才,
    你最爱我的那颗牙阅读 203评论 0 0
  • Document Types中可以设置应用跟文件的关联。比如你开发了一个图片应用,可以设置双击图片时自动运行你的应...
    开发者老岳阅读 2,397评论 0 1