系統(tǒng)穩(wěn)定性分析

一、在線日志分析

日志中所包含的內(nèi)容如下圖:

日志中含有的內(nèi)容

常見定位問題的方法如下圖:

常見定位問題的方法

1. 日志分析常用命令

日志分析常用命令

2. 日志分析腳本

sed 編輯器
awk 命令

二、集群監(jiān)控

1. 監(jiān)控指標(biāo)

監(jiān)控指標(biāo)
1.1 load

系統(tǒng)的load被定義為特定時(shí)間間隔內(nèi)運(yùn)行隊(duì)列中的平均線程數(shù),如果一個(gè)線程滿足以下條件,該線程就會(huì)處于運(yùn)行隊(duì)列中:

  • 沒有處于I/O等待狀態(tài);
  • 沒有主動(dòng)進(jìn)入等待狀態(tài),也就是沒有調(diào)用wait操作;
  • 沒有被終止。
      每個(gè)CPU的核都維護(hù)了一個(gè)運(yùn)行隊(duì)列,系統(tǒng)的load主要由運(yùn)行隊(duì)列來決定。load的值越大,也就意味著系統(tǒng)的CPU越繁忙,這樣線程運(yùn)行完以后等待操作系統(tǒng)分配下一個(gè)時(shí)間片段的時(shí)間也就越長。一般來說,只要每個(gè)CPU當(dāng)前的活動(dòng)線程數(shù)不大于3,我們認(rèn)為它的負(fù)載是正常的,如果每個(gè)CPU的線程數(shù)大于5,則表示當(dāng)前系統(tǒng)的負(fù)載已經(jīng)非常高了,需要采取措施來減低系統(tǒng)的負(fù)載,以提高響應(yīng)速度。
      使用uptime命令查看系統(tǒng)的load:
[log@www ~]$ uptime
 08:44:47 up 260 days, 20:31,  1 user,  load average: 7.07, 6.13, 5.93

各個(gè)列的含義如下:

uptime 命令結(jié)果分析
1.2 CPU利用率

在 Linux 系統(tǒng)下,CPU 的時(shí)間消耗主要在這幾個(gè)方面,即用戶進(jìn)程、內(nèi)核進(jìn)程、中斷處理、I/O 等待、Nice 時(shí)間、丟失時(shí)間、空閑等幾個(gè)部分,而 CPU 的利用率則為這些時(shí)間所占總時(shí)間的百分比。通過 CPU 的利用率,能夠反映出CPU 的使用和消耗情況。
  可以通過top 命令來查看Linux系統(tǒng)的 CPU 消耗情況:

[log@www ~]$ top | grep Cpu
%Cpu(s):  5.4 us,  1.4 sy,  0.0 ni, 92.9 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
%Cpu(s):  4.5 us,  1.2 sy,  0.0 ni, 94.0 id,  0.0 wa,  0.0 hi,  0.2 si,  0.0 st
%Cpu(s):  3.8 us,  1.1 sy,  0.0 ni, 94.9 id,  0.0 wa,  0.0 hi,  0.2 si,  0.0 st

其中,CPU 后面跟的各個(gè)列便是各種狀態(tài)下 CPU所消耗的時(shí)間占比。

各個(gè)列的含義
1.3 磁盤剩余空間

通過df 命令,能夠看到磁盤的剩余空間。

[log@www ~]$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3        49G  3.1G   46G   7% /
devtmpfs         16G     0   16G   0% /dev
tmpfs            16G     0   16G   0% /dev/shm
tmpfs            16G  1.6G   15G  10% /run
tmpfs            16G     0   16G   0% /sys/fs/cgroup
/dev/sda2       494M  123M  372M  25% /boot
/dev/sda6       488G  206G  283G  43% /app
tmpfs           3.2G     0  3.2G   0% /run/user/1003
tmpfs           3.2G     0  3.2G   0% /run/user/0
tmpfs           3.2G     0  3.2G   0% /run/user/1000

-h 選項(xiàng)表示按單位格式化輸出。該命令顯示 sda3一共有49GB 的空間,3.1G 已用,剩余46GB 空間可用。
  如果需要查看具體目錄所占用的空間,分析大文件所處位置,可以使用 du 命令來進(jìn)行查看:

[log@www ~]$ du -d 1 -h /app
208G    /app/test
944K    /app/scripts
208G    /app

