<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>

          服務(wù)發(fā)布或重啟,發(fā)生抖動怎么辦?

          共 2871字,需瀏覽 6分鐘

           ·

          2021-07-13 20:40

          作者 | zhanlijun

          來源 | http://www.cnblogs.com/LBSer

          一、問題描述

          在發(fā)布或重啟某線上某服務(wù)時(jetty8作為服務(wù)器),常常發(fā)現(xiàn)有些機器的load會飆到非常高(高達70),并持續(xù)較長一段時間(5分鐘)后回落(圖1),與此同時響應(yīng)時間曲線(圖2)也與load曲線一致。

          注:load飆高的初始時刻是應(yīng)用服務(wù)端口打開,流量打入時:

          圖1 發(fā)布時候load飆高

          圖2 發(fā)布時候響應(yīng)時間飆高

          二、問題排查方法

          發(fā)布時對資源使用情況進行監(jiān)控。

          1)通過top -H -p 查找cpu使用率較高的線程,發(fā)現(xiàn)2129和2130這兩個線程cpu使用較高。

          圖3 查找cpu使用率較高的線程

          2)通過jstack打印棧信息,并將線程號2129和2130轉(zhuǎn)換成16進制(printf "%x\n" 2129),分別為851和852,發(fā)現(xiàn)這兩個線程是編譯線程(表1)。

          此外當這兩個線程cpu使用率降低后load以及響應(yīng)時間也馬上恢復(fù)了正常,時間點非常吻合。

          表1 cpu使用率較高的兩個線程詳細信息

          "C2 CompilerThread1" daemon prio=10 tid=0x00007fce48125800 nid=0x852 waiting on condition [0x0000000000000000]
          java.lang.Thread.State: RUNNABLE
          Locked ownable synchronizers:
          - None
          "C2 CompilerThread0" daemon prio=10 tid=0x00007fce48123000 nid=0x851 waiting on condition [0x0000000000000000]
          java.lang.Thread.State: RUNNABLE
          Locked ownable synchronizers:
          - None

          三、現(xiàn)象解釋

          C2 CompilerThread線程項目啟動初期cpu使用率那么高,它在干什么呢?

          Java程序在啟動的時候所有代碼的執(zhí)行都處于解釋執(zhí)行模式,只有在運行了一段時間后,根據(jù)代碼方法執(zhí)行的次數(shù),或代碼里循環(huán)的執(zhí)行次數(shù)等達到一定的閾值才會編譯成機器碼,編譯成機器碼后執(zhí)行效率會得到大幅提升,而隨著執(zhí)行時間進一步拉長,JVM的各種更高級的編譯優(yōu)化手段就會逐漸加上,例如if條件的執(zhí)行狀況,逃逸分析等。這里的C2 CompilerThread線程干的就是編譯優(yōu)化的活。

          現(xiàn)在貌似可以解釋之前的現(xiàn)象了。

          在程序剛啟動的時候,java還處于解釋執(zhí)行模式,因此服務(wù)效率很低,響應(yīng)時間緩慢,處理得慢了,load自然也就高了。而當流量持續(xù)不斷導(dǎo)入時,我們代碼的很多方法執(zhí)行次數(shù)不斷增多,此時C2 CompilerThread線程不斷收集優(yōu)化信息,并且開始將一些熱點代碼優(yōu)化編譯成本地機器碼,因此該線程的cpu使用率增高。而當C2 CompilerThread線程完成初始編譯優(yōu)化過程后,C2 CompilerThread線程的cpu使用率開始下降,與此同時優(yōu)化后服務(wù)的性能大幅提升,服務(wù)響應(yīng)時間也大大縮短,load也下降。

          現(xiàn)在的癥結(jié)在于編譯優(yōu)化過程持續(xù)時間較長,引起抖動。

          如何降低編譯優(yōu)化的持續(xù)時間呢?

          四、解決思路

          1)預(yù)熱

          如果在服務(wù)接受線上請求之前提前完成編譯優(yōu)化過程,那么將能避免此種抖動情況。

          一般的做法是預(yù)熱,有兩種方法:

          a)程序主動預(yù)熱:在啟動完成后,程序主動的訪問熱點的代碼,確保主要的熱點代碼已被編譯成機器碼后再放入流量,可通過-XX:+PrintCompilation來確認。

          b)復(fù)制流量預(yù)熱:通過tcpcopy軟件拷貝一份線上nginx的流量進行預(yù)熱,完成之后再導(dǎo)入線上流量。

          2)啟動多個線程進行編譯優(yōu)化

          如果能加快編譯優(yōu)化速度,那也能降低解釋執(zhí)行階段導(dǎo)致的抖動時間。因此可以多拿幾個線程來做編譯,加快達到高峰性能的速度。另外,多線程系列面試題和答案全部整理好了,微信搜索Java技術(shù)棧,在后臺發(fā)送:面試,可以在線閱讀。

          可以使用-XX:CICompilerCount參數(shù)來設(shè)置編譯線程數(shù)目,這個值默認是2(之前在棧里看到有兩個編譯線程),我們可以加到4。

          3)采用多層編譯

          編譯方式有三種:

          1)Client模式;

          2)Server模式;

          3)Tiered模式。

          我們服務(wù)默認是Server模式。Server模式是采用c2高級編譯的,會比較耗時且要運行一段時間才會觸發(fā)編譯。Server模式的優(yōu)點是編譯后程序效率較高;

          Client模式比較輕量也比較快觸發(fā)(比Server模式觸發(fā)快),編譯優(yōu)化后程序效率不如Server模式;

          Tiered模式是Client模式和Server模式的折中,一開始會啟用Client模式,可以在啟動后更快的讓部分代碼先進入編譯優(yōu)化階段,之后會啟動Server模式,達到程序效率最大優(yōu)化的目的。

          Oracle JDK 7里的HotSpot VM已經(jīng)開始有比較好的Tiered編譯(tiered compilation)支持,可以設(shè)置參數(shù)-XX:+TieredCompilation來啟動Tiered模式,java 8默認就是Tiered模式。

          圖4是到截取的不同編譯方式的性能比較圖,橫坐標是時間,縱坐標是性能??梢钥闯鯰ired模式開始階段性能與C1相當,當?shù)竭_某一時刻后性能與C2相當。

          圖4 不同編譯模式的性能比較

          五、結(jié)果分析

          簡單起見采用方案2和方案3來進行優(yōu)化。

          采用方案2和3之后進行了多次發(fā)布,發(fā)布時除個別機器load達到10之外,基本沒有過高現(xiàn)象(在2~4范圍內(nèi)),并且短時間(2分鐘)內(nèi),load都會降到較合理水平(2左右),較發(fā)布時的load來看,比優(yōu)化前要好很多。

          方案2和方案3只是降低了抖動持續(xù)的時間以及抖動強度,并不能完全避免抖動。真正能避免抖動的方案應(yīng)該是方案1,通過預(yù)熱的方式實現(xiàn)平滑發(fā)布或重啟。

          往期推薦

          什么?超過60%的開發(fā)者都開始從Java 8 升級到 Java 11了?

          趁周末,來學(xué)點進階知識:Java 動態(tài)編譯

          程序員寫代碼崩潰,路過的暖心美團騎手:我?guī)湍憧纯矗?/p>

          Spring發(fā)布新成員:Spring GraphQL!高調(diào)出場的GraphQL能火起來了嗎?

          推薦一本DD剛擼完的書,順便送一波!



          喜歡本文歡迎轉(zhuǎn)發(fā),關(guān)注我訂閱更多精彩

          關(guān)注我回復(fù)「加群」,加入Spring技術(shù)交流群

          瀏覽 25
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  6—12呦国产精品 | 亚洲午夜无码久久久A | 国产无遮挡啪视频 | 偷拍精品一区二区三区 | 大香蕉AV永久在线 |