<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go 內(nèi)存泄漏排查實(shí)戰(zhàn)

          共 1932字,需瀏覽 4分鐘

           ·

          2022-04-11 15:59

          例1:Goroutine 泄漏

          現(xiàn)象

          NumGoroutine 指標(biāo)持續(xù)上漲,且低峰期未下降,判斷出現(xiàn)了 Goroutine 泄漏現(xiàn)象。

          image.png

          排查

          1. 通過訪問線上服務(wù) pprof 暴露出來的 HTTP 接口,拿到當(dāng)前所有協(xié)程的堆棧信息;curl http://「ip:port」/debug/pprof/goroutine?debug=2

          2. 發(fā)現(xiàn)存在大量存活時(shí)間超過上千分鐘的 Goroutine,觀察堆棧疑似是 http 連接未釋放導(dǎo)致,通過對(duì)下圖 net.sockets.tcp.inuse(正在使用的tcp socket數(shù)量)指標(biāo)的觀察進(jìn)行了進(jìn)一步的確認(rèn);

          結(jié)論

          http

          下面以本次 case http 服務(wù)為例,做簡(jiǎn)單介紹:

          • 上游服務(wù)作為客戶端使用了 http1.1 并且將連接設(shè)置為 keepalive;
          • 本服務(wù)作為服務(wù)端未設(shè)置 idletimeout 與 readtimeout;

          當(dāng)這兩種情況同時(shí)發(fā)生時(shí),如果上游持有對(duì)本服務(wù)的連接不進(jìn)行釋放,那么服務(wù)端會(huì)一直維持這個(gè)連接的存在,不進(jìn)行回收,進(jìn)而導(dǎo)致協(xié)程泄漏;

          client上游客戶端可能為 GO、Java 等,以下為 GO 語言 http 客戶端的空閑連接超時(shí)設(shè)置;server解決建議啟動(dòng) http server 盡量用后者,前者雖然簡(jiǎn)單,但是服務(wù)不夠健壯;

          thrift

          server

          image.png

          Tips

          需要注意的一點(diǎn)是,這個(gè) Goroutine 泄漏問題不止在 http 下會(huì)發(fā)生,在 thrift、grpc 中也是同樣的道理,如果服務(wù)端不對(duì)連接設(shè)置 timeout,某些情況下就會(huì)被上游拖死。

          Reference

          一起 goroutine 泄漏問題的排查[1]

          例2:內(nèi)存居高不下

          現(xiàn)象

          內(nèi)存使用量(mem.rss)居高不下,且低峰期未下降,懷疑發(fā)生了內(nèi)存泄漏現(xiàn)象;

          排查

          1. 剛開始懷疑時(shí)內(nèi)存泄漏,但是抓取 pprof heap 圖觀察后,未發(fā)現(xiàn)泄露問題,且內(nèi)存分配符合預(yù)期;
          2. 發(fā)現(xiàn)內(nèi)存使用雖然居高不下,但未呈上漲趨勢(shì),因此修改關(guān)鍵字為“go 內(nèi)存占用居高不下”,發(fā)現(xiàn)有相同問題;

          結(jié)論

          問題來自于 GO 在將內(nèi)存歸還給操作系統(tǒng)時(shí)的內(nèi)存釋放策略,詳情見官方 issues[2],以下做簡(jiǎn)單介紹。

          GO 內(nèi)存釋放策略

          (此節(jié)內(nèi)容整理自 壓測(cè)后go服務(wù)內(nèi)存暴漲[3]

          不同策略的釋放機(jī)制

          • MADV_DONTNEED:內(nèi)核將會(huì)在合適的時(shí)機(jī)去釋放內(nèi)存,但進(jìn)程的 RSS(常駐內(nèi)存)將會(huì)立即減少。如果再次申請(qǐng)內(nèi)存,內(nèi)核會(huì)重新分配一塊新的空間。
          • MADV_FREE:只能在 linux 內(nèi)核版本 4.5 以上才能使用,此操作理論上只是打了一個(gè)標(biāo)記位,只有在內(nèi)核感覺到內(nèi)存壓力的時(shí)候才會(huì)將這些打標(biāo)記的內(nèi)存回收掉,分配給其他進(jìn)程使用。這個(gè)策略下進(jìn)程的 RSS 不會(huì)立即減少。

          不同策略的實(shí)際差別

          • 理論上 MADV_FREE 效率要高一些,通過在頁表中做標(biāo)記的方式,延遲內(nèi)存的分配和回收,可以提高內(nèi)存管理的效率,畢竟內(nèi)存的回收和分配都是會(huì)消耗系統(tǒng)性能的;
          • 導(dǎo)致的 RSS 指標(biāo)變化 MADV_DONTNEED 會(huì)導(dǎo)致進(jìn)程 RSS 會(huì)有明顯的下降;MADV_FREE 會(huì)導(dǎo)致進(jìn)程 RSS 平穩(wěn)在高峰,不會(huì)得到立即釋放;

          不同 GO 版本的釋放策略

          • 在 GO1.12 之前,默認(rèn)均選擇的 MADV_DONTNEED 策略進(jìn)行內(nèi)存回收;
          • 在 GO1.12~GO1.15,官方默認(rèn)選擇 MADV_FREE 策略進(jìn)行內(nèi)存回收;
          • 在 GO1.16 及之后,又改回了 MADV_DONTNEED 策略進(jìn)行回收內(nèi)存。

          在 GO1.12~GO1.15 且內(nèi)核版本 4.5 以上,mem.rss 指標(biāo)已經(jīng)無法準(zhǔn)確觀測(cè)服務(wù)內(nèi)存占用;

          解決方法

          • 不解決,對(duì)程序性能有利,但是會(huì)降低一些可觀測(cè)性;
          • 以下任一方法可以解決,但會(huì)損失一定性能 把 export GODEBUG=madvdontneed=1 寫進(jìn)服務(wù) control.sh 腳本;
          • 升級(jí) GO 版本至 1.16 及以上;

          參考資料

          [1]

          一起 goroutine 泄漏問題的排查: https://zhuanlan.zhihu.com/p/100740270

          [2]

          issues: https://github.com/golang/go/issues/42330

          [3]

          壓測(cè)后go服務(wù)內(nèi)存暴漲: http://soiiy.com/go/17114.html



          推薦閱讀


          福利

          我為大家整理了一份從入門到進(jìn)階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進(jìn)階看什么。關(guān)注公眾號(hào) 「polarisxu」,回復(fù)?ebook?獲??;還可以回復(fù)「進(jìn)群」,和數(shù)萬 Gopher 交流學(xué)習(xí)。

          瀏覽 47
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美精品aa | 91狠狠综合久久久久久 | 黄色毛片一级 | 激情 小说 亚洲 图片: 伦 | 天天干 天天添 |