成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

一次線上問題排查所引發(fā)的思考

levy9527 / 2947人閱讀

摘要:直到有一天你會(huì)碰到線上奇奇怪怪的問題,如線程執(zhí)行一個(gè)任務(wù)遲遲沒有返回,應(yīng)用假死。正好這次借助之前的一次生產(chǎn)問題來聊聊如何排查和解決問題。本地模擬上文介紹的是線程相關(guān)問題,現(xiàn)在來分析下內(nèi)存的問題。盡可能的減少多線程競爭鎖。

前言

之前或多或少分享過一些內(nèi)存模型、對(duì)象創(chuàng)建之類的內(nèi)容,其實(shí)大部分人看完都是懵懵懂懂,也不知道這些的實(shí)際意義。

直到有一天你會(huì)碰到線上奇奇怪怪的問題,如:

線程執(zhí)行一個(gè)任務(wù)遲遲沒有返回,應(yīng)用假死。

接口響應(yīng)緩慢,甚至請求超時(shí)。

CPU 高負(fù)載運(yùn)行。

這類問題并不像一個(gè)空指針、數(shù)組越界這樣明顯好查,這時(shí)就需要?jiǎng)偛盘岬降膬?nèi)存模型、對(duì)象創(chuàng)建、線程等相關(guān)知識(shí)結(jié)合在一起來排查問題了。

正好這次借助之前的一次生產(chǎn)問題來聊聊如何排查和解決問題。

生產(chǎn)現(xiàn)象

首先看看問題的背景吧:

我這其實(shí)是一個(gè)定時(shí)任務(wù),在固定的時(shí)間會(huì)開啟 N 個(gè)線程并發(fā)的從 Redis 中獲取數(shù)據(jù)進(jìn)行運(yùn)算。

業(yè)務(wù)邏輯非常簡單,但應(yīng)用一般涉及到多線程之后再簡單的事情都要小心對(duì)待。

果不其然這次就出問題了。

現(xiàn)象:原本只需要執(zhí)行幾分鐘的任務(wù)執(zhí)行了幾個(gè)小時(shí)都沒退出。翻遍了所有的日志都沒找到異常。

于是便開始定位問題之路。

定位問題

既然沒辦法直接從日志中發(fā)現(xiàn)異常,那就只能看看應(yīng)用到底在干嘛了。

最常見的工具就是 JDK 自帶的那一套。

這次我使用了 jstack 來查看線程的執(zhí)行情況,它的作用其實(shí)就是 dump 當(dāng)前的線程堆棧。

當(dāng)然在 dump 之前是需要知道我應(yīng)用的 pid 的,可以使用 jps -v 這樣的方式列出所有的 Java 進(jìn)程。

當(dāng)然如果知道關(guān)鍵字的話直接使用 ps aux|grep java 也是可以的。

拿到 pid=1523 了之后就可以利用 jstack 1523 > 1523.log 這樣的方式將 dump 文件輸出到日志文件中。

如果應(yīng)用簡單不復(fù)雜,線程這些也比較少其實(shí)可以直接打開查看。

但復(fù)雜的應(yīng)用導(dǎo)出來的日志文件也比較大還是建議用專業(yè)的分析工具。

我這里的日志比較少直接打開就可以了。

因?yàn)槲仪宄缿?yīng)用中開啟的線程名稱,所以直接根據(jù)線程名就可以在日志中找到相關(guān)的堆棧:

所以通常建議大家線程名字給的有意義,在排查問題時(shí)很有必要。

其實(shí)其他幾個(gè)線程都和這里的堆棧類似,很明顯的看出都是在做 Redis 連接。

于是我登錄 Redis 查看了當(dāng)前的連接數(shù),發(fā)現(xiàn)已經(jīng)非常高了。

這樣 Redis 的響應(yīng)自然也就變慢了。

接著利用 jps -v 列出了當(dāng)前所以在跑的 Java 進(jìn)程,果不其然有好幾個(gè)應(yīng)用都在查詢 Redis,而且都是并發(fā)連接,問題自然就找到了。

解決辦法
所以問題的主要原因是:大量的應(yīng)用并發(fā)查詢 Redis,導(dǎo)致 Redis 的性能降低。

既然找到了問題,那如何解決呢?

減少同時(shí)查詢 Redis 的應(yīng)用,分開時(shí)段降低 Redis 的壓力。

