AeroFS是一家為企業提供安全和廉價的私有云存儲方案。日前,AeroFS的開發團隊發現程序內存發現異常(AeroFS應用大部分是基于Java開發的),經過排查后發現JVMs之間無法進行更多的只讀內存共享,于是決定采用新的開發工具,選用Go語言,隨后,代碼減半、常駐內存下降、Docker鏡像內存也減少許多。AeroFS開發團隊將這一事件記錄下來,我們一起來看下。
AeroFS應用由很多微服務構成,主要以Java來編寫。在一段時間里,它運作良好,服務的用戶約為幾千。但當我們轉到Docker時,發現程序內存占用出現大幅攀升。于是前期我們先是使用了Docker監控工具進行檢查,后得出如下的檢測腳本:
[js] view plaincopy
for line in `docker ps | awk '{print $1}' | grep -v CONTAINER`; do \
echo $(( `cat /sys/fs/cgroup/memory/docker/$line*/memory.usage_in_bytes` / 1024 / 1024 ))MB \
$(docker ps | grep $line | awk '{printf $NF" "}') ; \
done | sort –n
運行后輸出結果是運行中的容器清單,以常駐內存大小進行排序。例如:
46MB web
66MB verification
74MB openid
82MB havre
105MB logcollection
146MB sp
181MB Sparta
該分析沒有覆蓋那些內存占用異常高的Java服務,因為這是非常規的。我們總結了幾點造成內存占用高的因素:
由于tomcat servlet被放置于單獨的容器上,造成JVMs的增加。
JVMs之間無法進行更多的只讀內存共享:原因是所有共享庫都依賴于JVM本身,以及很多JARs是被多服務所使用的。
內存分離會導致過多的批量啟發,從而使由服務分配的緩存增多。
有鑒于此,我們決定使用新的工具。
代碼名字:Greasefire
隨后我把該為AeroFS程序減負的項目作為黑客松參賽項目,我的競賽點是:
CPU占用下降
保持內存的穩定和安全
常駐內存占用減少一倍甚至更多
新工具嘗試
為了實現CPU和內存的優化目標,選擇的語音需要以系統編程為設計根本。經過一番篩選后,Go和Rust成為了我的目標。這兩者都能很方便地編譯出能在小型容器運行的小型靜態二進制代碼,都具有良好的性能表現,安全性以及并發處理支持,關鍵的是比JVM有著更少的內存占用。
Rust的類型系統特性非常迷人。但是它與Go相比還是顯得稚嫩,同時支持庫在HTTP和低階網絡編程上有所欠缺。
與C家族相近的Go入門較易,但是有很多獨有的特性需要結合支持文檔進行細讀。幸好支持文檔寫得詳盡而細致,與標準庫資源無縫連接,所以能夠使初學者寫出清晰可讀性高的代碼。此外,易于與文本編輯器如vim等整合的gofmt工具的提供,也是很令人興奮的。
結果
代碼縮減了約一半,從175行減少為96行。
常駐內存從87MB下降為3MB,減少了將近29倍。
Docker鏡像大小從668MB減少為4.3MB。
在黑客馬拉松的后一天,我還對CA(Certificate Authority 認證授權)進行了優化。我們的認證服務先是從內部服務和桌面用戶機器上接收證書簽名請求,然后以P2P方式在用戶和服務器間返回相關簽名認證。當我以新CA替換原來的Java時,常駐內存更是減少了100倍。后,該項目獲得了黑客松的技術卓越獎。
本站文章版權歸原作者及原出處所有 。內容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負責,本站只提供參考并不構成任何投資及應用建議。本站是一個個人學習交流的平臺,網站上部分文章為轉載,并不用于任何商業目的,我們已經盡可能的對作者和來源進行了通告,但是能力有限或疏忽,造成漏登,請及時聯系我們,我們將根據著作權人的要求,立即更正或者刪除有關內容。本站擁有對此聲明的最終解釋權。