有段時(shí)間沒(méi)有跟學(xué)弟學(xué)妹們互動(dòng)了,因?yàn)樽罱@段時(shí)間實(shí)在是太忙了,因?yàn)榭炫R近雙十一嘛!
言歸正傳啊,上次有學(xué)妹跟我聊,剛?cè)ス静皇煜きh(huán)境,Linux系統(tǒng)不熟悉,很多命令不知道怎么用,外加上公司里面查詢?nèi)罩具€是使用跳板機(jī)的方式,所以特別被動(dòng)。今天就跟大家聊聊一些簡(jiǎn)單實(shí)用的Linux命令來(lái)面對(duì)一些工作中遇到問(wèn)題。
什么是Linux?
Linux全稱GNU/Linux,是一種免費(fèi)使用和自由傳播(開(kāi)源)的UNIX操作系統(tǒng),安裝在我們我們的計(jì)算機(jī)硬件上,用來(lái)管理計(jì)算機(jī)的硬件和軟件資源管理等。
當(dāng)然也并不只是因?yàn)槊赓M(fèi)和開(kāi)源導(dǎo)致Linux為啥這么火的,相比于widows系統(tǒng)它還是有很多優(yōu)點(diǎn)的:
Linux相比較于widows系統(tǒng)他更注重安全性,比如說(shuō)在Linux目錄的下的文件都有一個(gè)權(quán)限的控制,不同的用戶訪問(wèn)的權(quán)限能有不同的控制權(quán)限,所以它的安全性更好一點(diǎn)
相比較于widows系統(tǒng),Linux的穩(wěn)定性更好,很少會(huì)出現(xiàn)系統(tǒng)崩潰的情況出現(xiàn),因?yàn)闄?quán)限控制到位了,很多核心應(yīng)用文件沒(méi)有權(quán)限是不能進(jìn)行操作的,還有很多配置更改都不需要去重啟機(jī)器,不會(huì)影響到相關(guān)的服務(wù)程序。
Linux還有很多其他的一些特點(diǎn)比如說(shuō)靈活性,因?yàn)殚_(kāi)源嘛,還有對(duì)硬件沒(méi)啥要求等等,所以現(xiàn)在很多的公司都是使用Linux系統(tǒng)來(lái)作為服務(wù)器。
而我們?cè)诜?wù)器終端輸入的命令通過(guò)命令解析器(常見(jiàn)的有 shell,)處理完之后才真正的被運(yùn)行。
今天主要是從三個(gè)方面跟學(xué)妹聊Linux,其實(shí)就是一些我們工作中比較實(shí)用的命令
- Linux的基礎(chǔ)命令
- Java中的服務(wù)器排查問(wèn)題命令
- 擴(kuò)展Arthas中的常見(jiàn)用法(號(hào)稱 Java診斷神器)
Linux的基礎(chǔ)命令
一些簡(jiǎn)單的常見(jiàn)的我就不跟大家一一列舉出來(lái)了,這個(gè)直接百度一下就全部都有了
文件相關(guān)命令
ls :顯示當(dāng)前目錄下所有的文件
ls -a :列出所有文件,包括以 "." 開(kāi)頭的隱含文件。
ll :顯示當(dāng)前文件或目錄的詳細(xì)信息,含有時(shí)間、讀寫權(quán)限、大小、時(shí)間等信息,等于是 ls -l 命令
du :用于顯示目錄或文件的大小。一般用來(lái)查看文件的大小,比如說(shuō)看一些dump的日志的文件的大小
du -sh * :查詢當(dāng)前目錄下所有的文件的大小以K,M,G為單位,提高信息的可讀性。
- 場(chǎng)景:查看服務(wù)器中一個(gè)文件(比如日志)大小,在刪除磁盤文件的時(shí)候能有一個(gè)對(duì)比,那個(gè)文件占用磁盤最大
cat :輸出當(dāng)前文件內(nèi)容。
- 場(chǎng)景:一般就是用來(lái)查看當(dāng)前文件的內(nèi)容,比如說(shuō)要看下服務(wù)器的啟動(dòng)service.sh腳本文件中的內(nèi)容(cat service.sh)
- 擴(kuò)展:cat -n fileName 輸出文件內(nèi)容并且在前面加上行號(hào)。
- 擴(kuò)展:cat -b fileName 輸出文件內(nèi)容并且在前面加上行號(hào),與上面的不同是會(huì)過(guò)濾空白行。
- 擴(kuò)展:cat -n textfile1 > textfile2 把 textfile1 的文檔內(nèi)容加上行號(hào)后輸入 textfile2 這個(gè)文檔里。
more :跟cat差不多,但是有一個(gè)優(yōu)點(diǎn)就是展示出來(lái)的是按照頁(yè)的形式出來(lái),可以接著按space空格鍵向下翻頁(yè)
- 擴(kuò)展:more -num 一次顯示行數(shù)。
- 擴(kuò)展:more +num 從第num行開(kāi)始顯示。
chmod :修改當(dāng)前用戶對(duì)文件的權(quán)限
- r=4,w=2,x=1,所以想要rxw 讀寫和可執(zhí)行權(quán)限,那就是4+2+1=7,而一個(gè)位數(shù)表示一個(gè)角色,chmod a=rwx txt1.txt就可以理解為就是 chmod 777 txt1.txt
- u 表示該文件的擁有者,g 表示與該文件的擁有者屬于同一個(gè)群體(group)者,o 表示其他以外的人,a 表示這三者皆是
- + 表示增加權(quán)限、- 表示取消權(quán)限、= 表示唯一設(shè)定權(quán)限
- r 表示可讀取,w 表示可寫入,x 表示可執(zhí)行
- 場(chǎng)景:chmod這個(gè)命令實(shí)用比較廣泛,但是說(shuō)白了就是一點(diǎn)更改文件權(quán)限,但是權(quán)限這個(gè)東西怎么加,是加所有用戶還是其他?是加讀寫還是去除讀寫?這個(gè)就需要理解 u、g、o、a、+、-、=、r、w、x等含義
- 擴(kuò)展:chmod ugo+r txt1.txt 或者 chmod a+r txt1.txt 設(shè)置txt1.txt 對(duì)所有的用戶角色可讀
- 擴(kuò)展:chmod 777 file ,chmod也可以用數(shù)字來(lái)代表權(quán)限問(wèn)題,
diff :用于比較文件的差異。
- 擴(kuò)展:diff log1.log log2.log -y -W 50并排輸出兩個(gè)文件的不同。
grep :用于查找文件里符合條件的字符串,這個(gè)是最常見(jiàn)的也是日常查詢文件最常用的。
- $grep2021-10-27T20:17:20.519+0800gc.log|wc-l
- 1
- $grep2021-10-27T21gc.log|grep25:33
- 2021-10-27T21:25:33.413+0800:797616.955:[GC(AllocationFailure)2021-10-27T21:25:33.414+0800:797616.955:[ParNew:848318K->18793K(943744K),0.0263809secs]1283786K->454263K(1992320K),0.0270603secs][Times:user=0.09sys=0.00,real=0.03secs]
- 擴(kuò)展:grep "aaa" log.log -A 10 ,除了顯示符合搜索條件的那一列之外,并顯示該行之后的10行內(nèi)容。wc
- 擴(kuò)展:grep "aaa" log.log -B 10 ,除了顯示符合搜索條件的那一列之外,并顯示該行之前的10行內(nèi)容。
- 擴(kuò)展:grep "aaa" log.log | grep "bb" -A 10,同時(shí)搜索滿足條件以上兩個(gè)條件的結(jié)果,并向下在打印剩下的10行。
- 擴(kuò)展:grep "aaa" log.log | wc -l,統(tǒng)計(jì)滿足條件的的次數(shù)
scp : 命令用于 Linux 之間復(fù)制文件和目錄。可以用來(lái)作為下載文件到本地的一種方式。scp 是 secure copy 的縮寫, scp 是 linux 系統(tǒng)下基于 ssh 登陸進(jìn)行安全的遠(yuǎn)程文件拷貝命令。
- 打開(kāi)本地系統(tǒng)服務(wù) 文件 遠(yuǎn)程登入 允許訪問(wèn) 所有用戶
- 輸入:scp heap.hprof [email protected]:/Users/aobing/Downloads
- 輸入本機(jī)電腦登入密碼即可,就能顯示當(dāng)前在下載的進(jìn)度了
- 擴(kuò)展:舉一個(gè)用法的例子,假設(shè)用我自己當(dāng)前電腦作為演示,怎么去把我們跳板機(jī)中的dump文件下載到我們本地,以便于我們自己來(lái)分析堆棧呢?
- 這個(gè)是比較常用的方法,可以有其他的用法,就因個(gè)人而已吧
mkdir :用于創(chuàng)建目錄。這個(gè)是最簡(jiǎn)單的了。
- 擴(kuò)展:mkdir aaaa 創(chuàng)建一個(gè)aaaa文件
kill :刪除執(zhí)行中的程序或工作,這個(gè)需要慎重使用,我們可以一般在我們的電腦卡死,或者我們本地啟動(dòng)tomcat端口被占用了,但是我們又沒(méi)有找到,可以ps查一下進(jìn)程ID,然后kill一下
- 擴(kuò)展:kill 14269,殺死14269這個(gè)進(jìn)程
- 擴(kuò)展:kill -KILL 14269,強(qiáng)制殺死14269這個(gè)進(jìn)程
- 擴(kuò)展:kill -9 14269,徹底殺死14269這個(gè)進(jìn)程
rm :用于刪除一個(gè)文件或者目錄。在使用這個(gè)命令之前需要注意,不要隨便執(zhí)行這個(gè)命令,文件一旦通過(guò)rm命令刪除,則無(wú)法恢復(fù)所以可能有時(shí)候不小心刪除某些文件,第二天新聞就出來(lái)“杭州某公司丙某因?yàn)閳?zhí)行時(shí)rm -rf命令,導(dǎo)致服務(wù)器或者數(shù)據(jù)庫(kù) 數(shù)據(jù)丟失 造成嚴(yán)重?fù)p失”
- $rmgc.log.20210506151038
- rm:removeregularfile‘gc.log.20210506151038’?y
- 擴(kuò)展:rm gc.log.20210506151038 ,刪除 gc.log.20210506151038 文件?會(huì)跳出一個(gè)確定提示,輸入 y,則是刪除
- 擴(kuò)展:rm -f gc.log.20210506151038,不會(huì)產(chǎn)生確認(rèn)刪除提示,直接刪除文件
- 擴(kuò)展:rm -rf gc.log.20210506151038,不會(huì)產(chǎn)生確認(rèn)刪除提示,直接刪除文件,并且會(huì)把當(dāng)前目錄下的所有文件一并刪除,非常的暴力。
gzip :用于壓縮文件。文件經(jīng)它壓縮過(guò)后,其名稱后面會(huì)多出".gz"的擴(kuò)展名。當(dāng)服務(wù)器某個(gè)文件過(guò)大時(shí),你下載非常的慢,所以考慮一下壓縮之后再下載。
- 擴(kuò)展:gzip gc.log.20210506151038 ,壓縮一下文件gc.log.20210506151038,壓縮之后會(huì)生成一個(gè)文件gc.log.20210506151038.gz,這個(gè)比較簡(jiǎn)單,壓縮完可以使用上面的 ll 或者 du 等相關(guān)命令再查看下文件的大小。
- 擴(kuò)展:gzip -<壓縮效率> gc.log.20210506151038 , 壓縮效率是一個(gè)介于1-9的數(shù)值,預(yù)設(shè)值為"6",指定愈大的數(shù)值,壓縮效率就會(huì)愈高,控制壓縮比例。
ps :(全拼:process status)用于顯示當(dāng)前進(jìn)程的狀態(tài),主要是用來(lái)查詢當(dāng)前進(jìn)程的狀態(tài),比如說(shuō)需要查詢一下當(dāng)前tomcat的相關(guān)信息,或者說(shuō)服務(wù)器配置的tomcat的一些啟動(dòng)參數(shù),都是可以看到。
- $ps-ef|greptomcat
- www383304000:02pts/000:00:00grep--color=autotomcat
- www557918Oct22?10:36:09/opt/vdian/java/bin/java-Djava.util.logging.config.file=/home/www/item-sell/.server/conf/logging.properties-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager-Djdk.tls.ephemeralDHKeySize=2048-server-Xms5g-Xmx5g-XX:MetaspaceSize=256m-XX:MaxMetaspaceSize=256m-Xmn2g-XX:MaxDirectMemorySize=512m-XX:SurvivorRatio=8
- 擴(kuò)展:ps -ef | grep 進(jìn)程關(guān)鍵字,查詢某個(gè)關(guān)鍵字的進(jìn)程,如下所示,能顯示很多信息。我這里沒(méi)有復(fù)制全,自己可以進(jìn)公司的服務(wù)試一下,不會(huì)有問(wèn)題的。
- 擴(kuò)展:ps -A,列出所有的進(jìn)程
- 擴(kuò)展:ps -aux,顯示所有包含其他使用者的行程
- 等等還有很多很多,我就舉出常用的,一一列舉大家不常用也就沒(méi)有什么意思。
pwd :用于顯示工作目錄,這個(gè)命令就很簡(jiǎn)單了, 沒(méi)有什么特殊的參數(shù)啥的,就是顯示當(dāng)前目錄地址。
- $pwd
- /home/www
- 擴(kuò)展:pwd,跟簡(jiǎn)單,后面不需再加什么參數(shù),顯示一下目錄,方便下我們復(fù)制文件的目錄地址。
source :這個(gè)命令一般就是和**點(diǎn)(.)**是一樣的效果,就是修改了某個(gè)文件不用重啟,而可以立馬生效
- 擴(kuò)展:source fileName等于. fileName是一個(gè)效果。使改動(dòng)的文件立即生效
tail :用于查看文件的內(nèi)容。通常比如說(shuō)我們需要查看正在變動(dòng)的日志文件,那就可以用這個(gè)命令了。
- 擴(kuò)展:tail -f filename,會(huì)把 filename 文件里的最尾部的內(nèi)容顯示出來(lái),并且不斷刷新,只要 filename 更新就可以看到最新的文件內(nèi)容。
- 擴(kuò)展:tail -20f filename,會(huì)把 filename 文件里的最后的20行內(nèi)容顯示出來(lái),并且不斷刷新。
- 擴(kuò)展:tail -c 20 filename,顯示文件 filename 的最后 20 個(gè)字符。
- 擴(kuò)展:tail -n +20 filename,顯示文件 filename 的內(nèi)容,從第 20 行至文件末尾。
以上就是在Linux中我們工作中比較常用的一些命令,以及它們的一些擴(kuò)展,當(dāng)然,這個(gè)并不是全部的,我也只是列出了冰山一角。如果還是沒(méi)有滿足你們的日常工作可能就需要你們自己的再去查查資料,看看書了。
Java中的常見(jiàn)排查問(wèn)題命令
在工作中都會(huì)多少都會(huì)接觸到一些服務(wù)器調(diào)優(yōu),或者說(shuō)一些線上問(wèn)題排查,這是在面試過(guò)程中,面試官比較喜歡問(wèn)的一個(gè)問(wèn)題,也是為了考察面試者的思考能力以及動(dòng)手能力和基礎(chǔ)是否扎實(shí)。都說(shuō)是面試造飛機(jī),進(jìn)去擰螺絲。很多時(shí)候問(wèn)題都輪不到你來(lái)處理,但是你還是得會(huì)。
之前也有很多學(xué)弟學(xué)妹來(lái)給我留言怎么去排查一些線上服務(wù)器問(wèn)題,比如說(shuō)某個(gè)時(shí)間 dubbo線程池滿,內(nèi)存告警,以及OOM等。
所以這里主要也就跟學(xué)弟學(xué)妹從三個(gè)方面負(fù)載、cpu、內(nèi)存 這三個(gè)方面去聊聊,怎么通過(guò)一些命令去看這些東西。
負(fù)載
負(fù)載是對(duì)當(dāng)前CPU的工作量的一個(gè)度量,通常負(fù)載越低,說(shuō)明機(jī)器工作輕松,反之則越累,高負(fù)載的情況下就可能會(huì)出現(xiàn)機(jī)器無(wú)法處理其他的業(yè)務(wù)請(qǐng)求了。
查看負(fù)載的命令有很多,top、uptime 等都可以查看
- $uptime
- 01:13:53up319days,14:05,1user,loadaverage:0.39,0.34,0.39
從這個(gè)信息看,我們要關(guān)注的 是后面的 load average 顯示的信息
- load average:0.39, 0.34, 0.39 這三個(gè)數(shù)字的意思分別是1分鐘、5分鐘、15分鐘內(nèi)系統(tǒng)的平均負(fù)荷
- user:1 user,當(dāng)前一個(gè)用戶登入
前面顯示的信息就是服務(wù)器啟動(dòng)到現(xiàn)在已經(jīng)有多長(zhǎng)時(shí)間了。
top 命令是比較常見(jiàn)的,也是最常用的,因?yàn)樗@示的信息也是最全的。
- $top
- top-01:19:56up319days,14:11,1user,loadaverage:0.13,0.25,0.35
- Tasks:145total,1running,144sleeping,0stopped,0zombie
- %Cpu(s):2.8us,0.9sy,0.3ni,95.6id,0.1wa,0.0hi,0.2si,0.2st
- KiBMem:8173324total,142188free,5861548used,2169588buff/cache
- KiBSwap:0total,0free,0used.1634952availMem
- PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND
- 7704www20097140244.824g5932S27.661.93717:34java
- 2150root30107850085867235804S1.70.73254:22polaris-agent
- 16043www20038007324026043788S0.34.9603:29.85java
- 1root2004353633961948S0.00.056:12.32systemd
這里可以看到除了顯示平均負(fù)載的情況下還能顯示 CPU相關(guān)信息。還有每個(gè)進(jìn)程占用的資源情況。
針對(duì)負(fù)載的問(wèn)題,我們?cè)趺茨艽_定負(fù)載當(dāng)前是高還是低?
一般來(lái)說(shuō)只要負(fù)載超過(guò)0.7可能就表示當(dāng)前負(fù)載有點(diǎn)高了,需要排查一下,這個(gè)是針對(duì)單核CPU來(lái)說(shuō)的,如果是多核CPU來(lái)說(shuō),我們就是CPU核數(shù)乘以0.7來(lái)計(jì)算的。
在top顯示的進(jìn)程信息的時(shí)候,我們可能看到當(dāng)前進(jìn)程中 7704這個(gè)進(jìn)程 占用CPU最高,而且是我們的Java進(jìn)程
假設(shè)現(xiàn)在是CPU被這個(gè)進(jìn)程占用百分之90,那我們就可以重點(diǎn)排查一下這個(gè)進(jìn)程到底在做什么導(dǎo)致CPU占用這么高
- $top-Hp7704
- top-01:33:05up319days,14:24,1user,loadaverage:0.12,0.23,0.31
- Threads:651total,5running,646sleeping,0stopped,0zombie
- %Cpu(s):2.1us,0.8sy,0.3ni,96.4id,0.1wa,0.0hi,0.3si,0.1st
- KiBMem:8173324total,143612free,5862648used,2167064buff/cache
- KiBSwap:0total,0free,0used.1633376availMem
- PIDUSERPRNIVIRTRESSHRS%CPU%MEMTIME+COMMAND
- 9046www20097140244.824g5932S4.661.913:12.99java
- 8415www20097140244.824g5932R2.661.9442:19.10java
- 8418www20097140244.824g5932R2.661.9424:18.67java
top -Hp 是查看當(dāng)前進(jìn)程中的所有的線程情況,同樣的可以看到 9046 這個(gè)線程占用比較高,那么我們?cè)俳又治鲞@個(gè)線程在處理什么邏輯就可以了。
- $printf%s9046
- 2356
使用printf命令查看這個(gè)線程的16進(jìn)制
最后使用jstack命令查看當(dāng)前線程正在執(zhí)行的什么方法
- $jstack7704|grep-A102356
- "DubboServerHandler-10.33.130.247:2201-thread-154"#867daemonprio=5os_prio=0tid=0x00007f4ef005a800nid=0x2356waitingoncondition[0x00007f4ec1acf000]
- java.lang.Thread.State:WAITING(parking)
- atsun.misc.Unsafe.park(NativeMethod)
- -parkingtowaitfor<0x0000000708513d48>(ajava.util.concurrent.SynchronousQueue$TransferStack)
- atjava.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
- atjava.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:458)
- atjava.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
- atjava.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:924)
- atjava.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
- atjava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
- atjava.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
從這里就能大致做一個(gè)分析了,但是這個(gè)不一定都能確定出來(lái)問(wèn)題,但是能給我展示出一些有用的信息。具體的還需要我們?cè)偃タ聪逻@里執(zhí)行了什么方法。
再或者我們直接使用 jmap 來(lái)dump內(nèi)存。
CPU
在看CPU信息的時(shí)候主要關(guān)注的點(diǎn)就是CPU的使用率。
在上面使用top能查看CPU的使用情況之后,還有一個(gè)vmstat命令,這個(gè)命令有一個(gè)好處可以看到內(nèi)存使用,虛擬內(nèi)存還有IO等信息。
- $vmstat
- procs-----------memory-------------swap-------io-----system--------cpu-----
- rbswpdfreebuffcachesisobiboincsussyidwast
- 000172572021337800015100419500
- us:用戶進(jìn)程執(zhí)行時(shí)間百分比(如果當(dāng)前值比較高,說(shuō)明用戶進(jìn)程消耗高)
- sy:內(nèi)核系統(tǒng)進(jìn)程執(zhí)行時(shí)間百分比(如果系統(tǒng)比較高,那么你可以找運(yùn)維了)
- id:空閑時(shí)間百分比
- wa:IO等待時(shí)間百分比(如果IO時(shí)間長(zhǎng),那說(shuō)明機(jī)器在大量的處理磁盤的讀寫操作,這個(gè)也是關(guān)注的重點(diǎn),可能寫日志啊等都有可能)
- st:虛擬 CPU 等待實(shí)際 CPU 的時(shí)間的百分比
所以觸發(fā)CPU高的場(chǎng)景也有很多,這個(gè)CPU高可能只是一個(gè) “果的關(guān)系”,具體的“因”是啥還需要在進(jìn)步排查,比如說(shuō)再用top,按上面的思路再看下。
內(nèi)存
內(nèi)存是保證我們程序能正常運(yùn)行的關(guān)鍵,這個(gè)也是需要我們查看的一個(gè)關(guān)鍵指標(biāo)數(shù)據(jù)。
查看內(nèi)存的命令除了上面的top之外還有一個(gè)free來(lái)查看內(nèi)存數(shù)據(jù)。細(xì)心的人應(yīng)該發(fā)現(xiàn)了top命令真的展示信息最全了。當(dāng)然我們還是主要分析一下這個(gè)命令展示的數(shù)據(jù),以及怎么分析這些數(shù)據(jù)。
- $free
- totalusedfreesharedbuff/cacheavailable
- Mem:8173324587086812644840181221760081625028
- Swap:000
Mem行,顧名思義也就是展示內(nèi)存的使用情況
- total:表示物理內(nèi)存總大小
- used:已經(jīng)被使用的物理內(nèi)存和交換空間
- free:表示未被分配的內(nèi)存
- shared:共享使用的物理內(nèi)存大小
- buff/cache buffer 和 cache 使用的物理內(nèi)存大小
- available:當(dāng)前剩余實(shí)際可用內(nèi)存(還可以被應(yīng)用程序使用的物理內(nèi)存大小)
Swap:這個(gè)被稱之為交換區(qū),當(dāng)系統(tǒng)內(nèi)存不夠使用時(shí),釋放磁盤內(nèi)存,來(lái)保證當(dāng)前運(yùn)行的程序能正常使用(Linux會(huì)將一些不常訪問(wèn)的數(shù)據(jù)保存在交換區(qū),但是目前一般不會(huì)配置)。
- Total:Swap內(nèi)存總大小
- Used:已分配的Swap大小
- Free:未被分配的內(nèi)存
所以在查看內(nèi)存的時(shí)候我們還是不能不能確定這個(gè)因果關(guān)系,在出現(xiàn)問(wèn)題的時(shí)候,如果我們沒(méi)有一個(gè)很好的思路,就先看看這三個(gè)指標(biāo),可以通過(guò)一些排除法來(lái)給我們一些思考。
但是現(xiàn)在我們最常用的基本都是看top 一下看看各個(gè)指標(biāo),如果確定是Java進(jìn)程的問(wèn)題,很多時(shí)候都會(huì)去dump一下內(nèi)存,來(lái)分析一下對(duì)象信息。如果有很多大對(duì)象,一直被引用那就具體看代碼了。一般的問(wèn)題大部分都是因?yàn)槲覀兊拇a引起的。
Arthas
說(shuō)到dump內(nèi)存,常見(jiàn)的可能就是使用jmap 命令來(lái)處理,但是這里跟大家分享一個(gè)新的阿里開(kāi)源的工具Arthas。
Arthas 是Alibaba開(kāi)源的Java診斷工具,深受開(kāi)發(fā)者喜愛(ài)。在線排查問(wèn)題,無(wú)需重啟;動(dòng)態(tài)跟蹤Java代碼;實(shí)時(shí)監(jiān)控JVM狀態(tài)。
我個(gè)人覺(jué)得也確實(shí)是蠻好用的。官方文檔:https://arthas.aliyun.com/doc/arthas-tutorials.html?language=cn
首先就是先安裝一下
- $curl-Ohttps://arthas.aliyun.com/arthas-boot.jar
- %Total%Received%XferdAverageSpeedTimeTimeTimeCurrent
- DloadUploadTotalSpentLeftSpeed
- 100138k100138k00420k0--:--:----:--:----:--:--421k
啟動(dòng)
- $java-jararthas-boot.jar
- [INFO]arthas-bootversion:3.5.4
- [INFO]Foundexistingjavaprocess,pleasechooseoneandinputtheserialnumberoftheprocess,eg:1.ThenhitENTER.
- *[1]:20851/home/www/xxxxx/xxxx.14_75b3f783befda28c22c6ce8b48d7f41b_prod.jar
- [2]:6152com.xxxx.xxxx.xxxx.main.Main
這里看到會(huì)有兩個(gè)應(yīng)用但是我們需要進(jìn)入Java應(yīng)用,所以直接按2,進(jìn)入。
因此如果需要dump堆棧內(nèi)存只要一個(gè)命令就可以了
dump到指定文件
- heapdump/tmp/dump.hprof
只dump live對(duì)象
- heapdump--live/tmp/dump.hprof
在dump堆棧的時(shí)候是會(huì)觸發(fā)fullGC的這個(gè)需要注意一下,一般針對(duì)這有問(wèn)題的機(jī)器,可以先把這個(gè)機(jī)器offline掉,這樣流量進(jìn)不來(lái),保證平臺(tái)先“止血“。
在獲取到堆棧信息之后那就是分析堆棧了,可以MAT、Jprofiler等,但是還有一個(gè)簡(jiǎn)單的輕小的gceasy也可以去分析一個(gè)堆棧信息。
還有一個(gè)我們比較常用的功能就是分析我們方法的耗時(shí)問(wèn)題。
假設(shè)現(xiàn)在我們有個(gè)方法,里面有很多子方法,包含很多rpc掉用,以及很多很多的業(yè)務(wù)邏輯在里面,那我們?cè)趺慈カ@取每個(gè)子方法的耗時(shí)呢?
針對(duì)相信上面的問(wèn)題,很多人都會(huì)想到先用System.currentTimeMillis()來(lái)獲取當(dāng)前時(shí)間,然后每執(zhí)行一個(gè)方法在減去開(kāi)始的時(shí)間以此來(lái)得到一個(gè)時(shí)間差,再用日志打印出來(lái)。這樣雖然是可行的,但是非常的麻煩。Arthas里面有一個(gè)trace命令就能幫我處理這個(gè)問(wèn)題。
- [arthas@6152]$tracecom.xxxx.xxx.xxx.service.ItemSnapshotServicesaveFullSnapshot
- PressQorCtrl+Ctoabort.
- Affect(classcount:1,methodcount:1)costin231ms,listenerId:3
- `---ts=2021-10-2802:50:23;thread_name=ConsumeMessageThread_4;id=3c2;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2
- `---[3.939696ms]com.xxx.xx.xx.service.ItemSnapshotService:saveFullSnapshot()
- +---[0.047704ms]com.xxx.xx.xx.service.ItemSnapshotService:$jacocoInit()
- +---[0.014779ms]com.xx.xx.xx.xx.snapshot.ItemSnapShot:getItemId()#304
- +---[0.008545ms]com.xxx.xxx.xx.x.snapshot.ItemSnapShot:getOperateTime()#305
- +---[0.306668ms]com.xx.xxx.xx.service.ItemSnapshotService:buildRowKey()#306
- +---[0.006373ms]com.xxx.xx.xxx.domain.snapshot.ItemSnapShot:getAfter()#307
- +---[0.004874ms]com.xx.xx.xx.domain.snapshot.ItemSnapShot:getBefore()#307
- +---[0.058562ms]
展示結(jié)果如上所示,還有能做過(guò)濾啊,統(tǒng)計(jì)次數(shù)啊等等一些功能。
Arthas它的功能還有很多很多啊,我也一下子說(shuō)不完,感興趣的同學(xué)可以去看看我貼的那個(gè)官方文檔。之所以跟大家聊這個(gè)是我覺(jué)得確實(shí)挺好用的,在我們的工作中能起到一個(gè)很好的幫助。
總結(jié)
這次跟大家分享的都是我個(gè)人感覺(jué)在工作中比較實(shí)用的一些常見(jiàn)命令以及工具,以及在工作中會(huì)經(jīng)常遇到的一些問(wèn)題。這也是在面試的過(guò)程中您能和面試官聊的東西。只有當(dāng)別人不知道而你知道那你就走在別人的前面,不是故意要卷,而是當(dāng)前互聯(lián)網(wǎng)就是一個(gè)卷的時(shí)代了。
本次要跟學(xué)弟學(xué)妹聊的一些命令就到到這里了,雖然擴(kuò)展了很多其他的東西,但是我感覺(jué)還是比較有用的吧!!!
原文鏈接:https://mp.weixin.qq.com/s/T6try9YIKh8gTLG2lyKKOQ