精品国产一级在线观看,国产成人综合久久精品亚洲,免费一级欧美大片在线观看

實(shí)例解讀:如何減少Docker中的Java內(nèi)存消耗

責(zé)任編輯:editor006

作者:田曉旭

2017-08-18 16:03:39

摘自:it168網(wǎng)站

最近,我所在的團(tuán)隊(duì)面臨著部署微服務(wù)(Java+SpringMVC in Docker on AWS)的問(wèn)題。通過(guò)JVM選項(xiàng)提供有關(guān)內(nèi)存配置的一些信息:  此外,作為應(yīng)用程序的基礎(chǔ)圖像,我們選擇了 ,因?yàn)槲覀儼l(fā)現(xiàn)它是 Jetty Java * wars中最輕量級(jí)的圖像之一。

最近,我所在的團(tuán)隊(duì)面臨著部署微服務(wù)(Java+SpringMVC in Docker on AWS)的問(wèn)題。主要問(wèn)題是,很多非常輕巧的應(yīng)用程序消耗了太多的內(nèi)存。因此,我們經(jīng)過(guò)多方嘗試找到了在Docker中關(guān)于Java內(nèi)存消耗的問(wèn)題,并通過(guò)重構(gòu)和遷移到Spring Boot實(shí)現(xiàn)了減少消耗的方法。本文,我將和大家分享這整個(gè)過(guò)程,希望能夠?qū)Υ蠹矣兴鶐椭?/p>

在部署之前,我們要估計(jì)應(yīng)用程序消耗多少內(nèi)存。為此,我們制定了一個(gè)清晰簡(jiǎn)單的方程來(lái)找到RSS:

RSS = Heap size + MetaSpace + OffHeap size

這里OffHeap由線程堆棧,緩沖區(qū),庫(kù)(* .jars)和JVM代碼組成。

Resident Set Size是當(dāng)前分配給進(jìn)程使用的RAM的數(shù)量。它包括代碼、數(shù)據(jù)和共享庫(kù)。

讓我們根據(jù)本地Java VisualVM值找到它:

RSS = 253(Heap) + 100(Metaspace) + 170(OffHeap) + 52*1(Threads) = 600Mb (max avarage)

所以,我們得出結(jié)果:大概600Mb就夠了。我們選擇了一個(gè)t2.micro AWS實(shí)例(具有1Gb RAM)進(jìn)行部署,并開(kāi)始部署應(yīng)用程序。首先,通過(guò)JVM選項(xiàng)提供有關(guān)內(nèi)存配置的一些信息:

如何減少Docker中的Java內(nèi)存消耗

此外,作為應(yīng)用程序的基礎(chǔ)圖像,我們選擇了 ,因?yàn)槲覀儼l(fā)現(xiàn)它是 Jetty Java *.wars中最輕量級(jí)的圖像之一。

正如前文所提到的600Mb就足夠了,所以啟動(dòng)了一個(gè)容器,其容量如下:

docker run -m 600m

那么你覺(jué)得這樣會(huì)發(fā)生什么?我們的集裝箱會(huì)由于內(nèi)存不足被DD(Docker daemon)殺死。這個(gè)容器是在本地啟動(dòng)的,具有完全相同的參數(shù),通過(guò)逐步增加容器的內(nèi)存限制,我們達(dá)到了700…我開(kāi)玩笑的,我們有850mb。

經(jīng)過(guò)觀察和閱讀有用的文章,我們決定進(jìn)行測(cè)量。結(jié)果是非常奇怪和有爭(zhēng)議的。

Heap Size與我們本地相同:

  但Docker顯示了一些瘋狂的統(tǒng)計(jì)數(shù)據(jù):

如何減少Docker中的Java內(nèi)存消耗

  發(fā)生了什么事?情況變得非常混亂...

我們花了很多時(shí)間去搞清楚這些數(shù)據(jù)為什么會(huì)有爭(zhēng)議,在搜索過(guò)程中發(fā)現(xiàn)我們并不是個(gè)例。在查找了很多資料,分析了 應(yīng)用之后,我們幾乎找到了答案。大部分額外的內(nèi)存都是被用于存儲(chǔ)編譯的類及其元數(shù)據(jù)。

那么有關(guān)JavaVM / Docker統(tǒng)計(jì)數(shù)據(jù)的爭(zhēng)議數(shù)字呢?事實(shí)證明,Java VisualVM不了解OffHeap的內(nèi)容,因此,使用此工具調(diào)查Java應(yīng)用程序的內(nèi)存消耗會(huì)非常棘手。此外,了解您使用的JVM選項(xiàng)也是至關(guān)重要。在我看來(lái),指定-Xmx=512m告訴JVN分配512mb Heap,但是它并不告訴JVM整個(gè)內(nèi)存使用要限制在512mb,所以就會(huì)出現(xiàn)代碼緩存和其它非Heap數(shù)據(jù)占用內(nèi)存直至超過(guò)。所以,要指定總內(nèi)存需要使用XX:MaxRAM參數(shù)。請(qǐng)注意,使用MaxRam = 512m,你的Heap約為250mb,這時(shí)就要注意應(yīng)用程序JVM選項(xiàng)。