將 Redis 復(fù)制幾個(gè)集群,各個(gè)應(yīng)用分開查詢。但是這樣會(huì)涉及到數(shù)據(jù)的同步等運(yùn)維操作,或者由程序了進(jìn)行同步也會(huì)增加復(fù)雜度。

目前我們選擇的是第一個(gè)方案,效果很明顯。

本地模擬

上文介紹的是線程相關(guān)問題,現(xiàn)在來分析下內(nèi)存的問題。

以這個(gè)類為例:

https://github.com/crossoverJie/Java-Interview/blob/master/src/main/java/com/crossoverjie/oom/heap/HeapOOM.java

public class HeapOOM {

    public static void main(String[] args) {
        List list = new ArrayList<>(10) ;
        while (true){
            list.add("1") ;
        }
    }
}

啟動(dòng)參數(shù)如下:

-Xms20m
-Xmx20m
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/Users/xx/Documents

為了更快的突出內(nèi)存問題將堆的最大內(nèi)存固定在 20M,同時(shí)在 JVM 出現(xiàn) OOM 的時(shí)候自動(dòng) dump 內(nèi)存到 /Users/xx/Documents(不配路徑則會(huì)生成在當(dāng)前目錄)。

執(zhí)行之后果不其然出現(xiàn)了異常:

同時(shí)對(duì)應(yīng)的內(nèi)存 dump 文件也生成了。

內(nèi)存分析

這時(shí)就需要相應(yīng)的工具進(jìn)行分析了,最常用的自然就是 MAT 了。

我試了一個(gè)在線工具也不錯(cuò)(文件大了就不適合了):

http://heaphero.io/index.jsp

上傳剛才生成的內(nèi)存文件之后:

因?yàn)槭莾?nèi)存溢出,所以主要觀察下大對(duì)象:

也有相應(yīng)提示,這個(gè)很有可能就是內(nèi)存溢出的對(duì)象,點(diǎn)進(jìn)去之后:

看到這個(gè)堆棧其實(shí)就很明顯了:

在向 ArrayList 中不停的寫入數(shù)據(jù)時(shí),會(huì)導(dǎo)致頻繁的擴(kuò)容也就是數(shù)組復(fù)制這些過程,最終達(dá)到 20M 的上限導(dǎo)致內(nèi)存溢出了。

更多建議

上文說過,一旦使用了多線程,那就要格外小心。

以下是一些日常建議:

盡量不要在線程中做大量耗時(shí)的網(wǎng)絡(luò)操作,如查詢數(shù)據(jù)庫(可以的話在一開始就將數(shù)據(jù)從從 DB 中查出準(zhǔn)備好)。

盡可能的減少多線程競爭鎖??梢詫?shù)據(jù)分段,各個(gè)線程分別讀取。

多利用 CAS+自旋 的方式更新數(shù)據(jù),減少鎖的使用。

應(yīng)用中加上 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp 參數(shù),在內(nèi)存溢出時(shí)至少可以拿到內(nèi)存日志。

線程池監(jiān)控。如線程池大小、隊(duì)列大小、最大線程數(shù)等數(shù)據(jù),可提前做好預(yù)估。

JVM 監(jiān)控,可以看到堆內(nèi)存的漲幅趨勢,GC 曲線等數(shù)據(jù),也可以提前做好準(zhǔn)備。

總結(jié)

線上問題定位需要綜合技能,所以是需要一些基礎(chǔ)技能。如線程、內(nèi)存模型、Linux 等。

當(dāng)然這些問題沒有實(shí)操過都是紙上談兵;如果第一次碰到線上問題,不要慌張,反而應(yīng)該慶幸解決之后你又會(huì)習(xí)得一項(xiàng)技能。

號(hào)外

最近在總結(jié)一些 Java 相關(guān)的知識(shí)點(diǎn),感興趣的朋友可以一起維護(hù)。

地址: https://github.com/crossoverJie/Java-Interview

歡迎關(guān)注公眾號(hào)一起交流:

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/71531.html

