濮阳杆衣贸易有限公司

主頁 > 知識庫 > Erlang項(xiàng)目內(nèi)存泄漏分析方法

Erlang項(xiàng)目內(nèi)存泄漏分析方法

熱門標(biāo)簽:地圖標(biāo)注如何弄全套標(biāo) 武漢AI電銷機(jī)器人 電銷機(jī)器人 深圳 外呼系統(tǒng)會封嗎 萬利達(dá)綜合醫(yī)院地圖標(biāo)注點(diǎn) 實(shí)體店地圖標(biāo)注怎么標(biāo) 股票配資電銷機(jī)器人 南京電銷外呼系統(tǒng)哪家好 在電子版地圖標(biāo)注要收費(fèi)嗎

隨著項(xiàng)目越來越依賴Erlang,碰到的問題也隨之增加。前段時(shí)間線上系統(tǒng)碰到內(nèi)存高消耗問題,記錄一下troubleshooting的分析過程。線上系統(tǒng)用的是Erlang R16B02版本。

問題描述

有幾臺線上系統(tǒng),運(yùn)行一段時(shí)間,內(nèi)存飆升。系統(tǒng)模型很簡單,有網(wǎng)絡(luò)連接,pool中找新的process進(jìn)行處理。top命令觀察,發(fā)現(xiàn)內(nèi)存都被Erlang進(jìn)程給吃完了,netstat命令查看網(wǎng)絡(luò)連接數(shù),才區(qū)區(qū)幾K。問題應(yīng)該是Erlang內(nèi)存泄漏了。

分析方法

Erlang系統(tǒng)有個(gè)好處,可以直接進(jìn)入線上系統(tǒng),在生產(chǎn)現(xiàn)場分析問題。我們系統(tǒng)是通過Rebar管理的,可以用不同方法進(jìn)入線上系統(tǒng)。

本機(jī)登錄

可以直接登錄到線上機(jī)器,然后通過以下命令attach到Erlang系統(tǒng)里面

復(fù)制代碼 代碼如下:

$ cd /path/to/project
$ rel/xxx/bin/xxx attach
(node@host)>

通過remote shell

獲取Erlang系統(tǒng)的cookie

復(fù)制代碼 代碼如下:

$ ps -ef |grep beam  %%找到參數(shù) --setcookie

新開一個(gè)shell,使用同樣的cookie,不同的nodename
復(fù)制代碼 代碼如下:

$ erl --setcookie cookiename -name test@127.0.0.1

用start remote shell進(jìn)入系統(tǒng)
復(fù)制代碼 代碼如下:

Erlang R16B02 (erts-5.10.3) [source] [64-bit] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V5.10.3  (abort with ^G)
(test1@127.0.0.1)1> net_adm:ping('node@127.0.0.1').
pong
(test1@127.0.0.1)2> nodes().
['node@127.0.0.1']
(test1@127.0.0.1)3>
User switch command
 --> h
  c [nn]            - connect to job
  i [nn]            - interrupt job
  k [nn]            - kill job
  j                 - list all jobs
  s [shell]         - start local shell
  r [node [shell]]  - start remote shell
  q                 - quit erlang
  ? | h             - this message
 --> r 'node@127.0.0.1'
 --> j
   1  {shell,start,[init]}
   2* {'node@127.0.0.1',shell,start,[]}
 --> c 2

分析流程

Erlang有很多工具,可以分析系統(tǒng)信息,比如appmon,webtool。但是系統(tǒng)內(nèi)存嚴(yán)重不足,已經(jīng)沒有辦法啟動這些工具了,幸好還有Erlang shell。

Erlang shell自帶了很多有用的命令,可以用help()方法查看

復(fù)制代碼 代碼如下:

> help().

Erlang系統(tǒng)內(nèi)存消耗情況

top結(jié)果顯示,是內(nèi)存問題,所以第一步可以先看看Erlang的系統(tǒng)內(nèi)存消耗情況

復(fù)制代碼 代碼如下:

> erlang:memory().

memory()可以看到Erlang emulator分配的內(nèi)存,有總的內(nèi)存,atom消耗的內(nèi)存,process消耗的內(nèi)存等等。

Erlang process創(chuàng)建數(shù)量

線上系統(tǒng)發(fā)現(xiàn)主要內(nèi)存消耗都在process上面,接下來要分析,是process內(nèi)存泄漏了,還是process創(chuàng)建數(shù)量太多導(dǎo)致。

復(fù)制代碼 代碼如下:

> erlang:system_info(process_limit).  %%查看系統(tǒng)最多能創(chuàng)建多少process
> erlang:system_info(process_count).  %%當(dāng)前系統(tǒng)創(chuàng)建了多少process