星期一早上,尋找靈丹妙藥...

NMT和Java VisualVM Memory Sampler 可以幫助我們發(fā)現(xiàn)內(nèi)部核心框架在內(nèi)存中多次重寫的依賴,并且重復(fù)的數(shù)量等于微服務(wù)中子模塊的數(shù)量。如果想要更好的掌握這一點(diǎn),首先要說(shuō)明一下我們的“微服務(wù)”結(jié)構(gòu):

這是NMT(在本地機(jī)器上)的一個(gè)模塊快照(具有73MB加載的類元數(shù)據(jù),42MB線程和37MB的代碼,包括lib):

據(jù)我所知,構(gòu)建這樣的應(yīng)用程序是一個(gè)很大的錯(cuò)誤。首先,每個(gè)* .war已經(jīng)作為一個(gè)單獨(dú)的應(yīng)用程序部署在Jetty servlet容器中,這是非常奇怪的。因?yàn)楦鶕?jù)定義,微服務(wù)應(yīng)該是一個(gè)部署應(yīng)用程序(部署單元)。其次,Jetty在內(nèi)存中分別保存每個(gè)* .war的所有必需庫(kù),即使所有這些庫(kù)具有相同的版本。因此,DB連接、核心框架的各種基本功能等都會(huì)在內(nèi)存中重復(fù)。

一般的解決方案就是重構(gòu),讓應(yīng)用成為真正的微服務(wù)器。此外,我們可能還需要一整套的Jetty,但是一般人聽(tīng)到它的報(bào)價(jià)就能望而卻步。圈內(nèi)有句著名的評(píng)論“不要在Jetty中部署應(yīng)用程序,而是要在應(yīng)用程序中部署Jetty。

我們決定嘗試使用嵌入式Jetty的Spring Boot,因?yàn)樗仟?dú)立應(yīng)用程序中最常用的工具,尤其是在我們的案例中。配置很少,沒(méi)有XML,每個(gè)Spring框架都有優(yōu)勢(shì),還有很多插件,自動(dòng)配置。除此之外,網(wǎng)上還有大量的實(shí)用教程和文章,這些都讓Spring Boot看起來(lái)是個(gè)不錯(cuò)的選擇。

由于我們不再需要單獨(dú)的Jetty應(yīng)用程序服務(wù)器,所以我們將基礎(chǔ)Docker的圖像更改為輕量級(jí)的openjdk。

openjdk:8-jre-alpine

根據(jù)新的要求重構(gòu)了應(yīng)用程序之后,我們得到了類似下圖的東西:

  現(xiàn)在一切都準(zhǔn)備好了,我們來(lái)測(cè)試一下。

先從Java VirtualVM進(jìn)行測(cè)試:

從數(shù)據(jù)中可以看出,雖然新版本有了一些改進(jìn),但是與之前的應(yīng)用程序相比變化并沒(méi)有那么大:

如何減少Docker中的Java內(nèi)存消耗

  然后,我們?cè)賮?lái)看看Docker的統(tǒng)計(jì)數(shù)據(jù):

如何減少Docker中的Java內(nèi)存消耗

  結(jié)果很明顯,我們已經(jīng)減少了內(nèi)存消耗。

結(jié)論

對(duì)我們團(tuán)隊(duì)來(lái)說(shuō),這是一個(gè)很有意思的挑戰(zhàn)。找到導(dǎo)致錯(cuò)誤或者某件事情的根本原因,會(huì)讓你在特定領(lǐng)域中看得更深更廣。網(wǎng)上的資源非常豐富,如果你下定決心去查找答案,那么就一定會(huì)找得到。另外,從這次事件中也認(rèn)識(shí)到,不要完全信任Java VisualVM的內(nèi)存消耗預(yù)計(jì)。

對(duì)于技術(shù)的學(xué)習(xí)和性能的提高,我有三個(gè)更多和大家分享,閱讀更多,改進(jìn)更多,調(diào)查更多。另外,避免常規(guī),盡可能自動(dòng)化,這樣你可以更有效的進(jìn)行工作。

本文對(duì)你是否有幫助?歡迎在下方留言評(píng)論或者反饋您遇到的問(wèn)題。

鏈接已復(fù)制,快去分享吧

企業(yè)網(wǎng)版權(quán)所有?2010-2024 京ICP備09108050號(hào)-6京公網(wǎng)安備 11010502049343號(hào)

  • <menuitem id="jw4sk"></menuitem>

    1. <form id="jw4sk"><tbody id="jw4sk"><dfn id="jw4sk"></dfn></tbody></form>
      主站蜘蛛池模板: 和平区| 平武县| 沁水县| 沙雅县| 丰城市| 吐鲁番市| 岳阳县| 台北县| 交口县| 舒城县| 伊通| 涟水县| 祁门县| 祁阳县| 南乐县| 大庆市| 陵川县| 张北县| 玛纳斯县| 绵阳市| 肃宁县| 昭觉县| 玉环县| 托里县| 大丰市| 潮州市| 沿河| 五原县| 万载县| 泰安市| 永州市| 房山区| 沾化县| 临武县| 株洲市| 商水县| 长治市| 德格县| 白城市| 渝中区| 泰顺县|