其中-d 參數(shù)用來指定遞歸深度,這里指定為1,表示只列出指定目錄的下一級(jí)目錄文件的大小,-h 選項(xiàng)用來進(jìn)行按文件大小單位的格式化輸出。

1.4 網(wǎng)絡(luò) traffic

通過 sar 命令,可以看到系統(tǒng)的網(wǎng)絡(luò)狀況:

[log@www ~]$ sar -n DEV 1 1 
Linux 3.10.0-327.el7.x86_64 (www.www)   10/23/2017      _x86_64_        (32 CPU)

08:21:22 AM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
08:21:23 AM      eth0  55716.00  55578.00  11306.84   9979.24      0.00      0.00      0.00
08:21:23 AM      eth1      0.00      0.00      0.00      0.00      0.00      0.00      0.00
08:21:23 AM      eth2      0.00      0.00      0.00      0.00      0.00      0.00      0.00
08:21:23 AM      eth3      0.00      0.00      0.00      0.00      0.00      0.00      0.00
08:21:23 AM        lo   4511.00   4511.00   1282.70   1282.70      0.00      0.00      0.00

Average:        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
Average:         eth0  55716.00  55578.00  11306.84   9979.24      0.00      0.00      0.00
Average:         eth1      0.00      0.00      0.00      0.00      0.00      0.00      0.00
Average:         eth2      0.00      0.00      0.00      0.00      0.00      0.00      0.00
Average:         eth3      0.00      0.00      0.00      0.00      0.00      0.00      0.00
Average:           lo   4511.00   4511.00   1282.70   1282.70      0.00      0.00      0.00

-n 選項(xiàng)表示匯報(bào)網(wǎng)絡(luò)狀況,而 DEV 則表示查看的是各個(gè)網(wǎng)卡的網(wǎng)絡(luò)流量,第一個(gè)1表示每1秒抽樣一次,第二個(gè)1表示總共取一次。輸出結(jié)果的含義如下:

sar 命令輸出結(jié)果分析
1.5 磁盤 I/O

查看系統(tǒng)的I/O 狀況:

[log@www ~]$ iostat -d -k
Linux 3.10.0-327.el7.x86_64 (www.www)   10/24/2017      _x86_64_        (32 CPU)

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda              17.12      1412.58      1728.90 32444667123 39710079394

使用iostat 工具能夠看到磁盤的I/O 情況,其中-d選項(xiàng)表示查看磁盤使用情況,-k 選項(xiàng)表示以 KB為單位顯示。輸出結(jié)果含義如下:

iostat 命令輸出結(jié)果分析
1.6 內(nèi)存使用

通過 free 命令可以查看內(nèi)存的使用情況,加上-m 參數(shù)表示以 MB 為單位:

[log@www ~]$ free -m
              total        used        free      shared  buff/cache   available
Mem:          31890       18587        3234         297       10068       12551
Swap:         19999        5767       14232

Linux 的內(nèi)存包括物理內(nèi)存Mem 和虛擬內(nèi)存swap,下面介紹下每一列的含義:

free 命令結(jié)果分析

對應(yīng)用來說,更值得關(guān)注的應(yīng)該是虛擬內(nèi)存swap 的消耗,swap 內(nèi)存使用的過多,表示物理內(nèi)存已經(jīng)不夠用了,操作系統(tǒng)將本應(yīng)該物理內(nèi)存存儲(chǔ)的一部分內(nèi)存頁調(diào)度到磁盤上,以騰出足夠的空間給當(dāng)前的進(jìn)程使用。當(dāng)其他進(jìn)程需要運(yùn)行時(shí),再從磁盤將內(nèi)存的頁調(diào)度到物理內(nèi)存當(dāng)中,以恢復(fù)進(jìn)程的運(yùn)行。而這個(gè)調(diào)度的過程,則會(huì)產(chǎn)生swap I/O,如果 swap I/O較為頻繁,將嚴(yán)重地影響系統(tǒng)性能。
  通過 vmstat命令,可以查看到swap I/O 的情況:

[log@www ~]$ vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
20  0 5905120 2246828      4 11370556    0    0    44    54    0    0  5  2 93  0  0

其中,swap 列的 si 表示每秒從磁盤交換到內(nèi)存的數(shù)據(jù)量,單位是KB/s,so 表示每秒從內(nèi)存交換到磁盤的數(shù)據(jù)量,單位也是KB/s。

1.7 qps

