# 平均負載
## 如何理解平均負載?--> 平均活躍進程數
* 可運行狀態:進程等待或者使用 CPU,ps 中的 R 狀態。
* 不可中斷狀態:正在等待 IO 訪問的進程,ps 中的 D 狀態,一般指在等待硬件資源。
> 比如,當一個進程向磁盤讀寫數據時,為了保證數據的一致性,在得到磁盤回復前,它是不能被其他進程或者中斷打斷的,這個時候的進程就處于不可中斷狀態。不可中斷狀態實際上是系統對進程和硬件設備的一種保護機制。
## 平均負載為多少時合理
經驗值是 70%,比較靠譜的做法是看監控趨勢。
## mpstat
是一個常用的多核 CPU 性能分析工具,用來實時查看每個 CPU 的性能指標,
以及所有 CPU 的平均指標。
```
# 顯示各個 CPU 的詳細信息
mpstat -P ALL 2 5
# 默認顯示所有 CPU 的聚合后的信息
mpstat 2 5
```
## pidstat
一個常用的進程性能分析工具,用來實時查看進程的 CPU、內存、I/O 以及
上下文切換等性能指標
```
# 顯示正在占用 CPU 的進程
pidstat -u 5 1
# -p 可以過濾某個進程
pidstat -u 5 1 -p <pid>
```
>mpstat 和 pidstat 在 sysstat 包中。
---
# CPU 使用率
## /proc/stat
```
$ cat /proc/stat | grep ^cpu
cpu 280580 7407 286084 172900810 83602 0 583 0 0 0
cpu0 144745 4181 176701 86423902 52076 0 301 0 0 0
cpu1 135834 3226 109383 86476907 31525 0 282 0 0 0
```
user(通常縮寫為 us),代表用戶態 CPU 時間。注意,它不包括下面的 nice 時間,但
包括了 guest 時間。
nice(通常縮寫為 ni),代表低優先級用戶態 CPU 時間,也就是進程的 nice 值被調整
為 1-19 之間時的 CPU 時間。這里注意,nice 可取值范圍是 -20 到 19,數值越大,優
先級反而越低。
system(通常縮寫為 sys),代表內核態 CPU 時間。
idle(通常縮寫為 id),代表空閑時間。注意,它不包括等待 I/O 的時間(iowait)。
iowait(通常縮寫為 wa),代表等待 I/O 的 CPU 時間。
irq(通常縮寫為 hi),代表處理硬中斷的 CPU 時間。
softirq(通常縮寫為 si),代表處理軟中斷的 CPU 時間。
steal(通常縮寫為 st),代表當系統運行在虛擬機中的時候,被其他虛擬機占用的
CPU 時間。
guest(通常縮寫為 guest),代表通過虛擬化運行其他操作系統的時間,也就是運行虛
擬機的 CPU 時間。
guest_nice(通常縮寫為 gnice),代表以低優先級運行虛擬機的時間。
> CPU 使用率,就是除了空閑時間外的其他時間占總 CPU 時間的百分比
> 比如,對比一下 top 和 ps 這兩個工具報告的 CPU 使用率,默認的結果很可能不一樣,因
為 top 默認使用 3 秒時間間隔,而 ps 使用的卻是進程的整個生命周期。
## perf
perf top perf record 和 perf report
```
# -g 顯示調用關系
perf top -g -p 1118
```
## 無法解釋的 CPU 使用率
碰到常規問題無法解釋的 CPU 使用率情況時,首先要想到有可能是短時應用導致的問題,
比如有可能是下面這兩種情況。
* 第一,應用里直接調用了其他二進制程序,這些程序通常運行時間比較短,通過 top 等
工具也不容易發現。
* 第二,應用本身在不停地崩潰重啟,而啟動過程的資源初始化,很可能會占用相當多的
CPU。
對于這類進程,我們可以用 pstree 或者 [execsnoop][1] 找到它們的父進程,再從父進程所在
的應用入手。
# 僵尸進程
# 軟中斷
事實上,為了解決中斷處理程序執行過長和中斷丟失的問題,Linux 將中斷處理過程分成了兩個階段,也就是上半部和下半部:
* 上半部用來快速處理中斷,它在中斷禁止模式下運行,主要處理跟硬件緊密相關的或時間敏感的工作。
* 下半部用來延遲處理上半部未完成的工作,通常以內核線程的方式運行。
## 取外賣
比如說前面取外賣的例子,上半部就是你接聽電話,告訴配送員你已經知道了,其他事兒見面再說,然后電話就可以掛斷了;下半部才是取外賣的動作,以及見面后商量發票處理的動作。這樣,第一個配送員不會占用你太多時間,當第二個配送員過來時,照樣能正常打通你的電話。
## 網卡接收數據包
除了取外賣,我再舉個最常見的網卡接收數據包的例子,讓你更好地理解。網卡接收到數據包后,會通過硬件中斷的方式,通知內核有新的數據到了。這時,內核就應該調用中斷處理程序來響應它。
對上半部來說,既然是快速處理,其實就是要把網卡的數據讀到內存中,然后更新一下硬件寄存器的狀態(表示數據已經讀好了),最后再發送一個軟中斷信號,通知下半部做進一步的處理。而下半部被軟中斷信號喚醒后,需要從內存中找到網絡數據,再按照網絡協議棧,對數據進行逐層解析和處理,直到把它送給應用程序。
所以,這兩個階段你也可以這樣理解:
* 上半部直接處理硬件請求,也就是我們常說的硬中斷,特點是快速執行;
* 而下半部則是由內核觸發,也就是我們常說的軟中斷,特點是延遲執行,異步執行上半部未完成的工作。
Linux 中的軟中斷包括網絡收發、定時、調度、RCU 鎖等各種類型,可以通過查看/proc/softirqs 來觀察軟中斷的運行情況。
## SYN FLOOD 導致大量軟中斷
``` bash
# -S 參數表示設置 TCP 協議的 SYN(同步序列號),-p 表示目的端口為 80
# -i u100 表示每隔 100 微秒發送一個網絡幀
# 注:如果你在實踐過程中現象不明顯,可以嘗試把 100 調小,比如調成 10 甚至 1
$ hping3 -S -p 80 -i u100 192.168.0.30
```
### 分析過程
系統變慢(ssh 連接,只是網絡較慢導致但覺比較慢,但是實際上系統不慢),通過 top 發現軟中斷很多,
SYN FLOOD 導致了大量軟中斷。
觀察到NET_RX軟中斷在不斷變化。
```bash
watch -d cat /proc/softirqs
CPU0 CPU1
HI: 0 0
TIMER: 1083906 2368646
NET_TX: 53 9
NET_RX: 1550643 1916776
BLOCK: 0 0
IRQ_POLL: 0 0
TASKLET: 333637 3930
SCHED: 963675 2293171
HRTIMER: 0 0
RCU: 1542111 1590625
```
sar -n DEV 后的結果計算后發現,每個網絡包都很小。
[1]:https://github.com/PoplarYang/perf-tools/blob/master/execsnoop
- 目錄
- 離散的內容
- IO模型
- 網卡綁定
- ssh
- 硬件測試
- 硬件
- limits
- 網絡流量
- 硬盤IO
- 硬盤
- tmux
- 主機名和域名
- http_proxy
- iptables
- 內核參數
- 塊設備和字符設備
- 內存
- 虛擬內存并非交換分區
- 網絡延時
- 概念
- 多核壓縮
- linux基礎
- SSH協議
- 軟件管理
- yum
- 制作本地源 yum系列
- 制作本地源 apt系列
- apt
- 在 Linux 中移除從源代碼安裝的程序的一種簡單的方法
- 其他
- 源碼編譯和二進制安裝后更改配置
- DNS
- bind
- 守護進程
- 特殊權限
- limit.conf配置
- 網絡
- shell-ok
- 變量ok
- 數組ok
- 系統變量和環境變量
- 運算符和計算-ok
- 條件測試-ok
- 選擇-ok
- shell循環-ok
- 輸出echo和printf-ok
- 技巧-ok
- pre-web
- http協議
- web服務器
- Apache
- apache安裝
- yum安裝
- 二進制安裝
- 編譯安裝
- httpd命令
- 運行 監控apache
- apache配置文件
- 常用配置
- MPM多處理模塊
- 編譯模塊
- apache模塊
- apache核心模塊
- apache標準模塊
- apache第三方模塊
- 虛擬主機
- 1
- CGI-FastCGI-SSI
- 別名和重定向
- apache應用
- 301重定向
- apache防盜鏈
- http轉化為https
- 訪問時間段控制
- 控制訪問目錄
- 限制指定USER_AGENT
- 不同客戶端訪問不同網頁
- apache黑名單
- httpd之禁止解析php
- 不記錄css/js/img的訪問日志
- 瀏覽器端靜態緩存
- apache訪問日志自動切割
- order-require
- 壓縮傳輸
- httpd-ssl
- apache代理
- 正向代理
- 反向代理
- apache調優
- httpd壓力測試工具ab
- CGI測試
- php
- php原理
- httpd和php的結合方式
- php yum安裝之DSO模式
- php 編譯安裝之DSO模式
- php-fpm詳解
- php yum安裝之php-fpm模式
- php 編譯安裝之FastCGI模式
- php擴展之mysql
- php擴展之gd
- php擴展之pcntl
- php擴展之xcache
- php擴展之ZendGuardLoader
- phpMyAdmin
- wordpress
- 數據庫-mysql
- 數據庫原理
- mysql數據庫原理
- mysql源碼編譯安裝
- mysql二進制包安裝
- mysql命令行工具
- 更改密碼
- 數據庫授權grant
- mysql日志
- 命令
- 常用
- 小命令大作為
- awk 報告生成器
- 網絡命令
- 命令查找
- 壓縮歸檔命令
- 文件管理
- 文件管理命令
- 文件查看命令
- 目錄管理命令
- 用戶管理命令
- 用戶權限管理
- curl
- cheat
- chrony
- command
- crontab任務計劃
- cut
- date
- dd
- df
- echo
- find
- grep
- hash
- iftop
- kill pkill killall
- ls
- lsmod和modprobe
- lsof
- man
- mkpasswd
- mount
- mtr
- netstat
- nmap
- nc
- NTP
- passwd
- rm
- rdate
- pv
- sar系統活動情況報告
- sed文本處理命令
- setup
- screen
- shutdown
- sort 命令
- sudo
- tcpdump
- top
- uniq
- wget
- who
- xargs
- 監控
- zabbix郵件報警
- Redis
- redis安裝
- redis數據類型和操作方法
- redis持久化和配置
- redis主從配置
- php連接redis
- redis實現session共享
- 安裝測試
- redis設置密碼
- ELK日志分析系統
- elasticsearch
- logstash
- logstash插件
- filebeat日志收集
- kibana
- jenkins
- jenkins安裝與配置
- 案例1
- 案例2
- 案例3
- 代碼倉庫之svn
- svn服務端配置
- 常用操作
- svn備份
- LB集群
- LVS負載均衡集群
- ipvsadm使用方法
- LVS調度方法
- NAT原理
- NAT實踐
- DR原理
- DR實踐
- TUN原理
- LVS持久連接
- HA集群
- HPC集群
- 共享存儲
- ftp協議
- vsftpd
- NFS
- 網站架構發展
- 文件同步
- rsync基本用法
- rsync安裝和使用_拉取模式
- lsyncd安裝和用法
- zabbix
- zabbix服務端安裝
- zabbix客戶端安裝
- zabbix編譯安裝
- zabbix監控tomcat
- zabbix監控mysql
- gitlab
- supervisor
- nsq
- ruby
- nodejs
- consul
- mesos
- zookeeper
- rwho
- 對象存儲
- 工具
- rclone
- minio
- linux 性能調優
- CPU
- 第一部分 CPU
- 安全