Linux - 生产故障、性能评估面试题
目錄
- 1、生產(chǎn)環(huán)境服務(wù)器變慢,診斷思路和性能評估談?wù)?#xff1b;linux怎么查看系統(tǒng)負(fù)載情況
- 一、查看cpu
- 二、查看內(nèi)存
- 三、查看硬盤
- 四、磁盤IO
- 五、網(wǎng)絡(luò)I/O
- 記一次真實(shí)排查經(jīng)歷
- 2、假如生產(chǎn)環(huán)境出現(xiàn)cpu占用過高,請你談?wù)勀愕姆治鏊悸泛投ㄎ?/li>
- 3、Linux什么命令可以查詢java調(diào)用棧【度小滿】
- 4、linux,怎么統(tǒng)計(jì)一個(gè)文件的某詞的出現(xiàn)次數(shù)【度小滿】
- 5、kill -9 中9的含義是啥?【度小滿】
- 6、大日志怎么切分?【度小滿】
- 7、怎么查看一個(gè)進(jìn)程的端口號?【度小滿】
- 8、Linux,grep命令,在大日志文件中搜索關(guān)鍵字,最后/最開始出現(xiàn)位置【度小滿】
- 9、怎么動態(tài)的查看jvm內(nèi)存【度小滿】
- 9、監(jiān)視虛擬機(jī)各種運(yùn)行狀態(tài)信息【也可以動態(tài)的查看jvm內(nèi)存】
- 10、內(nèi)存泄漏怎么排查
- 10.1 確定頻繁Full GC現(xiàn)象
- 10.2、找出導(dǎo)致頻繁Full GC的原因
- 11、linux如何快速到文件底部和頭部
- 12、某個(gè)文件夾下,查找關(guān)鍵字并上色
1、生產(chǎn)環(huán)境服務(wù)器變慢,診斷思路和性能評估談?wù)?#xff1b;linux怎么查看系統(tǒng)負(fù)載情況
例子:linux上跑該java程序
import java.util.Random; public class JavaDemo02 {public static void main(String[] args) {while(true){System.out.println(new Random().nextInt(77778888));}} }一、查看cpu
1、整機(jī)性能查看:top命令,看cpu、內(nèi)存以及系統(tǒng)負(fù)載
[root@localhost ~]# jps -l 18734 sun.tools.jps.Jps 18687 JavaDemo02看右上角系統(tǒng)的負(fù)載,3個(gè)值,分別代表系統(tǒng)1分鐘,5分鐘,15分鐘的平均負(fù)載,如果三個(gè)值相加,除以3,再乘以100%,高于60%,那么表示系統(tǒng)的負(fù)擔(dān)壓力重
按小鍵盤上的1,能查看各個(gè)cpu
2、系統(tǒng)性能命令的精簡版
[root@localhost ~]# uptime21:55:33 up 5 min, 2 users, load average: 0.66, 2.05, 1.103、查看CPU
表示每兩秒采樣一次,共計(jì)采樣三次
procs:
- r表示運(yùn)行和等待cpu時(shí)間片的進(jìn)程數(shù),原則上1核的cpu運(yùn)行隊(duì)列不要超過2,整個(gè)系統(tǒng)的運(yùn)行隊(duì)列不能超過總核數(shù)的2倍,否則表示系統(tǒng)壓力過大
- b表示等待資源的進(jìn)程數(shù),比如正在等待磁盤I/O,網(wǎng)絡(luò)I/O等
CPU:
- us:用戶進(jìn)程消耗cpu時(shí)間片,us值高,用戶進(jìn)程消耗cpu時(shí)間多,如果長期大于50%,優(yōu)化程序;
- sy:內(nèi)核進(jìn)程消耗的cpu時(shí)間百分比
- us+sy參考值為80%,如果us+sy大于80%,說明可能存在cpu不足
- id:處于空閑的cpu百分比
- wa:系統(tǒng)等待io的cpu時(shí)間百分比
- st:來自于一個(gè)虛擬機(jī)偷取的cpu時(shí)間的百分比
4、查看所有cpu核信息
yum install sysstat [root@localhost init.d]# mpstat -P ALL 2mpstat [-P {|ALL}] [internal [count]] 參數(shù):(1)-P {|ALL}:表示監(jiān)控哪個(gè)CPU,在[0,cpu個(gè)數(shù)-1]中取值;(2)internal:相鄰的兩次采樣的間隔時(shí)間;(3)count:采樣的次數(shù),count只能和delay一起使如果cpu空閑率idle低于60,表示壓力來了
5、每個(gè)進(jìn)程使用cpu的用來分解信息
二、查看內(nèi)存
1.查看系統(tǒng)內(nèi)存情況
[root@iz2ze5pjtwp4umzvw3ikwyz /root]#free -mtotal used free shared buff/cache available Mem: 1838 1058 84 0 695 625 Swap: 0 0 0- 應(yīng)用程序可用內(nèi)存/系統(tǒng)物理內(nèi)存>70% :表示內(nèi)存充足
- 應(yīng)用程序可用內(nèi)存/系統(tǒng)物理內(nèi)存<20% :表示內(nèi)存不足,需要增加內(nèi)存
- 20%<應(yīng)用程序可用內(nèi)存/系統(tǒng)物理內(nèi)存<70%:基本夠用
2.查看某個(gè)進(jìn)程內(nèi)存占用情況
pidstat -p 進(jìn)程號 -r 采樣間隔秒數(shù)
三、查看硬盤
1.查看硬盤剩余空間數(shù)
df -h
17G用了8.9G,還剩8.2G
四、磁盤IO
系統(tǒng)慢,基本上,一個(gè)是cpu導(dǎo)致,一個(gè)是磁盤io;
磁盤io,mysql大表存儲,查詢的時(shí)候,大片的數(shù)據(jù)在磁盤上io,如果這個(gè)時(shí)候長時(shí)間的io,將會導(dǎo)致系統(tǒng)很大的問題。
1、系統(tǒng)整體的磁盤I/o性能評估
兩秒鐘取樣一次,取樣3次
磁盤塊設(shè)備分布:
- rkB/s每秒讀取數(shù)據(jù)量KB
- wkB/s每秒寫入數(shù)據(jù)量KB
- svctm I/O請求的平均服務(wù)時(shí)間,單位毫秒
- await I/O請求的平均等待時(shí)間,單位毫秒;值越小,性能越好
- util 一秒中有百分幾的時(shí)間用于i/o操作。接近100%時(shí),表示磁盤帶寬跑滿,需要優(yōu)化程序或者增加磁盤; 這個(gè)指標(biāo)最重要
- rkB/s 、wkB/s根據(jù)系統(tǒng)應(yīng)用不同會有不同的值,但有規(guī)律遵循:長期、超大數(shù)據(jù)讀寫,肯定不正常,需要優(yōu)化程序讀取。
- svctm與await 的值很接近,表示幾乎沒有i/o等待,磁盤性能好。如果await 的值遠(yuǎn)高于svctm的值,則表示i/o隊(duì)列等待太長,需要優(yōu)化程序或更換更快的磁盤。
命令參數(shù):
-c: 顯示CPU使用情況
-d: 顯示磁盤使用情況
-N: 顯示磁盤陣列(LVM) 信息
-n: 顯示NFS 使用情況
-k: 以 KB 為單位顯示
-m: 以 M 為單位顯示
-t: 報(bào)告每秒向終端讀取和寫入的字符數(shù)和CPU的信息
-V: 顯示版本信息
-x: 顯示詳細(xì)信息
-p:[磁盤] 顯示磁盤和分區(qū)的情況
2、查看某個(gè)進(jìn)程的磁盤i/o占用情況
[root@localhost elasticsearch]# pidstat -d 2 -p 8469 Linux 3.10.0-957.el7.x86_64 (localhost.localdomain) 2020年09月27日 _x86_64_ (1 CPU)23時(shí)23分02秒 UID PID kB_rd/s kB_wr/s kB_ccwr/s Command 23時(shí)23分04秒 1000 8469 0.00 0.00 0.00 java 23時(shí)23分06秒 1000 8469 0.00 0.00 0.00 java 23時(shí)23分08秒 1000 8469 0.00 0.00 0.00 javakB_rd/s:進(jìn)程每秒從磁盤讀取的數(shù)據(jù)量(以kB為單位)
kB_wr/s:進(jìn)程每秒向磁盤寫入的數(shù)據(jù)量(以kB為單位)
kB_ccwr/s:任務(wù)寫入磁盤被取消的速率(KB);當(dāng)任務(wù)截?cái)嗯K的pagecache的時(shí)候會發(fā)生。
3、如果不知道進(jìn)程號,但是iostat -xdk 2 3,又顯示磁盤占用高,怎么找到是哪個(gè)進(jìn)程占用高呢
一、通過 iotop 命令: yum install iotop 進(jìn)行安裝
–version 查看版本
-h, --help 查看幫助
-o, --only 只顯示有 IO 操作的進(jìn)程或線程
-b, --batch 沒有交互的模式,可以當(dāng)成日志直接輸出到文件記錄用。
-n NUM, --iter=NUM 循環(huán)次數(shù),在刷新了指定的次數(shù)后,程序就退出
-d SEC, --delay=SEC 刷新的頻率,默認(rèn) 1 秒一次
-p PID, --pid=PID 監(jiān)視單個(gè)進(jìn)程,默認(rèn)監(jiān)視所有。要監(jiān)視多個(gè),可以加多個(gè) -p PID
-u USER, --user=USER 監(jiān)視單個(gè)用戶,默認(rèn)監(jiān)視所有。
-P, --processes 只顯示進(jìn)程,不顯示線程。
-a, --accumulated 在 Disk Read 和 Disk Write 列顯示的是從 iotop 啟動開始,累計(jì)的數(shù)據(jù)量。
-k, --kilobytes 使用 KB 為單位。
-t, --time 在每一行加上時(shí)間戳
-q, --quiet 退出
例如:
iotop -oP -d 3 -t -b > /root/lzhdir/iotop.log二、通過 pidstat 命令
1 # 命令的含義:展示I/O統(tǒng)計(jì),每秒更新一次 2 # pidstat -d 1五、網(wǎng)絡(luò)I/O
ifstat的安裝使用: wget http://distfiles.macports.org/ifstat/ifstat-1.1.tar.gz tar xzvf ifstat-1.1.tar.gz cd ifstat-1.1 ./configure make make install查看網(wǎng)絡(luò)io: ifstat 1 每秒一次
[root@localhost ~]# ifstat 1ens33 docker0 vethd199461 veth5851ec1 vethca401c0 vethec1ba70 vethabce5d0 vethbdc7e7f KB/s in KB/s out KB/s in KB/s out KB/s in KB/s out KB/s in KB/s out KB/s in KB/s out KB/s in KB/s out KB/s in KB/s out KB/s in KB/s out0.06 0.42 34.88 35.76 0.00 0.00 13.29 22.54 0.00 0.00 22.54 13.22 0.00 0.00 0.00 0.000.06 0.26 0.36 0.45 0.00 0.00 0.45 0.45 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.000.06 0.26 0.51 0.55 0.00 0.00 0.29 0.26 0.00 0.00 0.26 0.29 0.00 0.00 0.00 0.000.06 0.26 2.22 2.31 0.00 0.00 1.71 0.67 0.00 0.00 0.61 1.64 0.00 0.00 0.00 0.00記一次真實(shí)排查經(jīng)歷
問題:服務(wù)器開機(jī)內(nèi)存便占用過半,一段時(shí)間后,內(nèi)存幾乎占用滿,但是開機(jī)以來,沒有運(yùn)行過任何程序。
排查問題的過程:
1、free -m 查看內(nèi)存,只能查看出系統(tǒng)內(nèi)存占用高,但看不出是哪個(gè)進(jìn)程在占用內(nèi)存
2、top 查看cpu,內(nèi)存以及負(fù)載,查看出負(fù)載很高,但是cpu和內(nèi)存并沒有異常【忘了截圖】,還是確定不下來是哪個(gè)進(jìn)程的問題
意外收獲:多次觀察下,發(fā)現(xiàn)了fdfs_storaged,fastdfs我并沒有啟動,怎么會有的呢
803 root 20 0 214724 67196 736 S 0.3 3.6 0:00.30 fdfs_storaged
3、iostat -xdk 2 3查看磁盤I/O,發(fā)現(xiàn)util指標(biāo)極高
4、 pidstat -d 1 命令,查看是哪個(gè)進(jìn)程導(dǎo)致的磁盤io高
發(fā)現(xiàn)了fdfs_trackerd進(jìn)程占用磁盤io,結(jié)合top命令發(fā)現(xiàn)的fdfs_storaged進(jìn)程,懷疑fastdfs是開機(jī)自啟動,于是百度了一下,如何關(guān)閉fastdfs的自啟動,意外發(fā)現(xiàn)fastdfs與nginx是一起工作的,直接使用命令ps -ef |grep fdfs 以及ps -ef |grep nginx,果然,這兩貨,都是自啟動,直接kill,然后在關(guān)閉自啟動,再次查看內(nèi)存,發(fā)現(xiàn)變化不大,難道還有其他自啟動的程序?繼續(xù)觀察top,發(fā)現(xiàn)了mysql的進(jìn)程,關(guān)了,并且自啟動也關(guān)了,好了
2、假如生產(chǎn)環(huán)境出現(xiàn)cpu占用過高,請你談?wù)勀愕姆治鏊悸泛投ㄎ?/h2>
1、top命令,找出cpu占比高的進(jìn)程
比如:進(jìn)程號58814
2、ps -ef或jps -l進(jìn)一步定位,得知是怎樣的一個(gè)后臺進(jìn)程在惹事
3、定位到具體的線程或者代碼
發(fā)現(xiàn)是線程號位58815的線程在惹事
ps -mp 58814 -o THREAD,tid,time
-m 顯示所有的線程
-p pid進(jìn)程使用cpu的時(shí)間
-o 該參數(shù)后是用戶自定義格式
4、將需要的線程id轉(zhuǎn)換為16進(jìn)程格式(英文小寫格式)
[root@localhost ~]# printf "%x\n" 58815 e5bf5、jstack 進(jìn)程號 | grep tid -A60
[root@localhost ~]# jstack 58814 | grep e5bf -A60 "main" #1 prio=5 os_prio=0 tid=0x00007f5378009000 nid=0xe5bf runnable [0x00007f5381ac0000]java.lang.Thread.State: RUNNABLEat java.io.FileOutputStream.writeBytes(Native Method)at java.io.FileOutputStream.write(FileOutputStream.java:326)at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)- locked <0x00000000ed01d528> (a java.io.BufferedOutputStream)at java.io.PrintStream.write(PrintStream.java:482)- locked <0x00000000ed014fc0> (a java.io.PrintStream)at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)- locked <0x00000000ed014f78> (a java.io.OutputStreamWriter)at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)at java.io.PrintStream.write(PrintStream.java:527)- eliminated <0x00000000ed014fc0> (a java.io.PrintStream)at java.io.PrintStream.print(PrintStream.java:597)at java.io.PrintStream.println(PrintStream.java:736)- locked <0x00000000ed014fc0> (a java.io.PrintStream)at JavaDemo02.main(JavaDemo02.java:6)"VM Thread" os_prio=0 tid=0x00007f537806d800 nid=0xe5c0 runnable "VM Periodic Task Thread" os_prio=0 tid=0x00007f53780b9000 nid=0xe5c7 waiting on condition JNI global references: 9at JavaDemo02.main(JavaDemo02.java:6);是這行代碼惹的事
3、Linux什么命令可以查詢java調(diào)用棧【度小滿】
jstack主要用來查看某個(gè)Java進(jìn)程內(nèi)的線程堆棧信息。
排查死鎖:
jps -l 查看進(jìn)程號
jstack 進(jìn)程號> 進(jìn)程號.txt 打開生成的文件,滑到最底下
4、linux,怎么統(tǒng)計(jì)一個(gè)文件的某詞的出現(xiàn)次數(shù)【度小滿】
grep -o "要統(tǒng)計(jì)的詞" 文件名 | wc -l 統(tǒng)計(jì)一個(gè):grep -o "a" test | wc -l統(tǒng)計(jì)二個(gè):grep -o "a\|b" test | wc -l5、kill -9 中9的含義是啥?【度小滿】
-9 代表強(qiáng)制殺死進(jìn)程。
6、大日志怎么切分?【度小滿】
方法一:head命令
head命令是用來獲取文本文件的開始n行。
方法二:tail命令
tail命令是用來獲取文本最后行。
方法三:sed命令
sed命令可以從第N行截取到第M行。( N > 0 , M < FileLineNumber )
方法四:split命令
每300行切分生成一個(gè)新文件,–verbose顯示切分進(jìn)度
每10M切分成一個(gè)新的文件,–verbose 顯示切分進(jìn)度
split -d 10m java.txt javaLog --verbose7、怎么查看一個(gè)進(jìn)程的端口號?【度小滿】
netstat -napl | grep 進(jìn)程號
[root@localhost sentinel]# jps -l 27350 sentinel-dashboard-1.7.1.jar 27366 sun.tools.jps.Jps [root@localhost sentinel]# netstat -napl | grep 27350 tcp6 0 0 :::8011 :::* LISTEN 27350/java tcp6 0 0 :::8719 :::* LISTEN 27350/java unix 2 [ ] STREAM CONNECTED 111050 27350/java unix 2 [ ] STREAM CONNECTED 111039 27350/java8、Linux,grep命令,在大日志文件中搜索關(guān)鍵字,最后/最開始出現(xiàn)位置【度小滿】
Linux grep 命令用于查找文件里符合條件的字符串。
-c是搜索關(guān)鍵字出現(xiàn)位置,并且和上下相鄰n行的結(jié)果grep -C 1 'INFO' sentinel.log |head -3 grep -C 1 'error' sentinel.log |tail -3https://www.pianshen.com/article/45201320508/9、怎么動態(tài)的查看jvm內(nèi)存【度小滿】
[root@localhost logs]# jmap -heap 27350 Attaching to process ID 27350, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.161-b12using thread-local object allocation. Mark Sweep Compact GCHeap Configuration:MinHeapFreeRatio = 40MaxHeapFreeRatio = 70MaxHeapSize = 478150656 (456.0MB)NewSize = 10485760 (10.0MB)MaxNewSize = 159383552 (152.0MB)OldSize = 20971520 (20.0MB)NewRatio = 2SurvivorRatio = 8MetaspaceSize = 21807104 (20.796875MB)CompressedClassSpaceSize = 1073741824 (1024.0MB)MaxMetaspaceSize = 17592186044415 MBG1HeapRegionSize = 0 (0.0MB)Heap Usage: New Generation (Eden + 1 Survivor Space):capacity = 14614528 (13.9375MB)used = 8833496 (8.424278259277344MB)free = 5781032 (5.513221740722656MB)60.44325208450112% used Eden Space:capacity = 13041664 (12.4375MB)used = 8639416 (8.239189147949219MB)free = 4402248 (4.198310852050781MB)66.24473686793341% used From Space:capacity = 1572864 (1.5MB)used = 194080 (0.185089111328125MB)free = 1378784 (1.314910888671875MB)12.339274088541666% used To Space:capacity = 1572864 (1.5MB)used = 0 (0.0MB)free = 1572864 (1.5MB)0.0% used tenured generation:capacity = 32301056 (30.8046875MB)used = 26747672 (25.508567810058594MB)free = 5553384 (5.296119689941406MB)82.80742276661172% used19495 interned Strings occupying 2488816 bytes.9、監(jiān)視虛擬機(jī)各種運(yùn)行狀態(tài)信息【也可以動態(tài)的查看jvm內(nèi)存】
jstat -gcutil 進(jìn)程號 1000 意思是每1000毫秒查詢一次,一直查。gcutil的意思是已使用空間站總空間的百分比
查詢結(jié)果表明:這臺服務(wù)器的新生代Eden區(qū)(E,表示Eden)使用了28.30%(最后)的空間,兩個(gè)Survivor區(qū)(S0、S1,表示Survivor0、Survivor1)分別是0和8.93%,老年代(O,表示Old)使用了87.33%。程序運(yùn)行以來共發(fā)生Minor GC(YGC,表示Young GC)101次,總耗時(shí)1.961秒,發(fā)生Full GC(FGC,表示Full GC)7次,Full GC總耗時(shí)3.022秒,總的耗時(shí)(GCT,表示GC Time)為4.983秒。
內(nèi)存泄漏例子:
有大量的FGC就要查詢是否有內(nèi)存泄漏的問題了,圖中的FGC數(shù)量就比較大,并且執(zhí)行時(shí)間較長,這樣就會導(dǎo)致系統(tǒng)的響應(yīng)時(shí)間較長,如果對jvm的內(nèi)存設(shè)置較大,那么執(zhí)行一次FGC的時(shí)間可能會更長。
如果為了更好的證明FGC對服務(wù)器性能的影響,我們可以使用java visualVM來查看一下:
從上圖可以發(fā)現(xiàn)執(zhí)行FGC的情況,下午3:10分之前是沒有FGC的,之后出現(xiàn)大量的FGC。
下圖是jvm堆內(nèi)存的使用情況,下午3:10分之前的內(nèi)存回收還是比較合理,但是之后大量內(nèi)存無法回收,最后導(dǎo)致內(nèi)存越來越少,導(dǎo)致大量的full gc。
下面我們在看看大量full GC對服務(wù)器性能的影響,下面是我用loadrunner對我們項(xiàng)目進(jìn)行壓力測試相應(yīng)時(shí)間的截圖:
從圖中可以發(fā)現(xiàn)有,在進(jìn)行full GC后系統(tǒng)的相應(yīng)時(shí)間有了明顯的增加,點(diǎn)擊率和吞吐量也有了明顯的下降。所以java內(nèi)存泄漏對系統(tǒng)性能的影響是不可忽視的。
10、內(nèi)存泄漏怎么排查
https://www.cnblogs.com/wyb628/p/8567617.html
https://www.jianshu.com/p/4548ab7f60e2
內(nèi)存溢出和內(nèi)存泄露的聯(lián)系,內(nèi)存泄露會最終會導(dǎo)致內(nèi)存溢出。
都會導(dǎo)致應(yīng)用程序運(yùn)行出現(xiàn)問題,性能下降或掛起。
10.1 確定頻繁Full GC現(xiàn)象
通過"監(jiān)視虛擬機(jī)各種運(yùn)行狀態(tài)信息"
10.2、找出導(dǎo)致頻繁Full GC的原因
分析方法通常有兩種:
1)把堆dump下來再用MAT等工具進(jìn)行分析,但dump堆要花較長的時(shí)間,并且文件巨大,再從服務(wù)器上拖回本地導(dǎo)入工具,這個(gè)過程有些折騰,不到萬不得已最好別這么干。
2)更輕量級的在線分析,使用“Java內(nèi)存影像工具:jmap”生成堆轉(zhuǎn)儲快照(一般稱為headdump或dump文件)。
jmap命令格式:
jmap [ option ] vmid
使用命令如下:
jmap -histo:live 20954
查看存活的對象情況,如下圖所示:
按照一位IT友的說法,數(shù)據(jù)不正常,十有八九就是泄露的。在我這個(gè)圖上對象還是挺正常的。
可以看出HashTable中的元素有5000多萬,占用內(nèi)存大約1.5G的樣子。這肯定不正常。
定位到代碼
定位到代碼,有很多種方法,比如前面提到的通過MAT查看Histogram即可找出是哪塊代碼。——我以前是使用這個(gè)方法。也可以使用BTrace,我沒有使用過。
舉個(gè)例子:
如圖,Object有197130個(gè)引用對象,大量的teaher對象,這些teacher被ArrayList引用,導(dǎo)致不能被回收,這些ArrayList,存在于類HeapDemo中。
這就定位出來了,只需要到HeapDemo中,去看看代碼怎么寫的
11、linux如何快速到文件底部和頭部
gg 到文件頂部
shift+g到文件底部
12、某個(gè)文件夾下,查找關(guān)鍵字并上色
find . -type f| xargs egrep '####\(business_changed_notify\)' -A10 -B10 --color=auto總結(jié)
以上是生活随笔為你收集整理的Linux - 生产故障、性能评估面试题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python链表怎么定义_链表初介绍以及
- 下一篇: 数据库死锁及解决办法