system_info()返回當(dāng)前系統(tǒng)的一些信息,比如系統(tǒng)process,port的數(shù)量。執(zhí)行上面命令,大吃一驚,只有2,3k的網(wǎng)絡(luò)連接,結(jié)果Erlang process已經(jīng)有10多w了。系統(tǒng)process創(chuàng)建了,但是因?yàn)榇a或者其它原因,堆積沒有釋放。

查看單個(gè)process的信息

既然是因?yàn)閜rocess因?yàn)槟撤N原因堆積了,只能從process里找原因了

先要獲取堆積process的pid

復(fù)制代碼 代碼如下:

> i().  %%返回system信息
> i(0,61,886).  %% (0,61,886)是pid

看到有很多process hang在那里,查看具體pid信息,發(fā)現(xiàn)message_queue有幾條消息沒有被處理。下面就用到強(qiáng)大的erlang:process_info()方法,它可以獲取進(jìn)程相當(dāng)豐富的信息。
復(fù)制代碼 代碼如下:

> erlang:process_info(pid(0,61,886), current_stacktrace).
> rp(erlang:process_info(pid(0,61,886), backtrace)).

查看進(jìn)程的backtrace時(shí),發(fā)現(xiàn)下面的信息
復(fù)制代碼 代碼如下:

0x00007fbd6f18dbf8 Return addr 0x00007fbff201aa00 (gen_event:rpc/2 + 96)
y(0)     #Ref0.0.2014.142287>
y(1)     infinity
y(2)     {sync_notify,{log,{lager_msg,[], ..........}}
y(3)     0.61.886>
y(4)     0.89.0>
y(5)     []

process在處理Erlang第三方的日志庫lager時(shí),hang住了。

問題原因

查看lager的文檔,發(fā)現(xiàn)以下信息

復(fù)制代碼 代碼如下:

Prior to lager 2.0, the gen_event at the core of lager operated purely in synchronous mode. Asynchronous mode is faster, but has no protection against message queue overload. In lager 2.0, the gen_event takes a hybrid approach. it polls its own mailbox size and toggles the messaging between synchronous and asynchronous depending on mailbox size.

{async_threshold, 20}, {async_threshold_window, 5}

This will use async messaging until the mailbox exceeds 20 messages, at which point synchronous messaging will be used, and switch back to asynchronous, when size reduces to 20 - 5 = 15.

If you wish to disable this behaviour, simply set it to 'undefined'. It defaults to a low number to prevent the mailbox growing rapidly beyond the limit and causing problems. In general, lager should process messages as fast as they come in, so getting 20 behind should be relatively exceptional anyway.


原來lager有個(gè)配置項(xiàng),配置message未處理的數(shù)量,如果message堆積數(shù)超出,則會用 同步 方式處理!

當(dāng)前系統(tǒng)打開了debug log,洪水般的log把系統(tǒng)給沖垮了。

老外也碰到類似問題,這個(gè)thread給我們的分析帶來很多幫助,感謝一下。

總結(jié)

Erlang提供了豐富的工具,可以在線進(jìn)入系統(tǒng),現(xiàn)場分析問題,這個(gè)非常有助于高效、快速的定位問題。同時(shí),強(qiáng)大的Erlang OTP讓系統(tǒng)有更穩(wěn)定的保證。我們還會繼續(xù)挖掘Erlang,期待有更多的實(shí)踐分享。

標(biāo)簽:濟(jì)寧 臺州 泰安 廣東 安徽 汕頭 濟(jì)源 武威

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Erlang項(xiàng)目內(nèi)存泄漏分析方法》,本文關(guān)鍵詞  Erlang,項(xiàng)目,內(nèi)存,泄漏,分析,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Erlang項(xiàng)目內(nèi)存泄漏分析方法》相關(guān)的同類信息!
  • 本頁收集關(guān)于Erlang項(xiàng)目內(nèi)存泄漏分析方法的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    吉林市| 梅州市| 鱼台县| 东阳市| 洪江市| 大埔县| 金溪县| 长海县| 个旧市| 岑巩县| 石棉县| 吉林市| 开江县| 容城县| 武鸣县| 甘德县| 江达县| 怀宁县| 资兴市| 仁怀市| 唐山市| 靖安县| 马龙县| 理塘县| 莒南县| 阿勒泰市| 鹤岗市| 克东县| 锡林浩特市| 彝良县| 洱源县| 浠水县| 南宫市| 古丈县| 嘉善县| 德惠市| 桐梓县| 亳州市| 伊吾县| 宁夏| 介休市|