致使cpu負載增高的三個場景:php
1.cpu密集型進程node
2io密集型,等待io也會致使負載升高,可是cpu使用率不必定很高linux
3.大量等待cpu的進程調度ios
cpu寄存器:是cpu內置的容量小,速度極快的內存【保存程序運行時的一些數據】nginx
cpu計數器:用來保存cpu正在執行的指令位置或者即將執行的下一條指令位置redis
cpu上下文切換就是保存當前運行的cpu寄存器和計數器中的數據而後跳轉到新的程序計數器位置執行其餘進程算法
頻繁的上下文切換會提升cpu負載。數據庫
系統調用一般稱爲特權模式的切換,從ring0切換到ring3,雖然系統調用也會發生上下文切換可是和進程的上下文切換是不同的,進程上下文切換是一個進程切換到另外一個進程運行,而系統調用過程一直是同一個進程在運行apache
stress 系統壓測工具緩存
sysbench 多進程下數據庫性能測試工具,也能夠用來多線程壓測linux系統。
sysstat 系統檢測工具軟件包:能夠對cpu,內存,io等維度監控linux
mpstat:多核cpu檢測工具,實時查看每一個cpu性能指標
mpstat -P ALL 5 #每5秒檢測一次cpu並輸出
pidstat:進程性能分析工具,查看進程cpu,內存,io以及上下文切換等指標
pidstat -u 5 1 #每5秒輸出一次cpu檢測數據
hcache: 查看哪些應用佔用了多少系統的內存的cache
dstat: 同事查看cpu,disk io,net io
進程上下文切換分爲資源切換和非自願切換:
自願切換:進程沒法獲取所需資源,如io,內存等資源不足
非自願切換:因爲時間片已到被系統強制調度,大量進程爭奪cpu時容易發生非自願切換
查看方式:
pidstat -u -w 1 #-u 輸出進程切換指標,
cat cat /proc/interrupts
cpu上下文切換數百到一萬之內都算正常,若是超過一萬或者成數量級增加就極可能出現了cpu性能瓶頸
查看具體應用的哪一個函數引發的cpu負載高:
perf top -g -p 21515 #-g 開啓調用關係分析,-p 指定 php-fpm 的進程號...
節拍率 HZ 是內核的可配選項,能夠設置爲 100、250、1000 等。不一樣的系統可能設置不一樣數值,你能夠經過查詢 /boot/config 內核選項來查看它的配置值。好比在個人系統中,節拍率設置成了 250,也就是每秒鐘觸發 250 次時間中斷。
$ grep 'CONFIG_HZ=' /boot/config-$(uname -r)
cat /proc/stat | grep ^cpu #查看cpu使用統計信息
cat /proc/[pid]/stat | grep ^cpu #查看指定進程cpu使用統計信息
不一樣工具測出的cpu使用率可能不一致, 好比,對比一下 top 和 ps 這兩個工具報告的 CPU 使用率,默認的結果極可能不同,由於 top 默認使用 3 秒時間間隔,而 ps 使用的倒是進程的整個生命週期。
碰到常規問題沒法解釋的 CPU 使用率狀況時,首先要想到有多是短時應用致使的問題,好比有多是下面這兩種狀況:
1.應用裏直接調用了其餘二進制程序,這些程序一般運行時間比較短,經過 top 等工具也不容易發現
2.應用自己在不停地崩潰重啓,而啓動過程的資源初始化,極可能會佔用至關多的 CPU
對於這類進程,咱們能夠用 pstree 或者 execsnoop 找到它們的父進程,再從父進程所在的應用入手,排查問題的根源。
################################
strace -p PID #實時跟蹤進程的系統調用
當iowait過多到只cpu負載太高時【dstat 1 4 #能夠同時查看進程的io和cpu使用狀況】:
1.用top找出cpu利用率高的進程
2.pidstat -d -p <PID> 1 4 #查看指定進程的磁盤io狀況
iowait高不必定表明io有性能瓶頸,當系統中只有io進程運行時iowait也會高,但遠遠沒有達到io的性能瓶頸。
殭屍進程的問題相對容易排查,使用 pstree 找出父進程後,去查看父進程的代碼,檢查 wait() / waitpid() 的調用,檢查父進程是否遺漏了退出時子進程銷燬
################################
cpu中斷:
爲了解決中斷處理程序執行過長和中斷丟失的問題,Linux 將中斷處理過程分紅了兩個階段,也就是上半部分和下半部分
上半部用來快速處理中斷,它在中斷禁止模式下運行,主要處理跟硬件緊密相關的或時間敏感的工做。上半部直接處理硬件請求,也就是咱們常說的硬中斷,特色是快速執行;
下半部用來延遲處理上半部未完成的工做,一般之內核線程的方式運行,而下半部則是由內核觸發,也就是咱們常說的軟中斷,特色是延遲執行。
上半部會打斷 CPU 正在執行的任務,而後當即執行中斷處理程序。而下半部之內核線程的方式執行,而且每一個 CPU 都對應一個軟中斷內核線程,名字爲 「ksoftirqd/CPU 編號」,好比說, 0 號 CPU 對應的軟中斷內核線程的名字就是 ksoftirqd/0。
/proc/softirqs 提供了軟中斷的運行狀況;
/proc/interrupts 提供了硬中斷的運行狀況。
通常來講,ps 的輸出中,名字括在中括號裏的,通常都是內核線程。
軟中斷過致使cpu利用率高的解決思路:
從系統的軟中斷使用率高這個現象出發,經過觀察 /proc/softirqs 文件的變化狀況,判斷出軟中斷類型是網絡接收中斷
# -n DEV 表示顯示網絡收發的報告,間隔 1 秒輸出一組數據
sar -n DEV 1
tcpdump 抓包找出可疑發包ip
防火牆禁用ip
##########
當物理內存不足的時候,內存的回收機制:
1.回收緩存(文件頁),基於lru(最近最少使用原則)算法
2.回收匿名頁,swap機制
3.oom,殺死佔用大量內存的進程
OOM(OUT OF MEMORY):
echo -16 > /proc/$(pidof sshd)/oom_adj
oom_adj 的範圍是 [-17, 15],數值越大,表示進程越容易被 OOM 殺死;數值越小,表示進程越不容易被 OOM 殺死,其中 -17 表示禁止 OOM。
cachetop #查看進程緩存使用狀況
cachestat #查看系統緩存使用狀況
/pro/zoneinfo #查看內存狀況(page_min page_high page_low)
/proc/sys/vm/swappiness 選項,用來調整使用 Swap 的積極程度。swappiness 的範圍是 0-100,數值越大,越積極使用 Swap,也就是更傾向於回收匿名頁;數值越小,越消極使用 Swap,也就是更傾向於回收文件頁。
#建立基於文件的swap
# 建立 Swap 文件
$ fallocate -l 8G /mnt/swapfile
# 修改權限只有根用戶能夠訪問
$ chmod 600 /mnt/swapfile
# 配置 Swap 文件
$ mkswap /mnt/swapfile
# 開啓 Swap
$ swapon /mnt/swapfile
IO優化:
linux爲每一個文件都分配了兩個數據結構:
1.索引節點(inode)
2.目錄項(dentry,文件系統的目錄結構,是由內核維護的內存數據結構,一般成爲目錄項緩存)
內核使用slab機制管理目錄項和索引節點(inode),/proc/meminfo只給出了slab的總體大小,具體到每一種緩存,要查看/proc/slabinfo (
cat /proc/slabinfo | grep -E '^#|dentry|inode'
)
3.邏輯塊:是由連續磁盤扇區構成的最小讀寫單元,用來存儲文件數據
4.超級塊:用來記錄文件系統的總體狀態,如索引節點和邏輯塊的使用狀況。
目錄項是一個內存緩存,而超級塊/索引節點和邏輯塊是存儲在磁盤中的持久化數據。
iostat -d -x 1 . #查看磁盤io狀態(iops,util等)
pidstat -d 1 #查看進程磁盤使用狀況
iotop #根據io使用狀況排序
案例一:找出狂打日誌的應用程序:
1.top 命令查看進程資源利用率,發現iowait 高(初步確認是磁盤問題致使cpu利用率高)
2.pidstat -d 1 查看每一個進程的磁盤利用率(找出磁盤利用率高的進程)
3.strace -p 進程號 跟蹤系統調用,看到了write 調用,進程正在每秒300mb的速度寫文件
4.lsof -p 進程號 查看進程打開了哪些文件
這跟剛纔 strace 完咱們猜想的結果一致,看來這就是問題的根源:進程 18940 以每次 300MB 的速度,在「瘋狂」寫日誌,而日誌文件的路徑是 /tmp/logtest.txt。查看應用程序源碼發現應用程序的日誌級別爲info,因此會頻繁打日誌,將日誌級別改成warn後問題解決。
案例二:磁盤io延遲很高:
1.top命令查看資源利用率發現cpu的iowait 很高,內存充足
2.iostat -d -x 1 查看磁盤使用狀況,發現磁盤利用率達到98%
3.pistat -d 1 查看進程io的利用狀況
4.strace -p 進程號查看咱們第三部找到的io利用率高的進程,可是未發現write 系統調用
5.使用新工具 filetop(跟蹤內核的文件讀寫狀況,輸出線程id,讀寫大小及文件名稱)
6.利用ps命令找出第五步讀寫文件線程所屬的進程,發現就是咱們第四部找到的cpu利用率高的進程
7.用opensnoop 命令跟蹤內核中的open系統調用,能夠獲得打開文件的路徑(filetop只給出文件名稱,沒有路徑)
結論:結合前面的全部分析,咱們基本能夠判斷,案例應用會動態生成一批文件,用來臨時存儲數據,用完就會刪除它們。但不幸的是,正是這些文件讀寫,引起了 I/O 的性能瓶頸,致使整個處理過程很是慢,在項目中若是要臨時緩存一些數據最好基於內存方式,或者redis之類的,儘可能不要使用磁盤。
網絡調優:
nethogs #查看進程實時的網絡io
nethogs #查看網卡實時流量
iftop #查看主機實時流量(顯示源和目的地址)
網絡性能指標:帶寬,吞吐量,延時,pps
netstat -s 查看協議棧統計信息
sar -n DEV 1 查看傳輸網卡相關參數(利用率,pps,吞吐量等)
ethtool eth0 查看網卡狀態(speed 等)
網絡性能測試(帶寬,pps)
modprobe pktgen #加載模塊
測試腳本:
# 定義一個工具函數,方便後面配置各類測試選項
function pgset() {
local result
echo $1 > $PGDEV
result=`cat $PGDEV | fgrep "Result: OK:"`
if [ "$result" = "" ]; then
cat $PGDEV | fgrep Result:
fi
}
# 爲 0 號線程綁定 eth0 網卡
PGDEV=/proc/net/pktgen/kpktgend_0
pgset "rem_device_all" # 清空網卡綁定
pgset "add_device eth0" # 添加 eth0 網卡
# 配置 eth0 網卡的測試選項
PGDEV=/proc/net/pktgen/eth0
pgset "count 1000000" # 總髮包數量
pgset "delay 5000" # 不一樣包之間的發送延遲 (單位納秒)
pgset "clone_skb 0" # SKB 包複製
pgset "pkt_size 64" # 網絡包大小
pgset "dst 192.168.0.30" # 目的 IP
pgset "dst_mac 11:11:11:11:11:11" # 目的 MAC
# 啓動測試
PGDEV=/proc/net/pktgen/pgctrl
pgset "start"
測試tcp/udp性能(吞吐量):
iperf3:
安裝:
# Ubuntu
apt-get install iperf3
# CentOS
yum install iperf3
# -s 表示啓動服務端,-i 表示彙報間隔,-p 表示監聽端口
$ iperf3 -s -i 1 -p 10000
# -c 表示啓動客戶端,192.168.0.30 爲目標服務器的 IP
# -b 表示目標帶寬 (單位是 bits/s)
# -t 表示測試時間
# -P 表示併發數,-p 表示目標服務器監聽端口
$ iperf3 -c 192.168.0.30 -b 1G -t 15 -P 2 -p 10000
http性能測試:
安裝ab:
# Ubuntu
$ apt-get install -y apache2-utils
# CentOS
$ yum install -y httpd-tools
# -c 表示併發請求數爲 1000,-n 表示總的請求數爲 10000
$ ab -c 1000 -n 10000 http://192.168.0.30/
應用負載能力:
wrk
dns解析相關:
1.nslookup --debug www.baidu.com
2.dig:
@114.114.114.114 #指定nameserver
+trace #查看解析流程
-x #反向解析(根據ip解析出域名)
若是dns解析失敗,先用nslookup --debug 查看失敗緣由。配置dns服務器時能夠ping dns服務器,能夠根據ping的延遲選擇最穩定的服務器,也能夠dig 相關相關域名時查看所需查詢時間等綜合指標選擇最合適的dns服務器。
dns解析不穩定能夠增長dns緩存。最簡單的是安裝dnsmasq,而後將nameserver指向啓動dnsmasq 的服務器。
ping 命令默認會將ip反向解析爲域名(rtt)若是遇到ping命令很慢的狀況能夠加上選項-n(linux中)
防護DDOS:
怎樣確認爲ddos攻擊:
1.cpu 負載變高
2.sar -n DEV 1 發現pps劇增,但網絡實時流量很小(小包不少)
3.netstat -na 看到不少SYN_RECV狀態的鏈接
緩解方法:
1.抓到指定異常ip,而後加入iptables 拒絕
2.
# 限制 syn 併發數爲每秒 1 次
$ iptables -A INPUT -p tcp --syn -m limit --limit 1/s -j ACCEPT
# 限制單個 IP 在 60 秒新創建的鏈接數爲 10
$ iptables -I INPUT -p tcp --dport 80 --syn -m recent --name SYN_FLOOD --update --seconds 60 --hitcount 10 -j REJECT
3.增大半開鏈接數量:
sysctl -w net.ipv4.tcp_max_syn_backlog=1024
net.ipv4.tcp_max_syn_backlog = 1024
4.減小SYV_RECV失敗重試次數:
sysctl -w net.ipv4.tcp_synack_retries=1
net.ipv4.tcp_synack_retries = 1
Note:Nagle 算法與cork算法以及tcp延遲確認
####### 網卡丟包問題排查 ##########
問題:nginx 服務器訪問
1,hping3 -c 10 -S -p 80 192.168.0.30 #嘗試nginx 端口,測試端口及返回時間是否正常
2.netstat -i #查看網卡丟包記錄
3. tc -s qdisc show dev eth0 #查看是否有qos限制
4. netstat -s #查看協議收發彙總信息(重傳,鏈接失敗等信息)
5.sysctl net.netfilter.nf_conntrack_max #查看conntrack表信息
6.ulimit -n #查看系統文件打開數信息
7. iptables -Ln -v #查看是否有iptables 規則
8.tcpdump 抓包 #查看通訊過程是否正常
9.netstat -i #查看網卡mtu設置是否正常
note: curl 與 hping 區別,hping只發送syn,只鏈接不發送實際數據,curl命令即發送syn創建tcp鏈接又要發送http包(發送mtu 大小的包,因此有時候hping能成功,而curl沒法成功!)