qps 是 query per second 的縮寫,即每秒查詢數(shù)。qps 在很大程度上代表了系統(tǒng)在業(yè)務(wù)上的繁忙程度,而每次請求的背后,可能對應(yīng)著多次磁盤I/O、多次網(wǎng)絡(luò)請求,以及多個(gè) CPU 時(shí)間片。
  通過關(guān)注系統(tǒng)的qps 數(shù),我們能夠非常直觀地了解到當(dāng)前系統(tǒng)業(yè)務(wù)情況,一旦當(dāng)前系統(tǒng)的 qps值超過所設(shè)置的預(yù)警閾值,即可考慮增加機(jī)器以對集群進(jìn)行擴(kuò)容,以免因壓力過大而導(dǎo)致宕機(jī)。集群預(yù)警閾值的設(shè)定,可以根據(jù)當(dāng)前壓測得出的值,綜合后期的運(yùn)維經(jīng)驗(yàn),評(píng)估一個(gè)較為合理的數(shù)值。

1.8 rt

rt 是response time 的縮寫,即請求的響應(yīng)時(shí)間。響應(yīng)時(shí)間是一個(gè)非常關(guān)鍵的指標(biāo),直接關(guān)系到前端的用戶體驗(yàn)。因此,任何開發(fā)人員和設(shè)計(jì)師都想盡可能地降低系統(tǒng)的rt 時(shí)間。對于Web 應(yīng)用來說,如果響應(yīng)太慢而導(dǎo)致用戶失去耐心,將損失大量的用戶。降低rt 時(shí)間需要從各個(gè)方面入手,找到應(yīng)用的瓶頸,對癥下藥。例如,通過部署 CDN 邊緣節(jié)點(diǎn)來縮短用戶請求的物理路徑;通過內(nèi)容壓縮來減少傳輸?shù)淖止?jié)數(shù);使用緩存來減少磁盤I/O和網(wǎng)絡(luò)請求等。
  而通過Apache或者Nginx的訪問日志,便能夠得知每個(gè)請求的響應(yīng)時(shí)間。以 Nginx 為例,在訪問日志的輸出格式中,增加$request_time的輸出,便能夠獲得響應(yīng)時(shí)間。
  CPU、內(nèi)存、網(wǎng)絡(luò)、磁盤、qps 和 rt。這些對于所有類型的應(yīng)用都需要關(guān)注,也有一些指標(biāo)只針對某一類型的應(yīng)用,如select/ps、update/ps、delete/ps只針對數(shù)據(jù)庫應(yīng)用,thread running只針對MySQL數(shù)據(jù)庫應(yīng)用,F(xiàn)ullGC只針對Java 應(yīng)用。

1.9 select/ps

select/ps記錄了數(shù)據(jù)庫每秒處理的 select語句的數(shù)量。對于 MySQL數(shù)據(jù)庫來說,如果select請求數(shù)量過多,則可以適當(dāng)?shù)卦黾幼x庫,以降低系統(tǒng)讀的壓力。

1.10 update/ps、delete/ps

update/ps 記錄了數(shù)據(jù)庫每秒處理 update語句的數(shù)量,相應(yīng)地,delete/ps則記錄了數(shù)據(jù)庫每秒處理 delete語句的數(shù)量。對于MySQL 數(shù)據(jù)庫來說,如果 update/delete這樣的寫入請求過多,單單增加讀的slave已經(jīng)解決不了問題,這時(shí)需要對響應(yīng)的庫進(jìn)行拆分,將請求分散到其它集群。

1.11 GC

可以對 JVM的一些內(nèi)存參數(shù)進(jìn)行調(diào)整和優(yōu)化,以降低 GC時(shí)應(yīng)用停止響應(yīng)的時(shí)間。如果一個(gè) Java 應(yīng)用頻繁地進(jìn)行Full GC,我們認(rèn)為它的性能是有問題的。

2. 心跳檢測

1、ping
2、應(yīng)用層檢測
3、業(yè)務(wù)檢測

3. 容量評(píng)估及應(yīng)用水位

三、流量控制

1. 流量控制實(shí)施

2. 服務(wù)穩(wěn)定性

1、依賴管理
2、優(yōu)雅降級(jí)
3、服務(wù)分級(jí)
4、開關(guān)
5、應(yīng)急預(yù)案

3. 高并發(fā)系統(tǒng)設(shè)計(jì)

