引言
Linux服務(wù)器性能問題是最讓運維工程師頭疼的故障之一。服務(wù)器響應(yīng)緩慢、網(wǎng)站打開轉(zhuǎn)圈、數(shù)據(jù)庫查詢超時,這些現(xiàn)象背后可能隱藏著CPU打滿、內(nèi)存泄漏、磁盤IO瓶頸、網(wǎng)絡(luò)延遲等各種原因。不同于服務(wù)不可用這種"非黑即白"的故障,性能問題往往是漸進(jìn)的、模糊的,需要運維工程師有系統(tǒng)的排查思路和豐富的經(jīng)驗積累。
本文面向初中級運維工程師和系統(tǒng)管理員,詳細(xì)講解Linux服務(wù)器性能問題的排查流程。文章不追求面面俱到的理論講解,而是從實戰(zhàn)出發(fā),提供可以直接落地執(zhí)行的操作步驟。內(nèi)容包括CPU、內(nèi)存、磁盤IO、網(wǎng)絡(luò)四大基礎(chǔ)資源的排查方法,進(jìn)程級別性能分析工具的使用,以及常見性能瓶頸的識別和處理。
本文假設(shè)讀者具備基本的Linux操作能力,能夠熟練使用top、ps等基礎(chǔ)命令。閱讀本文后,讀者應(yīng)該能夠:對性能問題建立系統(tǒng)化的排查思路、使用top、htop、vmstat、iostat、netstat等工具進(jìn)行性能診斷、分析CPU、內(nèi)存、磁盤、網(wǎng)絡(luò)四大資源的瓶頸所在、定位到具體進(jìn)程或服務(wù)并進(jìn)行處理。
一、性能排查基礎(chǔ)
1.1 性能問題的分類
Linux服務(wù)器性能問題可以分為四大類:CPU密集型、內(nèi)存密集型、IO密集型、網(wǎng)絡(luò)密集型。實際生產(chǎn)環(huán)境中,往往是多種問題混合存在,需要綜合分析。
CPU密集型問題的特征是服務(wù)器負(fù)載高但I(xiàn)O等待低。典型場景包括:頻繁的計算任務(wù)、加密解密、大量正則表達(dá)式處理、不當(dāng)?shù)难h(huán)結(jié)構(gòu)等。這類問題的表現(xiàn)是CPU使用率接近100%,但磁盤和網(wǎng)絡(luò)IO較低。
內(nèi)存密集型問題的特征是可用內(nèi)存持續(xù)下降,swap使用率上升。典型場景包括:內(nèi)存泄漏、應(yīng)用配置不當(dāng)(jvm heap過大)、緩存數(shù)據(jù)過大等。表現(xiàn)是free命令顯示可用內(nèi)存很少,si/so(swap in/out)數(shù)值較高。
IO密集型問題的特征是磁盤讀寫量巨大,IO等待時間長。典型場景包括:頻繁的日志寫入、大數(shù)據(jù)量的數(shù)據(jù)庫操作、不當(dāng)?shù)呐R時文件使用等。表現(xiàn)是iostat顯示高util%,CPU的wa(wait)值高。
網(wǎng)絡(luò)密集型問題的特征是網(wǎng)絡(luò)帶寬接近飽和或存在大量連接異常。典型場景包括:DDoS攻擊、爬蟲頻繁訪問、接口調(diào)用超時等。表現(xiàn)是網(wǎng)絡(luò)流量接近帶寬上限、大量連接處于TIME_WAIT狀態(tài)。
1.2 排查的基本順序
性能問題排查遵循"先整體后局部、先CPU后內(nèi)存、IO網(wǎng)絡(luò)配合看"的原則。
第一步,用top或uptime命令快速了解系統(tǒng)負(fù)載概況。系統(tǒng)負(fù)載(load average)如果超過CPU核心數(shù),說明存在資源爭搶。
第二步,用vmstat命令查看系統(tǒng)整體的CPU、內(nèi)存、IO、swap狀態(tài)。關(guān)注r(運行隊列長度)、b(阻塞進(jìn)程數(shù))、wa(IO等待)、si/so(swap換入換出)等指標(biāo)。
第三步,用iostat命令查看磁盤IO情況,確定是否存在IO瓶頸。
第四步,用free命令查看內(nèi)存使用情況,確認(rèn)是否存在內(nèi)存不足。
第五步,用netstat或ss命令查看網(wǎng)絡(luò)連接狀態(tài),確認(rèn)是否存在網(wǎng)絡(luò)問題。
第六步,確定瓶頸所在后,用top、ps等工具定位到具體進(jìn)程,進(jìn)行進(jìn)一步分析。
1.3 系統(tǒng)負(fù)載與CPU核心數(shù)的關(guān)系
理解系統(tǒng)負(fù)載(load average)與CPU核心數(shù)的關(guān)系,是判斷服務(wù)器是否"繁忙"的前提。
load average是Linux系統(tǒng)的重要指標(biāo),通過uptime命令或top命令的第一行可以看到:
uptime # 輸出:1612 up 45 days, 3:22, 2 users, load average: 2.85, 3.21, 4.10
load average的三個數(shù)字分別代表1分鐘、5分鐘、15分鐘的平均負(fù)載。理想情況下,load average應(yīng)該小于CPU核心數(shù)。如果load average長期高于CPU核心數(shù),說明系統(tǒng)處于高負(fù)載狀態(tài),新任務(wù)需要等待才能執(zhí)行。
假設(shè)服務(wù)器有8個CPU核心:
load average為2.85,說明平均有2.85個任務(wù)在等待CPU資源,系統(tǒng)比較輕松
load average為8,說明CPU資源剛好夠用,沒有等待
load average為12,說明有4個任務(wù)在等待CPU資源,系統(tǒng)繁忙
可以通過以下命令查看CPU核心數(shù):
nproc # 或者 grep"processor"/proc/cpuinfo | wc -l
1.4 關(guān)鍵性能指標(biāo)速覽
vmstat命令是性能排查中最常用的工具之一,它能在一屏之內(nèi)展示系統(tǒng)整體的CPU、內(nèi)存、IO、swap等關(guān)鍵指標(biāo):
vmstat 2 5
參數(shù)2表示每隔2秒采樣一次,共采樣5次。輸出示例:
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 2 0 0 2048000 123456 789012 0 0 50 100 500 1000 10 5 80 5 0
各列含義:
r:運行隊列中的進(jìn)程數(shù),表示等待CPU的進(jìn)程數(shù)
b:阻塞的進(jìn)程數(shù),表示等待IO或資源的進(jìn)程數(shù)
swpd:使用的swap空間大?。↘B)
free:可用內(nèi)存大?。↘B)
buff:用作緩沖的內(nèi)存大小(KB)
cache:用作緩存的內(nèi)存大?。↘B)
si:每秒從swap換入的內(nèi)存大?。↘B)
so:每秒換出到swap的內(nèi)存大?。↘B)
bi:每秒從塊設(shè)備接收的塊數(shù)(blocks/s)
bo:每秒發(fā)送到塊設(shè)備的塊數(shù)(blocks/s)
in:每秒中斷數(shù)
cs:每秒上下文切換次數(shù)
us:用戶空間CPU使用率
sy:內(nèi)核空間CPU使用率
id:空閑率
wa:等待IO的CPU時間百分比
st:被虛擬機偷走的CPU時間百分比
正常狀態(tài)參考:
r值應(yīng)小于CPU核心數(shù)的4倍
b值應(yīng)接近0
si/so應(yīng)接近0(持續(xù)不為0說明內(nèi)存不足)
id應(yīng)大于30%(如果持續(xù)低于30%說明CPU繁忙)
wa應(yīng)小于20%(如果高于20%說明IO存在瓶頸)
二、CPU性能排查
2.1 快速查看CPU狀態(tài)
top命令是排查CPU問題的首選工具,它能夠?qū)崟r顯示系統(tǒng)資源使用情況和進(jìn)程列表:
top
top界面的第一行是系統(tǒng)負(fù)載信息,第二行是任務(wù)(進(jìn)程)統(tǒng)計,第三行是CPU使用情況,第四五行是內(nèi)存使用情況,下方是進(jìn)程列表。
CPU區(qū)域的顯示含義:
%Cpu(s): 25.0 us, 5.0 sy, 0.0 ni, 68.0 id, 2.0 wa, 0.0 hi, 0.0 si, 0.0 st
us(user):用戶空間進(jìn)程消耗的CPU百分比
sy(system):內(nèi)核空間消耗的CPU百分比
ni(nice):優(yōu)先級調(diào)整過的用戶進(jìn)程消耗的CPU百分比
id(idle):空閑CPU百分比
wa(wait):等待IO的CPU百分比
hi(hardirq):處理硬件中斷消耗的CPU百分比
si(softirq):處理軟中斷消耗的CPU百分比
st(steal):被虛擬機偷走的CPU百分比
us高sy低:正常情況,說明用戶進(jìn)程在大量計算。
us高sy也高:需要檢查系統(tǒng)調(diào)用或上下文切換是否過多。
wa高:說明進(jìn)程在等待IO,可能是磁盤IO慢或網(wǎng)絡(luò)IO慢。
hi/si高:說明存在大量中斷或軟中斷,可能與網(wǎng)絡(luò)或存儲驅(qū)動有關(guān)。
2.2 定位CPU占用最高的進(jìn)程
在top界面中,按Shift+M按內(nèi)存排序,按Shift+P按CPU排序。按q退出。
查看CPU占用最高的進(jìn)程:
ps aux --sort=-%cpu | head -20
這條命令會列出CPU占用前20的進(jìn)程。輸出示例:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 12345 95.0 2.0 1234567 456789 ? R 10:00 950:00 myapp root 12346 3.2 1.0 234567 123456 ? S 10:00 120:00 java root 1 0.5 0.1 12345 6789 ? Ss Jan01 5:00 systemd
%CPU列是重點,如果某個進(jìn)程的CPU占用持續(xù)接近或超過100%(單核心),說明該進(jìn)程存在CPU密集型問題。
2.3 查看進(jìn)程線程
對于Java、Go等支持多線程的語言,一個進(jìn)程可能有多個線程。查看特定進(jìn)程的線程:
# 查看進(jìn)程的所有線程 ps -eLf | grep# 或使用top查看線程 top -H -p
top的-H參數(shù)顯示線程視圖,-p參數(shù)指定進(jìn)程ID。
2.4 分析CPU使用率高的常見原因
原因一:業(yè)務(wù)代碼存在無限循環(huán)或密集計算。這是最常見的原因,需要檢查業(yè)務(wù)代碼邏輯。
排查方法:使用strace跟蹤系統(tǒng)調(diào)用,確認(rèn)進(jìn)程在做什么:
strace -p-c
-c參數(shù)統(tǒng)計系統(tǒng)調(diào)用,按Ctrl+C結(jié)束。
原因二:GC(垃圾回收)頻繁。對于Java應(yīng)用,GC頻繁會導(dǎo)致CPU飆高。
排查方法:查看GC日志,確認(rèn)GC頻率和耗時:
jstat -gc1000 10
這條命令每1秒打印一次GC統(tǒng)計,共打印10次。
原因三:正則表達(dá)式回溯。大量使用正則表達(dá)式的應(yīng)用,如果正則寫的不當(dāng),可能導(dǎo)致災(zāi)難性回溯。
原因四:加密解密或壓縮解壓。這些操作本身就是CPU密集型的,需要確認(rèn)是否有必要。
2.5 高CPU問題的處理步驟
確認(rèn)是高CPU問題后,按以下步驟處理:
第一步,確認(rèn)是哪個進(jìn)程:
ps aux --sort=-%cpu | head -10
第二步,查看該進(jìn)程的詳細(xì)信息:
ps -ef | grep
第三步,查看進(jìn)程打開的文件和網(wǎng)絡(luò)連接:
lsof -p
第四步,如果是業(yè)務(wù)進(jìn)程,查看應(yīng)用日志:
# Java應(yīng)用 tail -f /var/log/myapp/application.log # Nginx tail -f /var/log/nginx/error.log
第五步,考慮處理措施:
如果是異常進(jìn)程(如被入侵),立即kill:
kill-9
如果是業(yè)務(wù)進(jìn)程存在bug,嘗試重啟或回滾
如果是配置不當(dāng),調(diào)整配置參數(shù)
如果是資源不足,考慮擴容
2.6 系統(tǒng)層面的CPU優(yōu)化
如果確認(rèn)是系統(tǒng)層面需要優(yōu)化,考慮以下方向:
調(diào)整進(jìn)程優(yōu)先級。使用nice和renice調(diào)整進(jìn)程優(yōu)先級:
# 啟動時設(shè)置優(yōu)先級 nice -n 10 /path/to/application # 調(diào)整運行中的進(jìn)程 renice -n 10 -p
nice值范圍是-20到19,值越低優(yōu)先級越高。
綁定CPU核心。使用taskset將進(jìn)程綁定到特定CPU核心,減少上下文切換:
# 綁定到CPU核心0-3 taskset -c 0-3 -p
三、內(nèi)存性能排查
3.1 快速查看內(nèi)存狀態(tài)
free命令是最常用的內(nèi)存查看工具:
free -h
輸出示例:
total used free shared buff/cache available
Mem: 31Gi 28Gi 1.5Gi 200Mi 1.5Gi 2.5Gi
Swap: 8Gi 0B 8Gi
各列含義:
total:總內(nèi)存
used:已使用內(nèi)存
free:完全未使用的內(nèi)存
shared:共享內(nèi)存(tmpfs)
buff/cache:緩沖和緩存(可以回收)
available:實際可用內(nèi)存(包括cache可回收部分)
重點關(guān)注available而不是free。Linux會使用空閑內(nèi)存作為緩存來提高性能,這些緩存可以在需要時釋放。所以看到free很低但available很高是正常現(xiàn)象。
3.2 內(nèi)存使用的詳細(xì)分析
查看內(nèi)存使用的詳細(xì)信息:
cat /proc/meminfo
輸出中關(guān)鍵指標(biāo):
MemTotal: 32768000 kB # 總內(nèi)存 MemFree: 1500000 kB # 完全空閑 MemAvailable: 2500000 kB # 可用內(nèi)存 Buffers: 123456 kB # 緩沖區(qū) Cached: 1500000 kB # 緩存 SwapCached: 0 kB # 交換到磁盤的緩存 Active(anon): 18000000 kB # 活躍匿名內(nèi)存 Inactive(anon): 2000000 kB # 不活躍匿名內(nèi)存 Active(file): 5000000 kB # 活躍文件內(nèi)存 Inactive(file): 3000000 kB # 不活躍文件內(nèi)存 SwapTotal: 8000000 kB # swap總大小 SwapFree: 8000000 kB # swap空閑
SwapUsed不為0且持續(xù)增長,說明存在內(nèi)存壓力,物理內(nèi)存不足。
3.3 查看進(jìn)程內(nèi)存占用
按內(nèi)存使用排序查看進(jìn)程:
ps aux --sort=-%mem | head -20
或者使用top按內(nèi)存排序(按Shift+M)。
3.4 分析內(nèi)存泄漏
內(nèi)存泄漏的典型特征是:進(jìn)程占用的內(nèi)存持續(xù)增長,不下降,即使在負(fù)載降低后也不釋放。
監(jiān)控進(jìn)程內(nèi)存使用變化:
# 每5秒檢查一次,共檢查20次
foriin{1..20};do
ps -o pid,rss,vsz,comm -p
sleep 5
done
或者使用pmap查看進(jìn)程的內(nèi)存映射:
pmap -x| sort -k3 -n -r | head -20
-x參數(shù)顯示擴展格式,| sort按第3列(Kbytes)排序。
3.5 內(nèi)存使用率高常見原因
原因一:應(yīng)用內(nèi)存泄漏。Java應(yīng)用最常見,典型表現(xiàn)是堆內(nèi)存持續(xù)增長直到OOM。
排查方法:分析堆內(nèi)存dump或GC日志。Java應(yīng)用可以查看JVM內(nèi)存使用:
jstat -gcjmap -heap
原因二:緩存數(shù)據(jù)過大。Nginx、Redis等應(yīng)用會使用大量內(nèi)存作為緩存。
排查方法:檢查應(yīng)用配置,確認(rèn)緩存大小限制。
原因三:JVM heap配置過大。如果JVM的heap配置超過了物理內(nèi)存的一半,可能影響系統(tǒng)穩(wěn)定性。
排查方法:檢查JVM參數(shù):
jcmdVM.flags
原因四:進(jìn)程數(shù)過多。大量進(jìn)程同時運行會消耗大量內(nèi)存。
排查方法:檢查進(jìn)程數(shù):
ps aux | wc -l
3.6 swap問題排查
swap使用率高(si/so持續(xù)不為0)是內(nèi)存不足的明確信號。
查看swap使用情況:
swapon -s free -h vmstat 2 5
如果發(fā)現(xiàn)swap使用率高,需要分析是物理內(nèi)存真的不足,還是存在內(nèi)存泄漏。
分析哪些進(jìn)程在使用swap:
forfin$(ls /proc/*/status 2>/dev/null);do
awk'/VmSwap/{print $2, $3, $4}'$f|whilereadsize unit name;do
if["${size%"*}"-gt 0 ];then
echo"$name$size$unit"
fi
done
done| sort -k2 -n -r | head -20
這個腳本會列出使用swap最多的前20個進(jìn)程。
3.7 內(nèi)存問題的處理步驟
第一步,確認(rèn)是否真的內(nèi)存不足:
free -h vmstat 2 5
如果available遠(yuǎn)大于used,說明內(nèi)存充足,不需要處理。
第二步,確認(rèn)是哪個進(jìn)程占用內(nèi)存最多:
ps aux --sort=-%mem | head -10
第三步,分析進(jìn)程類型:
系統(tǒng)進(jìn)程(kswapd、jbd2等)占用高,說明存在IO壓力
業(yè)務(wù)進(jìn)程占用高,分析應(yīng)用日志和配置
多個進(jìn)程占用都高,說明整體內(nèi)存配置不足
第四步,處理措施:
調(diào)整應(yīng)用內(nèi)存配置(如JVM heap大?。?/p>
清理不必要的進(jìn)程
增加物理內(nèi)存
優(yōu)化應(yīng)用內(nèi)存使用
四、磁盤IO排查
4.1 IO性能基礎(chǔ)概念
磁盤IO問題是生產(chǎn)環(huán)境中常見的性能瓶頸。理解幾個基本概念有助于后續(xù)排查:
IOPS(Input/Output Operations Per Second):每秒IO操作數(shù),衡量隨機讀寫能力。
吞吐量(Throughput):每秒數(shù)據(jù)傳輸量,衡量順序讀寫能力,單位通常是MB/s或GB/s。
延遲(Latency):單個IO操作的響應(yīng)時間,單位通常是毫秒。
利用率(Utilization):磁盤處理IO的時間占總時間的百分比,接近100%時說明磁盤飽和。
不同類型的存儲設(shè)備性能差異巨大:
HDD(機械硬盤):IOPS通常幾十到幾百,延遲毫秒級
NVMe SSD:IOPS可達(dá)幾十萬,延遲微秒級
4.2 iostat命令詳解
iostat是排查磁盤IO問題的核心工具,需要安裝sysstat包:
yum install sysstat # CentOS/RHEL apt-get install sysstat # Debian/Ubuntu
基本用法:
iostat -x 2 5
參數(shù)-x顯示擴展統(tǒng)計信息,每2秒采樣一次,共5次。
輸出示例:
Linux 5.4.0-xxx (hostname) 05/13/2026 _x86_64_ (8 CPU)
avg-cpu: %user %nice %system %iostat %idle
10.50 0.00 5.25 2.50 81.75
Device: r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz %util
sda 10.00 100.00 5120.00 51200.00 0.00 5.00 0.00 4.76 10.00 5.00 2.50 55.00
關(guān)鍵指標(biāo):
r/s、w/s:每秒讀寫次數(shù)
rkB/s、wkB/s:每秒讀寫數(shù)據(jù)量
await:平均IO等待時間(毫秒),包含排隊時間和實際處理時間
%util:設(shè)備利用率,接近100%說明設(shè)備飽和
aqu-sz:平均等待中的IO請求數(shù)
判斷IO瓶頸的標(biāo)準(zhǔn):
%util接近100%:設(shè)備飽和
await遠(yuǎn)高于正常值(HDD通常10-20ms,SSD<1ms)
avgqu-sz持續(xù)大于1(對于單盤)
4.3 查看具體進(jìn)程的IO使用
iotop命令可以查看每個進(jìn)程的IO使用情況,需要root權(quán)限:
yum install iotop # 安裝 iotop
iotop界面類似于top,按IO排序顯示進(jìn)程。
參數(shù)說明:
iotop -o # 只顯示有IO活動的進(jìn)程 iotop -p# 只顯示特定進(jìn)程 iotop -a # 累計顯示IO量
如果iotop不可用,可以使用pidstat:
pidstat -d 2 5
4.4 查看IO等待
CPU的wa(wait)值高,說明進(jìn)程在等待IO:
vmstat 2 5
結(jié)合iostat可以確認(rèn)是哪個設(shè)備導(dǎo)致的IO等待。
4.5 分析IO模式
確認(rèn)是IO問題后,需要分析是讀多還是寫多,是隨機IO還是順序IO。
查看每個磁盤的讀寫統(tǒng)計:
iostat -x 1 3
如果r/s高說明讀多,w/s高說明寫多。
查看具體文件系統(tǒng)的IO:
df -h
確認(rèn)是哪個掛載點的問題。
4.6 常見IO問題原因
原因一:日志寫入過多。應(yīng)用程序產(chǎn)生大量日志寫入。
排查方法:檢查/var/log目錄大?。?/p>
du -sh /var/log/*
原因二:數(shù)據(jù)庫IO壓力大。頻繁的數(shù)據(jù)庫讀寫操作。
排查方法:查看數(shù)據(jù)庫的慢查詢?nèi)罩尽?/p>
原因三:臨時文件操作頻繁。應(yīng)用在/tmp目錄頻繁讀寫。
排查方法:使用lsof查看進(jìn)程打開的文件。
原因四:swap操作。內(nèi)存不足導(dǎo)致頻繁換頁。
排查方法:結(jié)合內(nèi)存排查一起看。
4.7 IO問題的處理步驟
第一步,確認(rèn)是否是IO問題:
iostat -x 2 5
關(guān)注%util和await指標(biāo)。
第二步,如果是IO問題,確認(rèn)是讀還是寫導(dǎo)致的:
iostat -x 1 3
看r/s和w/s哪個更高。
第三步,定位到具體進(jìn)程:
iotop
第四步,分析是哪個文件或掛載點:
lsof -p
第五步,處理措施:
減少不必要的IO操作
優(yōu)化應(yīng)用IO模式(異步IO、合并寫操作)
使用更快的存儲設(shè)備
增加內(nèi)存減少swap使用
清理不必要的文件
五、網(wǎng)絡(luò)性能排查
5.1 快速查看網(wǎng)絡(luò)狀態(tài)
查看網(wǎng)絡(luò)連接統(tǒng)計:
netstat -s
或者使用ss命令(更現(xiàn)代,性能更好):
ss -s
查看活動連接:
ss -tan state established | head -20
5.2 網(wǎng)絡(luò)帶寬檢查
查看網(wǎng)卡流量:
cat /proc/net/dev
或者使用iftop(需要安裝):
iftop -i eth0
監(jiān)控特定端口的連接數(shù):
netstat -an | grep :80 | wc -l
5.3 連接狀態(tài)分析
分析TCP連接狀態(tài)分布:
netstat -an | awk'/^tcp/{print $NF}'| sort | uniq -c
或使用ss命令:
ss -tan state established | wc -l ss -tan state time-wait | wc -l ss -tan state syn-recv | wc -l
常見的異常狀態(tài):
大量TIME_WAIT:可能是頻繁建立和關(guān)閉連接
大量SYN_RECV:可能是SYN Flood攻擊
大量ESTABLISHED但沒有數(shù)據(jù)傳輸:可能是連接泄漏
5.4 網(wǎng)絡(luò)延遲排查
測試到目標(biāo)主機的延遲:
ping -c 10
測試DNS解析:
time nslookup example.com
測試TCP連接延遲:
telnet
5.5 網(wǎng)卡隊列和中斷
查看網(wǎng)卡中斷分布:
cat /proc/interrupts | grep eth
查看網(wǎng)卡隊列:
ethtool -l eth0
調(diào)整網(wǎng)卡隊列數(shù):
ethtool -L eth0 combined 8
5.6 網(wǎng)絡(luò)問題的處理步驟
第一步,確認(rèn)是否網(wǎng)絡(luò)問題:
ping -c 5 8.8.8.8 ping -c 5
如果內(nèi)網(wǎng)通但外網(wǎng)不通,可能是NAT或路由問題。
第二步,分析連接狀態(tài):
ss -tan state syn-recv | wc -l
如果SYN_RECV狀態(tài)連接很多,可能是SYN Flood攻擊。
第三步,檢查防火墻:
iptables -L -n iptables -L -n -t nat
第四步,處理措施:
DDoS攻擊:使用iptables限速或接入云防護(hù)
配置不當(dāng):修復(fù)防火墻規(guī)則或路由
帶寬不足:升級帶寬或優(yōu)化應(yīng)用
六、綜合排查案例
6.1 案例一:服務(wù)器負(fù)載高但CPU使用率不高
現(xiàn)象:uptime顯示load average很高,但top顯示CPU使用率不高。
分析:load average高但CPU空閑,說明進(jìn)程在等待IO或其他資源,而不是在計算。
排查步驟:
用vmstat查看:
vmstat 2 5
關(guān)注r列(運行隊列)和b列(阻塞進(jìn)程)。
用iostat查看IO:
iostat -x 2 5
看哪個磁盤的%util很高。
用iotop定位進(jìn)程:
iotop
看哪個進(jìn)程的IO最多。
根因:很可能是日志寫入或數(shù)據(jù)庫IO導(dǎo)致。
6.2 案例二:內(nèi)存持續(xù)增長
現(xiàn)象:free命令顯示內(nèi)存使用持續(xù)增長,但應(yīng)用日志沒有明顯異常。
分析:可能是內(nèi)存泄漏或緩存增長。
排查步驟:
查看進(jìn)程內(nèi)存占用:
ps aux --sort=-%mem | head -20
監(jiān)控特定進(jìn)程:
foriin{1..30};dops -o pid,rss,vsz -p ; sleep 10;done
檢查swap使用:
free -h vmstat 2 5
根因:可能是應(yīng)用內(nèi)存泄漏或JVM heap配置過大。
6.3 案例三:CPU使用率高但找不到高CPU進(jìn)程
現(xiàn)象:top顯示CPU使用率很高,但ps命令找不到占用CPU高的進(jìn)程。
分析:可能是系統(tǒng)調(diào)用或中斷導(dǎo)致的CPU消耗。
排查步驟:
查看系統(tǒng)CPU消耗:
top
看sy(系統(tǒng)調(diào)用)占比。
查看中斷:
cat /proc/interrupts
查看軟中斷:
cat /proc/softirqs
用strace分析進(jìn)程:
strace -p-c
根因:可能是大量系統(tǒng)調(diào)用、軟中斷或網(wǎng)絡(luò)中斷。
七、性能優(yōu)化建議
7.1 系統(tǒng)參數(shù)優(yōu)化
調(diào)整文件描述符限制。高并發(fā)服務(wù)需要調(diào)整文件描述符限制:
# 查看當(dāng)前限制 ulimit-n # 臨時調(diào)整 ulimit-n 65535 # 永久調(diào)整,編輯/etc/security/limits.conf * soft nofile 65535 * hard nofile 65535
調(diào)整內(nèi)核參數(shù)。編輯/etc/sysctl.conf:
# 增加tcp連接最大數(shù)量 net.ipv4.tcp_max_syn_backlog = 65535 # 調(diào)整socket緩沖區(qū)大小 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 # 調(diào)整TIME_WAIT復(fù)用 net.ipv4.tcp_tw_reuse = 1 # 調(diào)整文件描述符 fs.file-max = 65535
使配置生效:
sysctl -p
7.2 應(yīng)用配置優(yōu)化
JVM優(yōu)化。對于Java應(yīng)用,合理的JVM參數(shù)很重要:
-Xms4g -Xmx4g # 堆內(nèi)存大小 -XX:+UseG1GC # G1垃圾回收器 -XX:MaxGCPauseMillis=200 # 最大GC停頓時間
Nginx優(yōu)化:
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 65535;
use epoll;
}
7.3 監(jiān)控和告警
建立完善的監(jiān)控體系是預(yù)防性能問題的關(guān)鍵。
關(guān)鍵告警指標(biāo):
系統(tǒng)負(fù)載 > CPU核心數(shù) * 0.8
內(nèi)存使用率 > 85%
磁盤使用率 > 80%
CPU iowait > 20%
網(wǎng)絡(luò)連接數(shù)異常增長
建議使用Prometheus + Grafana或云監(jiān)控服務(wù)。
總結(jié)
Linux性能排查的核心是建立系統(tǒng)化的思路:
先整體后局部:先用vmstat、iostat等工具確認(rèn)問題類型,再定位具體進(jìn)程
先CPU后內(nèi)存、IO:CPU是最容易排查的,從它開始
多個指標(biāo)配合看:單一指標(biāo)可能誤導(dǎo),配合多個指標(biāo)分析
找到根因再處理:不要盲目殺進(jìn)程或重啟服務(wù),找到根因才能根本解決
常用命令速查:
# 系統(tǒng)整體狀態(tài)
uptime
vmstat 2 5
# CPU分析
top
ps aux --sort=-%cpu | head -10
# 內(nèi)存分析
free -h
ps aux --sort=-%mem | head -10
# IO分析
iostat -x 2 5
iotop
# 網(wǎng)絡(luò)分析
ss -s
netstat -an | awk'/^tcp/{print $NF}'| sort | uniq -c
# 進(jìn)程詳細(xì)分析
strace -p -c
lsof -p
pmap -x
性能優(yōu)化是一個持續(xù)的過程,需要在日常運維中不斷積累經(jīng)驗,建立完善的監(jiān)控體系,才能在問題發(fā)生前發(fā)現(xiàn)問題。
八、生產(chǎn)環(huán)境實戰(zhàn)案例
8.1 案例:Java應(yīng)用頻繁Full GC導(dǎo)致服務(wù)卡頓
背景:某電商平臺促銷活動期間,訂單接口響應(yīng)時間從正常200ms飆升至5-10秒,用戶投訴頁面加載緩慢。
排查過程:
初步診斷。登錄服務(wù)器,用top查看CPU使用率,發(fā)現(xiàn)并不高,但load average偏高:
uptime # 1612 up 45 days, 3:22, load average: 12.85, 10.21, 8.10 top # 發(fā)現(xiàn)多個Java進(jìn)程CPU使用率不高但運行時間很長
分析GC情況。用jstat查看GC統(tǒng)計:
jstat -gc 12345 1000 10 # 每秒打印一次Java進(jìn)程12345的GC統(tǒng)計
輸出顯示:FGC(Full GC)次數(shù)很多,每次Full GC耗時超過2秒。這是典型的GC過于頻繁導(dǎo)致的服務(wù)卡頓。
分析堆內(nèi)存。用jmap查看堆內(nèi)存使用:
jmap -heap 12345
輸出顯示:Heap配置了8GB,但老年代使用率持續(xù)在95%以上,說明內(nèi)存分配不合理或者存在內(nèi)存泄漏。
查看GC日志:
cat /var/log/myapp/gc.log | tail -100
GC日志顯示:對象創(chuàng)建速度遠(yuǎn)大于回收速度,導(dǎo)致頻繁Full GC。
根因:JVM heap配置過大(8GB),導(dǎo)致GC時掃描的內(nèi)存區(qū)域過大,單次GC停頓時間過長。同時應(yīng)用存在對象創(chuàng)建過多的問題。
修復(fù)方案:
降低JVM heap大小,從8GB降到4GB
啟用G1垃圾回收器,優(yōu)化GC參數(shù)
優(yōu)化應(yīng)用代碼,減少不必要的對象創(chuàng)建
修復(fù)后的JVM參數(shù):
-Xms4g -Xmx4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:G1HeapRegionSize=4m -XX:InitiatingHeapOccupancyPercent=45 -XX:G1ReservePercent=15
驗證修復(fù):
# 觀察GC情況
jstat -gc 12345 1000 10
# 檢查接口響應(yīng)時間
curl -o /dev/null -s -w"%{time_total}
"http://localhost:8080/api/orders
總結(jié):Java應(yīng)用性能問題,GC是常見的根因。關(guān)鍵是要監(jiān)控GC情況,分析GC日志,合理配置JVM參數(shù)。
8.2 案例:Nginx連接數(shù)暴漲導(dǎo)致服務(wù)不可用
背景:某網(wǎng)站突然無法訪問,Nginx返回502 Bad Gateway錯誤。
排查過程:
檢查Nginx狀態(tài):
systemctl status nginx # 顯示nginx is running netstat -an | grep :80 | wc -l # 連接數(shù)超過60000
分析連接狀態(tài):
netstat -an | awk'/^tcp/{print $6}'| sort | uniq -c | sort -rn
輸出顯示大量TIME_WAIT狀態(tài)連接,說明上游服務(wù)處理能力不足。
檢查上游PHP-FPM:
systemctl status php-fpm # 顯示php-fpm正常運行 netstat -an | grep 9000 | wc -l # 9000端口(PHP-FPM)連接數(shù)超過10000
檢查PHP-FPM進(jìn)程數(shù):
ps aux | grep php-fpm | wc -l # 只有50個worker進(jìn)程 cat /etc/php-fpm.d/www.conf | grep ^pm.max_children # pm.max_children = 50
根因:PHP-FPM的max_children設(shè)置為50,但連接數(shù)遠(yuǎn)超這個數(shù)字,導(dǎo)致請求排隊或被拒絕。
修復(fù)方案:
臨時增加PHP-FPM進(jìn)程數(shù):
# 編輯 /etc/php-fpm.d/www.conf pm.max_children = 200 pm.start_servers = 50 pm.min_spare_servers = 50 pm.max_spare_servers = 200 pm.max_requests = 500 # 重啟PHP-FPM systemctl restart php-fpm
調(diào)整Nginx超時配置:
proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s;
啟用TCP連接復(fù)用:
upstream backend {
server 127.0.0.1:9000;
keepalive 200;
}
優(yōu)化數(shù)據(jù)庫連接。檢查數(shù)據(jù)庫連接是否成為瓶頸,如果是,需要增加連接池大小或優(yōu)化查詢。
總結(jié):高并發(fā)場景下,PHP-FPM等上游服務(wù)的進(jìn)程數(shù)配置很重要。要結(jié)合服務(wù)器資源和業(yè)務(wù)特點合理配置。
8.3 案例:MySQL慢查詢導(dǎo)致網(wǎng)站響應(yīng)緩慢
背景:某論壇網(wǎng)站訪問速度變慢,首頁加載需要10秒以上。
排查過程:
檢查Web服務(wù)器:
top # CPU和內(nèi)存使用正常 netstat -an | grep :80 | wc -l # 連接數(shù)正常
檢查MySQL:
mysql -u root -p -e"SHOW PROCESSLISTG"| head -50
輸出顯示多個查詢運行時間超過30秒,最長的超過5分鐘。
查看慢查詢?nèi)罩荆?/p>
cat /var/log/mysql/slow-query.log | tail -50
發(fā)現(xiàn)多個未建索引的JOIN查詢,單表數(shù)據(jù)量超過千萬級別。
分析查詢計劃:
mysql -u root -p -e"EXPLAIN SELECT * FROM posts JOIN users ON posts.user_id = users.id WHERE posts.created_at > '2026-01-01'G"
輸出顯示:全表掃描,沒有使用索引。
根因:posts表缺少user_id和created_at的聯(lián)合索引,查詢時全表掃描。
修復(fù)方案:
添加索引(高風(fēng)險操作,需要謹(jǐn)慎):
-- 先備份 mysqldump -u root -p mydb posts > /backup/posts.sql -- 添加索引(注意:在大表上添加索引可能很慢,需要在業(yè)務(wù)低峰期執(zhí)行) ALTERTABLEpostsADDINDEXidx_user_created (user_id, created_at);
優(yōu)化查詢語句:
-- 避免SELECT * SELECTid, title, created_atFROMpostsWHEREuser_id =123;
配置慢查詢?nèi)罩咀詣臃治觯?/p>
# /etc/mysql/my.cnf slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow-query.log long_query_time = 2
驗證修復(fù):
mysql -u root -p -e"EXPLAIN SELECT * FROM posts WHERE user_id = 123 AND created_at > '2026-01-01'G" # 確認(rèn)使用了索引
總結(jié):數(shù)據(jù)庫查詢性能問題,首先要開啟慢查詢?nèi)罩?,定位慢查詢,然后分析?zhí)行計劃,添加合適的索引。
8.4 案例:服務(wù)器遭遇DDoS攻擊
背景:服務(wù)器網(wǎng)絡(luò)帶寬突然占滿,服務(wù)器無法遠(yuǎn)程訪問,網(wǎng)站完全無法訪問。
排查過程:
檢查帶寬:
cat /proc/net/dev | grep eth0 # 發(fā)現(xiàn)接收字節(jié)數(shù)異常高
分析連接:
netstat -an | awk'/^tcp/{print $5}'| cut -d: -f1 | sort | uniq -c | sort -rn | head -20
發(fā)現(xiàn)大量來自同一IP段的連接。
查看連接狀態(tài):
ss -tan state syn-recv | wc -l # 超過50000個SYN_RECV連接
根因:SYN Flood攻擊,攻擊者發(fā)送大量SYN包但不完成三次握手,耗盡服務(wù)器連接資源。
處理措施:
使用iptables臨時屏蔽攻擊IP:
# 屏蔽單個IP iptables -I INPUT -s 1.2.3.4 -j DROP # 屏蔽IP段 iptables -I INPUT -s 1.2.3.0/24 -j DROP
優(yōu)化內(nèi)核參數(shù)緩解SYN Flood:
# 編輯 /etc/sysctl.conf net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_max_syn_backlog = 65535 net.ipv4.tcp_syn_retries = 2 net.ipv4.tcp_synack_retries = 2 # 使配置生效 sysctl -p
使用fail2ban自動屏蔽:
yum install fail2ban -y # 配置fail2ban cat > /etc/fail2ban/jail.local <'EOF' [DEFAULT] bantime = 3600 findtime = 600 maxretry = 100 [ssh-iptables] enabled =?true filter = sshd action = iptables[name=SSH, port=ssh, protocol=tcp] logpath = /var/log/secure maxretry = 5 [nginx-http-auth] enabled =?true filter = nginx-http-auth action = iptables[name=nginx-auth, port=http, protocol=tcp] logpath = /var/log/nginx/error.log maxretry = 10 EOF systemctl?enable?fail2ban systemctl start fail2ban
接入云防護(hù)服務(wù)。如果是大規(guī)模DDoS攻擊,本地防護(hù)很難應(yīng)對,建議接入云服務(wù)商提供的DDoS防護(hù)服務(wù)。
總結(jié):DDoS攻擊是常見的網(wǎng)絡(luò)安全問題,需要建立多層防護(hù)機制。應(yīng)用層可以用iptables和fail2ban,基礎(chǔ)設(shè)施層建議使用云防護(hù)服務(wù)。
九、常用調(diào)優(yōu)參數(shù)匯總
9.1 系統(tǒng)內(nèi)核參數(shù)
編輯/etc/sysctl.conf,添加以下參數(shù):
# 網(wǎng)絡(luò)參數(shù) net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_keepalive_time = 1200 net.ipv4.ip_local_port_range = 1024 65535 net.ipv4.tcp_max_syn_backlog = 65535 net.ipv4.tcp_max_tw_buckets = 5000 net.core.somaxconn = 65535 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216 # 文件系統(tǒng)參數(shù) fs.file-max = 65535 fs.inotify.max_user_watches = 524288 # 內(nèi)存參數(shù) vm.swappiness = 10 vm.dirty_ratio = 60 vm.dirty_background_ratio = 5
使配置生效:
sysctl -p
9.2 limits.conf參數(shù)
編輯/etc/security/limits.conf:
* soft nofile 65535 * hard nofile 65535 * soft nproc 65535 * hard nproc 65535
9.3 常用監(jiān)控命令腳本
編寫一個簡單的性能監(jiān)控腳本:
#!/bin/bash # performance_monitor.sh LOG_FILE="/var/log/performance_$(date +%Y%m%d).log" echo"===$(date)===">>$LOG_FILE echo"=== System Load ===">>$LOG_FILE uptime >>$LOG_FILE echo"=== Memory Usage ===">>$LOG_FILE free -h >>$LOG_FILE echo"=== Top 10 CPU Processes ===">>$LOG_FILE ps aux --sort=-%cpu | head -11 >>$LOG_FILE echo"=== Top 10 Memory Processes ===">>$LOG_FILE ps aux --sort=-%mem | head -11 >>$LOG_FILE echo"=== Disk IO ===">>$LOG_FILE iostat -x 1 1 >>$LOG_FILE echo"=== Network Connections ===">>$LOG_FILE ss -s >>$LOG_FILE echo"=== Done ===">>$LOG_FILE
加入crontab定期執(zhí)行:
crontab -e # 每天早上9點執(zhí)行 0 9 * * * /bin/bash /opt/scripts/performance_monitor.sh
十、總結(jié)
Linux性能排查需要建立系統(tǒng)化的思維框架:
理解四大資源:CPU、內(nèi)存、磁盤IO、網(wǎng)絡(luò)是性能問題的四個主要方向
掌握核心工具:top、vmstat、iostat、ss、netstat是排查的瑞士軍刀
建立排查順序:先整體后局部,先CPU后內(nèi)存,IO網(wǎng)絡(luò)配合看
多指標(biāo)綜合分析:單一指標(biāo)可能誤導(dǎo),要配合多個指標(biāo)判斷
找到根因再處理:不要盲目重啟服務(wù),找到根本原因才能徹底解決
性能優(yōu)化是一個持續(xù)的過程,需要在實踐中不斷積累經(jīng)驗。推薦的做法:
建立完善的監(jiān)控體系,在問題發(fā)生前發(fā)現(xiàn)異常
定期巡檢,記錄性能基線,便于對比分析
重大變更前做性能測試,避免上線后才發(fā)現(xiàn)問題
保留性能問題排查記錄,形成知識沉淀
性能問題的排查和優(yōu)化沒有捷徑,只有多實踐、多總結(jié),才能在遇到問題時快速定位、妥善處理。
-
Linux
+關(guān)注
關(guān)注
88文章
11845瀏覽量
219706 -
服務(wù)器
+關(guān)注
關(guān)注
14文章
10413瀏覽量
91810 -
命令
+關(guān)注
關(guān)注
5文章
763瀏覽量
24060
原文標(biāo)題:一文吃透:Linux 服務(wù)器性能排查完整流程
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
Linux服務(wù)器性能排查完整流程
評論