相關(guān)文章

  • 一次線上問題排查解決過程

    摘要:排查異常日志,發(fā)現(xiàn)沒有該問題存在。測試功能正常,沒有重現(xiàn)線上問題。解決問題原因定位好了,剩下的就是如何解決了。兩個(gè)方案修改線上配置該上實(shí)施難度系數(shù)高,因?yàn)楣臼褂玫慕y(tǒng)一發(fā)布部署平臺(tái),開發(fā)人員無服務(wù)器操作權(quán)限。 問題 XX系統(tǒng)中,一個(gè)用戶需要維護(hù)的項(xiàng)目數(shù)過多,填寫的任務(wù)數(shù)超多,產(chǎn)生了一次工時(shí)保存中,只有前面一部分的xx數(shù)據(jù)持久化到數(shù)據(jù)庫,后面的數(shù)據(jù)沒有保存。 圖1 showImg(htt...

    宋華 評(píng)論0 收藏0
  • 一次線上問題排查解決過程

    摘要:排查異常日志,發(fā)現(xiàn)沒有該問題存在。測試功能正常,沒有重現(xiàn)線上問題。解決問題原因定位好了,剩下的就是如何解決了。兩個(gè)方案修改線上配置該上實(shí)施難度系數(shù)高,因?yàn)楣臼褂玫慕y(tǒng)一發(fā)布部署平臺(tái),開發(fā)人員無服務(wù)器操作權(quán)限。 問題 XX系統(tǒng)中,一個(gè)用戶需要維護(hù)的項(xiàng)目數(shù)過多,填寫的任務(wù)數(shù)超多,產(chǎn)生了一次工時(shí)保存中,只有前面一部分的xx數(shù)據(jù)持久化到數(shù)據(jù)庫,后面的數(shù)據(jù)沒有保存。 圖1 showImg(htt...

    airborne007 評(píng)論0 收藏0
  • 一次線上問題排查解決過程

    摘要:排查異常日志,發(fā)現(xiàn)沒有該問題存在。測試功能正常,沒有重現(xiàn)線上問題。解決問題原因定位好了,剩下的就是如何解決了。兩個(gè)方案修改線上配置該上實(shí)施難度系數(shù)高,因?yàn)楣臼褂玫慕y(tǒng)一發(fā)布部署平臺(tái),開發(fā)人員無服務(wù)器操作權(quán)限。 問題 XX系統(tǒng)中,一個(gè)用戶需要維護(hù)的項(xiàng)目數(shù)過多,填寫的任務(wù)數(shù)超多,產(chǎn)生了一次工時(shí)保存中,只有前面一部分的xx數(shù)據(jù)持久化到數(shù)據(jù)庫,后面的數(shù)據(jù)沒有保存。 圖1 showImg(htt...

    HollisChuang 評(píng)論0 收藏0
  • 關(guān)于一次線上出錯(cuò)思考--如何規(guī)避線上程序崩盤

    摘要:近日在工作中由于疏忽問題導(dǎo)致某個(gè)客戶的系統(tǒng)直接崩盤,極大的影響了用戶使用產(chǎn)品的體驗(yàn)。在經(jīng)過修改之后,不得不思考下在日常開發(fā)中的一些壞習(xí)慣以及如何規(guī)避這些日常問題了。同時(shí)由于我們未能對(duì)錯(cuò)誤進(jìn)行好的處理,導(dǎo)致程序直接卡死。 近日在工作中由于疏忽問題導(dǎo)致某個(gè)客戶的系統(tǒng)直接崩盤,極大的影響了用戶使用產(chǎn)品的體驗(yàn)。在經(jīng)過修改之后,不得不思考下在日常開發(fā)中的一些壞習(xí)慣以及如何規(guī)避這些日常問題了。 在...

    LiuRhoRamen 評(píng)論0 收藏0
  • 一次線上頻繁FGC事件和解決方式

    摘要:直接顯示了一個(gè)疑似內(nèi)存泄漏的問題。然后分析文件給出的信息,發(fā)現(xiàn)一個(gè)叫的類。文件里面說的內(nèi)存泄漏的大概的意思就是說,這個(gè)類里面的存放的東西太多了,爆掉了。修改了代碼將調(diào)用的地方改成了單例。修改完線上跑了一段日子,后來也沒有出現(xiàn)過這樣的問題。 問題描述: ????早上去公司上班,突然就郵件一直報(bào)警,接口報(bào)異常,然后去查服務(wù)器的運(yùn)行情況,發(fā)現(xiàn)java的cpu爆了.接著就開始排查問題 問題解決...

    Alliot 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<