背景:測試同窗運行AElf單節點過程當中,發現節點忽然再也不出塊,經查看日誌發現 Worker(交易執行進程) 所有掉線,沒法繼續執行交易,從而致使節點掛掉。git
aelf的GitHub連接:https://github.com/AElfProjec...github
初步定位問題:出現這個問題很奇怪,由於節點和全部 Worker 在同一臺服務器上,網絡通訊應該不會有問題,再者發現,主節點、全部 Woker 和 Lighthouse 幾乎在同一時間所有掉線。而後繼續排查,經過 zabbix監控找到了問題,服務器在一個時間點內存幾乎被耗盡,經過觀察時間,發現與節點出現異常時間吻合。服務器
復現問題:咱們重點對內存使用進行測試。測試發現,隨着節點長時間運行,進程佔用服務器內存在不斷增長,尤爲在持續發了大量交易後,內存使用增加明顯,而且中止發交易後,內存也並不會降低。網絡
下面是具體的復現步驟:
首先介紹服務環境,咱們使用Ubuntu 16.04.5 LTS,dotnet core 版本爲2.1.402區塊鏈
節點剛開始運行的狀況:內存使用大約爲90M
而後對節點持續發大量交易,咱們能夠經過監控看到節點交易池堆積大量交易並不斷在執行測試
持續一段時間後,內存佔用已經達到1Gspa
此時中止發交易,等待交易執行,咱們經過監控看到交易池中的交易已都被執行。日誌
等待一段時間後,此時咱們繼續觀察內存佔用,發現內存使用仍是不會減小,一直保持1G 的水平對象
分析問題:blog
接下來咱們使用lldb分析咱們的節點。
首先在服務器上安裝 lldb
sudo apt-get install lldb
找到本機ibsosplugin.so位置
find /usr -name libsosplugin.so
啓動 lldb並附加到進程
sudo lldb –p 13067
加載libsosplugin.so
plugin load /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.4/libsosplugin.so
setclrpath /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.4/
首先分析下對象
dumpheap -stat
咱們能夠看到有大量的如下對象
AElf.Kernel.TransactionHolder
System.String
AElf.Common.Address
System.Collections.Concurrent.ConcurrentDictionary`2+Node[[AElf.Common.Hash,AElf.Common],[AElf.Kernel.TransactionHolder,AElf.Kernel.TxHub]]
AElf.Kernel.Transaction
AElf.Common.Hash
Google.Protobuf.ByteString
System.Byte[]
咱們再看下大於1024字節對象
能夠看有4個對象同類型的對象比較大
System.Collections.Concurrent.ConcurrentDictionary`2+Node[[AElf.Common.Hash, AElf.Common],[AElf.Kernel.TransactionHolder, AElf.Kernel.TxHub]][]
再進一步查看MethodTable對應的對象
能夠看到有8個對象,其中4個較大,挑選其中一個查看對象信息,發現裏面存儲了573437個值。
基於以上分析結果,排查對應源代碼,定位到類:AElf.Kernel.TxHub。該類主要做用是存儲交易池交易數據。該類包含8個ConcurrentDictionary<Hash, TransactionHolder>用於存儲交易數據,而TransactionHolder類中有存儲了Hash、Transaction 等類型,與上面內存分析的結果吻合。再繼續看內部邏輯,發現全部交易進入交易池後一直存儲在TxHub中,再也不進行釋放。到此爲止基本上定位問題所在。
待問題修復後重覆上面步驟進行驗證,效果比較明顯,待交易池交易執行完畢後,內存佔用有明顯降低,最終內存佔用以下
繼續看下內存中對象的狀況,能夠看到對象總數也有了明顯的降低。
可是仍存在內存少許增加的現象,而且有大對象駐留內存的狀況,此問題會進一步跟進分析。