1、操作原子性
2、多線程同步
3、數(shù)據(jù)一致性
4、系統(tǒng)可擴(kuò)展性
5、并發(fā)減庫存

四、性能優(yōu)化

1. 如何尋找性能瓶頸

1、前端優(yōu)化工具——YSlow
2、頁面響應(yīng)時(shí)間
3、方法響應(yīng)時(shí)間
4、GC 日志分析
5、數(shù)據(jù)庫查詢
6、系統(tǒng)資源使用

2. 性能測試工具

2.1 ab

ab 的全稱為 ApacheBench,用來對 HTTP 服務(wù)器進(jìn)行性能測試的小工具,可以模擬多個(gè)并發(fā)請求來對服務(wù)器進(jìn)行壓力測試,得出服務(wù)器在高負(fù)載下能夠支持的 qps 及應(yīng)用的響應(yīng)時(shí)間,為系統(tǒng)設(shè)計(jì)者提供參考依據(jù)。
  ab的使用:

ab [options] [http[s]://]hostname[:port]/path
常用參數(shù):
-n 總的請求數(shù);
-c 并發(fā)用戶數(shù)量。

假設(shè)并發(fā)數(shù)為5,一共執(zhí)行100次請求,目標(biāo)服務(wù)器為ab -n 100 -c 5 http://www.cnblogs.com,則對應(yīng)的命令為:
ab -n 100 -c 5 http://www.cnblogs.com/mongo/p/4910249.html

執(zhí)行后的結(jié)果如下:
Server Software:        
Server Hostname:        www.cnblogs.com
Server Port:            80

Document Path:          /mongo/p/4910249.html
Document Length:        15723 bytes

Concurrency Level:      5
Time taken for tests:   0.599 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      1605900 bytes
HTML transferred:       1572300 bytes
Requests per second:    167.03 [#/sec] (mean)
Time per request:       29.935 [ms] (mean)
Time per request:       5.987 [ms] (mean, across all concurrent requests)
Transfer rate:          2619.42 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        2    4   2.9      3      14
Processing:    13   25  31.3     16     231
Waiting:       11   16  10.4     14      77
Total:         15   29  31.6     20     234

Percentage of the requests served within a certain time (ms)
  50%     20
  66%     26
  75%     31
  80%     32
  90%     40
  95%     70
  98%    229
  99%    234
 100%    234 (longest request)

其中,幾個(gè)比較重要的指標(biāo)包括:

  • Requests per second為每秒處理的請求數(shù)量,即吞吐量;
  • Time per request 第一個(gè) Time per request 的值為每次并發(fā)所消耗的平均時(shí)間,即請求平均等待時(shí)間,第二個(gè)Time per request 的值為每次請求所消耗的平均時(shí)間;
  • Complete requests為完成的請求數(shù)量;
  • Failed requests為失敗的請求數(shù)量。
2.2 Apache JMeter

JMeter 的功能比 ab更為強(qiáng)大,采用純 Java 實(shí)現(xiàn),支持多種協(xié)議的性能基準(zhǔn)測試,如 HTTP、SOAP、FTP、TCP、SMTP、POP3等;可以用于模擬在服務(wù)器、網(wǎng)絡(luò)或者其他對象上施加高負(fù)載,以測試他們的壓力承受能力,或者分析他們在不同負(fù)載的情況下的性能表現(xiàn);能夠靈活地進(jìn)行插件化的擴(kuò)展;支持通過腳本方式的回歸測試,并且提供各項(xiàng)指標(biāo)的圖形化展示。

2.3 HP LoadRunner

LoadRunner 是一款功能極為強(qiáng)大的商業(yè)付費(fèi)性能測試工具,它通過模擬大量實(shí)際用戶的操作行為和實(shí)時(shí)性能檢測的方式,幫助用戶更加快速地查找和確認(rèn)問題。

2.4 反向代理引流

在分布式環(huán)境下,流量真正到達(dá)服務(wù)器之前,一般會(huì)經(jīng)過負(fù)載均衡設(shè)備進(jìn)行轉(zhuǎn)發(fā),通過修改負(fù)載均衡的策略,可以改變后端服務(wù)器所承受的壓力。在新版本發(fā)布之前,可以先對少部分機(jī)器進(jìn)行灰度發(fā)布,以驗(yàn)證程序的正確性和穩(wěn)定性,并且通過修改負(fù)載均衡策略,可以改變機(jī)器所承受的負(fù)載,達(dá)到對在線機(jī)器進(jìn)行性能基準(zhǔn)測試的目的。

2.5 TCPCopy

TCPCopy是一款請求復(fù)制工具,能夠?qū)⒃诰€請求復(fù)制到測試機(jī)器,模擬真實(shí)環(huán)境,達(dá)到程序在不上線的情況下承擔(dān)線上真實(shí)流量的效果。
  TCPCopy 分為TCPCopy Client 和 TCPCopy Server,其中TCPCopy Client運(yùn)行在真實(shí)環(huán)境的線上服務(wù)器之上,用來捕獲在線請求數(shù)據(jù)包,而TCPCopy Server則運(yùn)行在測試機(jī)上,用來捕獲響應(yīng)包,并將響應(yīng)包的頭部信息傳遞給TCPCopy Client,以完成 TCP 交互。

3. 性能優(yōu)化措施

3.1 前端性能優(yōu)化

(1)減少頁面的 HTTP 請求數(shù)量
(2)使用 CDN 網(wǎng)絡(luò)
(3)使用壓縮

3.2 Java 程序優(yōu)化

(1)單例
(2)Future 模式
  假設(shè)一個(gè)任務(wù) 執(zhí)行起來需要花費(fèi)一些時(shí)間,為了省去不必要的等待時(shí)間,可以先獲取一個(gè)“提貨單”,即 Future,然后繼續(xù)處理別的任務(wù),直到“貨物”到達(dá),即任務(wù)執(zhí)行完得到結(jié)果,此時(shí)便可以用“提貨單”進(jìn)行提貨,即通過Future 對象得到返回值。
  如下面的代碼所示,加載數(shù)據(jù)可能需要花費(fèi)一定的時(shí)間,此時(shí)可以先開始任務(wù),隨后處理其他事情,等其它事情都處理完后再取結(jié)果:

    static class Job<Object> implements Callable<Object> {

        @Override
        public Object call() throws Exception {
            return loadData();
        }
    }

    public static void main(String[] args) throws Exception {
        FutureTask futureTask = new FutureTask(new Job());
        new Thread(futureTask).start();

        // do something else

        Object result = (Object) futureTask.get();

    }

FutureTask 類實(shí)現(xiàn)了Future 和Runnable 接口,F(xiàn)utureTask開始后,loadData()執(zhí)行時(shí)間可能較長,因此可以先處理其他事情,等其它事情處理好后,再通過future.get()來獲取結(jié)果,如果loadData()還未執(zhí)行完畢,則此時(shí)線程會(huì)阻塞等待。

(3)線程池
(4)選擇就緒——NIO
(5)減少上下文切換
(6)降低鎖競爭

3.3 壓縮
3.4 結(jié)果緩存
3.5 數(shù)據(jù)庫查詢性能優(yōu)化

(1)合理使用索引
  MySQL 提供了explain 命令,用來解釋和分析SQL 查詢語句,通過explain 命令,可以模擬查詢優(yōu)化器來執(zhí)行 SQL 語句,從而知道 MySQL是如何執(zhí)行你的語句的。
  舉例來說,現(xiàn)有如下一張表,用來存放用戶的訂單信息:

create table order_info(
order_id int primary key auto_increment,
user_id int,
price int,
good_id int,
good_title varchar(100),
good_info varchar(500)
);

假設(shè)通過order_id(即表的主鍵)來進(jìn)行查詢,explain的結(jié)果是這樣的:

explain select * from order_info where order_id =1 ;
explain執(zhí)行結(jié)果

explain 詳細(xì)的解釋見:mysql explain執(zhí)行計(jì)劃詳解

(2)反范式設(shè)計(jì)
(3)使用查詢緩存
(4)使用搜索引擎
(5)使用key-value 數(shù)據(jù)庫

3.6 GC 優(yōu)化
3.7 硬件提升性能

五、Java 應(yīng)用故障的排查

1. 常用的工具

1、jps
2、jstat
3、jinfo
4、jstack
5、jmap
6、BTrace
7、JConsole
8、Memory Analyzer(MAT)
9、VisualVM

2. 典型案例分析

六、參考文獻(xiàn)

性能測試-ApacheBench
Jmeter使用入門
mysql explain執(zhí)行計(jì)劃詳解
大型分布式網(wǎng)站架構(gòu)設(shè)計(jì)與實(shí)踐——陳康賢著

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容