20190422每周精品之編程

系統(tǒng)異常處理指南

摘抄來源:https://mp.weixin.qq.com/s/ClBBFYULE02ZB_43GkUHjQ?

1. 服務(wù)異常的處理流程

2. 負(fù)載

2.1 查看機(jī)器 cpu 的負(fù)載

top -b -n 1 |grep java|awk {print "VIRT:"$5,"RES:"$6,"cpu:"$9"%","mem:"$10"%"}


2.2 查找 cpu 占用率高的線程

top -p?25603?-Hprintf?0x%x?25842jstack?25603?|?grep?0x64f2cat?/proc/interrupts

(1)CPU(2)Memory(3)IO(4)Network

可以從以下幾個方面監(jiān)控CPU的信息:(1)中斷;(2)上下文切換;(3)可運(yùn)行隊(duì)列;(4)CPU 利用率。

3. 內(nèi)存

3.1 系統(tǒng)內(nèi)存

free 命令

[root@server ~]# freetotal used free shared buffers cachedMem:?3266180?3250000?10000?0?201000?3002000-/+ buffers/cache:?47000?3213000Swap:?2048276?80160?1968116

這里的默認(rèn)顯示單位是kb。

各項(xiàng)指標(biāo)解釋

[if !supportLists]·?[endif]

total:總計(jì)物理內(nèi)存的大小。

[if !supportLists]·?[endif]

[if !supportLists]·?[endif]

used:已使用多大。

[if !supportLists]·?[endif]

[if !supportLists]·?[endif]

free:可用有多少。

[if !supportLists]·?[endif]

[if !supportLists]·?[endif]

Shared:多個進(jìn)程共享的內(nèi)存總額。

[if !supportLists]·?[endif]

[if !supportLists]·?[endif]

buffers: 磁盤緩存的大小。

[if !supportLists]·?[endif]

[if !supportLists]·?[endif]

cache:磁盤緩存的大小。

[if !supportLists]·?[endif]

[if !supportLists]·?[endif]

-/+ buffers/cached): used:已使用多大,free:可用有多少。

[if !supportLists]·?[endif]

[if !supportLists]·?[endif]

已用內(nèi)存= 系統(tǒng)used memory - buffers - cached(47000 = 3250000-201000-3002000)

[if !supportLists]·?[endif]

[if !supportLists]·?[endif]

可用內(nèi)存= 系統(tǒng)free memory + buffers + cached(3213000 = 10000+201000+3002000)

[if !supportLists]·?[endif]

什么是buffer/cache?

[if !supportLists]§?[endif]

buffer 指 Linux 內(nèi)存的:Buffer cache,緩沖區(qū)緩

[if !supportLists]§?[endif]

[if !supportLists]§?[endif]

cache 指 Linux內(nèi)存中的:Page cache,頁面緩存

[if !supportLists]§?[endif]

page cache

page cache 主要用來作為文件系統(tǒng)上的文件數(shù)據(jù)的緩存來用,尤其是針對當(dāng)進(jìn)程對文件有 read/write 操作的時候。

如果你仔細(xì)想想的話,作為可以映射文件到內(nèi)存的系統(tǒng)調(diào)用:mmap是不是很自然的也應(yīng)該用到 page cache?在當(dāng)前的系統(tǒng)實(shí)現(xiàn)里,page cache 也被作為其它文件類型的緩存設(shè)備來用,所以事實(shí)上 page cache 也負(fù)責(zé)了大部分的塊設(shè)備文件的緩存工作。

buffer cache

buffer cache 主要用來在系統(tǒng)對塊設(shè)備進(jìn)行讀寫的時候,對塊進(jìn)行數(shù)據(jù)緩存的系統(tǒng)來使用。這意味著某些對塊的操作會使用 buffer cache 進(jìn)行緩存,比如我們在格式化文件系統(tǒng)的時候。

一般情況下兩個緩存系統(tǒng)是一起配合使用的,比如當(dāng)我們對一個文件進(jìn)行寫操作的時候,page cache 的內(nèi)容會被改變,而 buffer cache 則可以用來將 page 標(biāo)記為不同的緩沖區(qū),并記錄是哪一個緩沖區(qū)被修改了。這樣,內(nèi)核在后續(xù)執(zhí)行臟數(shù)據(jù)的回寫(writeback)時,就不用將整個 page 寫回,而只需要寫回修改的部分即可。

在當(dāng)前的內(nèi)核中,page cache 是針對內(nèi)存頁的緩存,說白了就是,如果有內(nèi)存是以page進(jìn)行分配管理的,都可以使用page cache作為其緩存來管理使用。

當(dāng)然,不是所有的內(nèi)存都是以頁(page)進(jìn)行管理的,也有很多是針對塊(block)進(jìn)行管理的,這部分內(nèi)存使用如果要用到 cache 功能,則都集中到 buffer cache中來使用。(從這個角度出發(fā),是不是buffer cache改名叫做block cache更好?)然而,也不是所有塊(block)都有固定長度,系統(tǒng)上塊的長度主要是根據(jù)所使用的塊設(shè)備決定的,而頁長度在X86 上無論是 32位還是 64位都是 4k。

3.2 進(jìn)程內(nèi)存

3.2.1 進(jìn)程內(nèi)存統(tǒng)計(jì)

/proc/[pid]/status通過/proc//status可以查看進(jìn)程的內(nèi)存使用情況,包括虛擬內(nèi)存大小(VmSize),物理內(nèi)存大?。╒mRSS),數(shù)據(jù)段大?。╒mData),棧的大?。╒mStk),代碼段的大?。╒mExe),共享庫的代碼段大小(VmLib)等等。

Name: gedit?/*進(jìn)程的程序名*/State: S (sleeping)?/*進(jìn)程的狀態(tài)信息,具體參見http://blog.chinaunix.net/u2/73528/showart_1106510.html*/Tgid:?9744?/*線程組號*/Pid:?9744?/*進(jìn)程pid*/PPid:?7672?/*父進(jìn)程的pid*/TracerPid:?0?/*跟蹤進(jìn)程的pid*/VmPeak:?60184?kB?/*進(jìn)程地址空間的大小*/VmSize:?60180?kB?/*進(jìn)程虛擬地址空間的大小reserved_vm:進(jìn)程在預(yù)留或特殊的內(nèi)存間的物理頁*/VmLck:?0?kB?/*進(jìn)程已經(jīng)鎖住的物理內(nèi)存的大小.鎖住的物理內(nèi)存不能交換到硬盤*/VmHWM:?18020?kB?/*文件內(nèi)存映射和匿名內(nèi)存映射的大小*/VmRSS:?18020?kB?/*應(yīng)用程序正在使用的物理內(nèi)存的大小,就是用ps命令的參數(shù)rss的值 (rss)*/VmData:?12240?kB?/*程序數(shù)據(jù)段的大?。ㄋ继摂M內(nèi)存的大?。?,存放初始化了的數(shù)據(jù)*/VmStk:?84?kB?/*進(jìn)程在用戶態(tài)的棧的大小*/VmExe:?576?kB?/*程序所擁有的可執(zhí)行虛擬內(nèi)存的大小,代碼段,不包括任務(wù)使用的庫 */VmLib:?21072?kB?/*被映像到任務(wù)的虛擬內(nèi)存空間的庫的大小*/VmPTE:?56?kB?/*該進(jìn)程的所有頁表的大小*/Threads:?1?/*共享使用該信號描述符的任務(wù)的個數(shù)*/

3.2.2 JVM 內(nèi)存分配

java內(nèi)存組成介紹:堆(Heap)和非堆(Non-heap)內(nèi)存

按照官方的說法:“Java 虛擬機(jī)具有一個堆,堆是運(yùn)行時數(shù)據(jù)區(qū)域,所有類實(shí)例和數(shù)組的內(nèi)存均從此處分配。堆是在 Java 虛擬機(jī)啟動時創(chuàng)建的?!?“在JVM中堆之外的內(nèi)存稱為非堆內(nèi)存(Non-heap memory)”。

可以看出JVM主要管理兩種類型的內(nèi)存:堆和非堆。

簡單來說堆就是Java代碼可及的內(nèi)存,是留給開發(fā)人員使用的;非堆就是JVM留給自己用的。

所以方法區(qū)、JVM內(nèi)部處理或優(yōu)化所需的內(nèi)存(如JIT編譯后的代碼緩存)、每個類結(jié)構(gòu)(如運(yùn)行時常數(shù)池、字段和方法數(shù)據(jù))以及方法和構(gòu)造方法 的代碼都在非堆內(nèi)存中。

[if !supportLists]1.?[endif]

JVM 本身需要的內(nèi)存,包括其加載的第三方庫以及這些庫分配的內(nèi)存

[if !supportLists]2.?[endif]

[if !supportLists]3.?[endif]

NIO 的 DirectBuffer 是分配的 native memory

[if !supportLists]4.?[endif]

[if !supportLists]5.?[endif]

內(nèi)存映射文件,包括JVM 加載的一些 JAR 和第三方庫,以及程序內(nèi)部用到的。上面 pmap 輸出的內(nèi)容里,有一些靜態(tài)文件所占用的大小不在 Java 的 heap 里,因此作為一個Web服務(wù)器,趕緊把靜態(tài)文件從這個Web服務(wù)器中人移開吧,放到nginx或者CDN里去吧。

[if !supportLists]6.?[endif]

[if !supportLists]7.?[endif]

JIT, JVM會將Class編譯成native代碼,這些內(nèi)存也不會少,如果使用了Spring的AOP,CGLIB會生成更多的類,JIT的內(nèi)存開銷也會隨之變大,而且Class本身JVM的GC會將其放到Perm Generation里去,很難被回收掉,面對這種情況,應(yīng)該讓JVM使用ConcurrentMarkSweep GC,并啟用這個GC的相關(guān)參數(shù)允許將不使用的class從Perm ?Generation中移除,?參數(shù)配置:

[if !supportLists]8.?[endif]

-XX:+UseConcMarkSweepGC -X:+CMSPermGenSweepingEnabled -X:+CMSClassUnloadingEnabled,如果不需要移除而Perm Generation空間不夠,可以加大一點(diǎn):-X:PermSize=256M -X:MaxPermSize=512M

[if !supportLists]9.?[endif]

[if !supportLists]10.?[endif]

JNI,一些JNI接口調(diào)用的native庫也會分配一些內(nèi)存,如果遇到JNI庫的內(nèi)存泄露,可以使用valgrind等內(nèi)存泄露工具來檢測

[if !supportLists]11.?[endif]

[if !supportLists]12.?[endif]

線程棧,每個線程都會有自己的??臻g,如果線程一多,這個的開銷就很明顯了

[if !supportLists]13.?[endif]

[if !supportLists]14.?[endif]

jmap/jstack 采樣,頻繁的采樣也會增加內(nèi)存占用,如果你有服務(wù)器健康監(jiān)控,記得這個頻率別太高,否則健康監(jiān)控變成致病監(jiān)控了。

[if !supportLists]15.?[endif]

1.方法區(qū)

也稱”永久代” 、“非堆”,它用于存儲虛擬機(jī)加載的類信息、常量、靜態(tài)變量、是各個線程共享的內(nèi)存區(qū)域。默認(rèn)最小值為 16 MB,最大值為 64 MB,可以通過-XX: PermSize 和 -XX: MaxPermSize 參數(shù)限制方法區(qū)的大小。

運(yùn)行時常量池:是方法區(qū)的一部分,Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項(xiàng)信息是常量池,用于存放編譯器生成的各種符號引用,這部分內(nèi)容將在類加載后放到方法區(qū)的運(yùn)行時常量池中。

2.虛擬機(jī)棧描述的是java 方法執(zhí)行的內(nèi)存模型:每個方法被執(zhí)行的時候 都會創(chuàng)建一個“棧幀”用于存儲局部變量表(包括參數(shù))、操作棧、方法出口等信息。

每個方法被調(diào)用到執(zhí)行完的過程,就對應(yīng)著一個棧幀在虛擬機(jī)棧中從入棧到出棧的過程。聲明周期與線程相同,是線程私有的。

局部變量表存放了編譯器可知的各種基本數(shù)據(jù)類型(boolean、byte、char、short、int、float、long、double)、對象引用(引用指針,并非對象本身),其中64位長度的long和double類型的數(shù)據(jù)會占用2個局部變量的空間,其余數(shù)據(jù)類型只占1個。

局部變量表所需的內(nèi)存空間在編譯期間完成分配,當(dāng)進(jìn)入一個方法時,這個方法需要在棧幀中分配多大的局部變量是完全確定的,在運(yùn)行期間棧幀不會改變局部變量表的大小空間。

3.本地方法棧與虛擬機(jī)?;绢愃疲瑓^(qū)別在于虛擬機(jī)棧為虛擬機(jī)執(zhí)行的java方法服務(wù),而本地方法棧則是為Native方法服務(wù)。

4.堆也叫做java 堆、GC堆是java虛擬機(jī)所管理的內(nèi)存中最大的一塊內(nèi)存區(qū)域,也是被各個線程共享的內(nèi)存區(qū)域,在JVM啟動時創(chuàng)建。

該內(nèi)存區(qū)域存放了對象實(shí)例及數(shù)組(所有 new 的對象)。其大小通過 -Xms (最小值) 和 -Xmx (最大值) 參數(shù)設(shè)置,-Xms為 JVM 啟動時申請的最小內(nèi)存,默認(rèn)為操作系統(tǒng)物理內(nèi)存的 1/64 但小于 1G;

-Xmx 為 JVM 可申請的最大內(nèi)存,默認(rèn)為物理內(nèi)存的1/4但小于 1G,默認(rèn)當(dāng)空余堆內(nèi)存小于 40% 時,JVM 會增大 Heap 到 -Xmx 指定的大小,可通過 -XX:MinHeapFreeRation= 來指定這個比列;

當(dāng)空余堆內(nèi)存大于70%時,JVM 會減小 heap 的大小到 -Xms 指定的大小,可通過XX:MaxHeapFreeRation= 來指定這個比列,對于運(yùn)行系統(tǒng),為避免在運(yùn)行時頻繁調(diào)整 Heap 的大小,通常 -Xms 與 -Xmx 的值設(shè)成一樣。

由于現(xiàn)在收集器都是采用分代收集算法,堆被劃分為新生代和老年代。新生代主要存儲新創(chuàng)建的對象和尚未進(jìn)入老年代的對象。老年代存儲經(jīng)過多次新生代GC(Minor GC)任然存活的對象。

5.程序計(jì)數(shù)器是最小的一塊內(nèi)存區(qū)域,它的作用是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器,在虛擬機(jī)的模型里,字節(jié)碼解釋器工作時就是通過改變這個計(jì)數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令,分支、循環(huán)、異常處理、線程恢復(fù)等基礎(chǔ)功能都需要依賴計(jì)數(shù)器完成。

3.2.3 直接內(nèi)存

直接內(nèi)存并不是虛擬機(jī)內(nèi)存的一部分,也不是Java虛擬機(jī)規(guī)范中定義的內(nèi)存區(qū)域。jdk1.4中新加入的NIO,引入了通道與緩沖區(qū)的IO方式,它可以調(diào)用Native方法直接分配堆外內(nèi)存,這個堆外內(nèi)存就是本機(jī)內(nèi)存,不會影響到堆內(nèi)存的大小。

3.2.4 JVM 內(nèi)存分析

查看JVM 堆內(nèi)存情況jmap -heap [pid]

[root@server ~]$ jmap -heap?837Attaching to process ID?837, please wait...Debugger attached successfully.Server compiler detected.JVM version is?24.71-b01using?thread-local object allocation.Parallel GC with?4?thread(s)//GC 方式Heap Configuration:?//堆內(nèi)存初始化配置MinHeapFreeRatio =?0?//對應(yīng)jvm啟動參數(shù)-XX:MinHeapFreeRatio設(shè)置JVM堆最小空閑比率(default 40)MaxHeapFreeRatio =?100?//對應(yīng)jvm啟動參數(shù) -XX:MaxHeapFreeRatio設(shè)置JVM堆最大空閑比率(default 70)MaxHeapSize =?2082471936?(1986.0MB)?//對應(yīng)jvm啟動參數(shù)-XX:MaxHeapSize=設(shè)置JVM堆的最大大小NewSize =?1310720?(1.25MB)//對應(yīng)jvm啟動參數(shù)-XX:NewSize=設(shè)置JVM堆的‘新生代’的默認(rèn)大小MaxNewSize =?17592186044415?MB//對應(yīng)jvm啟動參數(shù)-XX:MaxNewSize=設(shè)置JVM堆的‘新生代’的最大大小OldSize =?5439488?(5.1875MB)//對應(yīng)jvm啟動參數(shù)-XX:OldSize=<value>:設(shè)置JVM堆的‘老生代’的大小NewRatio =?2?//對應(yīng)jvm啟動參數(shù)-XX:NewRatio=:‘新生代’和‘老生代’的大小比率SurvivorRatio =?8?//對應(yīng)jvm啟動參數(shù)-XX:SurvivorRatio=設(shè)置年輕代中Eden區(qū)與Survivor區(qū)的大小比值PermSize =?21757952?(20.75MB)?//對應(yīng)jvm啟動參數(shù)-XX:PermSize=<value>:設(shè)置JVM堆的‘永生代’的初始大小MaxPermSize =?85983232?(82.0MB)//對應(yīng)jvm啟動參數(shù)-XX:MaxPermSize=<value>:設(shè)置JVM堆的‘永生代’的最大大小G1HeapRegionSize =?0?(0.0MB)Heap Usage://堆內(nèi)存使用情況PS Young GenerationEden Space://Eden區(qū)內(nèi)存分布capacity =?33030144?(31.5MB)//Eden區(qū)總?cè)萘?/i>used =?1524040?(1.4534378051757812MB)?//Eden區(qū)已使用free?=?31506104?(30.04656219482422MB)?//Eden區(qū)剩余容量4.614088270399305% used?//Eden區(qū)使用比率From Space:?//其中一個Survivor區(qū)的內(nèi)存分布capacity =?5242880?(5.0MB)used =?0?(0.0MB)free?=?5242880?(5.0MB)0.0% usedTo Space:?//另一個Survivor區(qū)的內(nèi)存分布capacity =?5242880?(5.0MB)used =?0?(0.0MB)free?=?5242880?(5.0MB)0.0% usedPS Old Generation?//當(dāng)前的Old區(qū)內(nèi)存分布capacity =?86507520?(82.5MB)used =?0?(0.0MB)free?=?86507520?(82.5MB)0.0% usedPS Perm Generation//當(dāng)前的 “永生代” 內(nèi)存分布capacity =?22020096?(21.0MB)used =?2496528?(2.3808746337890625MB)free?=?19523568?(18.619125366210938MB)11.337498256138392% used670?interned Strings occupying?43720?bytes.

關(guān)于這里的幾個generation網(wǎng)上資料一大把就不細(xì)說了,這里算一下求和可以得知前者總共給Java環(huán)境分配了644M的內(nèi)存,而ps輸出的VSZ和RSS分別是7.4G和2.9G,這到底是怎么回事呢?

前面jmap輸出的內(nèi)容里,MaxHeapSize 是在命令行上配的,-Xmx4096m,這個java程序可以用到的最大堆內(nèi)存。

VSZ是指已分配的線性空間大小,這個大小通常并不等于程序?qū)嶋H用到的內(nèi)存大小,產(chǎn)生這個的可能性很多,比如內(nèi)存映射,共享的動態(tài)庫,或者向系統(tǒng)申請了更多的堆,都會擴(kuò)展線性空間大小,要查看一個進(jìn)程有哪些內(nèi)存映射,可以使用 pmap 命令來查看:

pmap -x [pid]

[root@server ~]$ pmap -x 837837: javaAddress Kbytes RSS Dirty Mode Mapping0000000040000000 36 4 0 r-x-- java0000000040108000 8 8 8 rwx-- java00000000418c9000 13676 13676 13676 rwx-- [ anon ]00000006fae00000 83968 83968 83968 rwx-- [ anon ]0000000700000000 527168 451636 451636 rwx-- [ anon ]00000007202d0000 127040 0 0?----- [ anon ]......00007f55ee124000 4 4 0 r-xs- az.png00007fff017ff000 4 4 0 r-x-- [ anon ]ffffffffff600000 4 0 0 r-x-- [ anon ]---------------- ------ ------ ------total kB 7796020 3037264 3023928

這里可以看到很多anon,這些表示這塊內(nèi)存是由mmap分配的。

RSZ是Resident Set Size,常駐內(nèi)存大小,即進(jìn)程實(shí)際占用的物理內(nèi)存大小, 在現(xiàn)在這個例子當(dāng)中,RSZ和實(shí)際堆內(nèi)存占用差了2.3G,這2.3G的內(nèi)存組成分別為:

查看JVM 堆各個分區(qū)的內(nèi)存情況

jstat -gcutil [pid]

[root@server ~]$ jstat -gcutil?837?1000?20S0?S1 E O P YGC YGCT FGC FGCT GCT0.00?80.43?24.62?87.44?98.29?7101?119.652?40?19.719?139.3710.00?80.43?33.14?87.44?98.29?7101?119.652?40?19.719?139.371

分析JVM 堆內(nèi)存中的對象查看存活的對象統(tǒng)計(jì)jmap -histo:live [pid]

dump 內(nèi)存jmap -dump:format=b,file=heapDump [pid]

然后用jhat命令可以參看jhat -port 5000 heapDump在瀏覽器中訪問:http://localhost:5000/ 查看詳細(xì)信息

4. 服務(wù)指標(biāo)

4.1 響應(yīng)時間(RT)

響應(yīng)時間是指系統(tǒng)對請求作出響應(yīng)的時間。直觀上看,這個指標(biāo)與人對軟件性能的主觀感受是非常一致的,因?yàn)樗暾赜涗浟苏麄€計(jì)算機(jī)系統(tǒng)處理請求的時間。

由于一個系統(tǒng)通常會提供許多功能,而不同功能的處理邏輯也千差萬別,因而不同功能的響應(yīng)時間也不盡相同,甚至同一功能在不同輸入數(shù)據(jù)的情況下響應(yīng)時間也不相同。

所以,在討論一個系統(tǒng)的響應(yīng)時間時,人們通常是指該系統(tǒng)所有功能的平均時間或者所有功能的最大響應(yīng)時間。

當(dāng)然,往往也需要對每個或每組功能討論其平均響應(yīng)時間和最大響應(yīng)時間。

對于單機(jī)的沒有并發(fā)操作的應(yīng)用系統(tǒng)而言,人們普遍認(rèn)為響應(yīng)時間是一個合理且準(zhǔn)確的性能指標(biāo)。需要指出的是,響應(yīng)時間的絕對值并不能直接反映軟件的性能的高低,軟件性能的高低實(shí)際上取決于用戶對該響應(yīng)時間的接受程度。

對于一個游戲軟件來說,響應(yīng)時間小于100毫秒應(yīng)該是不錯的,響應(yīng)時間在1秒左右可能屬于勉強(qiáng)可以接受,如果響應(yīng)時間達(dá)到3秒就完全難以接受了。

而對于編譯系統(tǒng)來說,完整編譯一個較大規(guī)模軟件的源代碼可能需要幾十分鐘甚至更長時間,但這些響應(yīng)時間對于用戶來說都是可以接受的。

4.2 吞吐量(Throughput)

吞吐量是指系統(tǒng)在單位時間內(nèi)處理請求的數(shù)量。對于無并發(fā)的應(yīng)用系統(tǒng)而言,吞吐量與響應(yīng)時間成嚴(yán)格的反比關(guān)系,實(shí)際上此時吞吐量就是響應(yīng)時間的倒數(shù)。

前面已經(jīng)說過,對于單用戶的系統(tǒng),響應(yīng)時間(或者系統(tǒng)響應(yīng)時間和應(yīng)用延遲時間)可以很好地度量系統(tǒng)的性能,但對于并發(fā)系統(tǒng),通常需要用吞吐量作為性能指標(biāo)。

對于一個多用戶的系統(tǒng),如果只有一個用戶使用時系統(tǒng)的平均響應(yīng)時間是t,當(dāng)有你n個用戶使用時,每個用戶看到的響應(yīng)時間通常并不是n×t,而往往比n×t小很多(當(dāng)然,在某些特殊情況下也可能比n×t大,甚至大很多)。

這是因?yàn)樘幚砻總€請求需要用到很多資源,由于每個請求的處理過程中有許多不走難以并發(fā)執(zhí)行,這導(dǎo)致在具體的一個時間點(diǎn),所占資源往往并不多。也就是說在處理單個請求時,在每個時間點(diǎn)都可能有許多資源被閑置,當(dāng)處理多個請求時,如果資源配置合理,每個用戶看到的平均響應(yīng)時間并不隨用戶數(shù)的增加而線性增加。

實(shí)際上,不同系統(tǒng)的平均響應(yīng)時間隨用戶數(shù)增加而增長的速度也不大相同,這也是采用吞吐量來度量并發(fā)系統(tǒng)的性能的主要原因。

一般而言,吞吐量是一個比較通用的指標(biāo),兩個具有不同用戶數(shù)和用戶使用模式的系統(tǒng),如果其最大吞吐量基本一致,則可以判斷兩個系統(tǒng)的處理能力基本一致。

4.3 并發(fā)用戶數(shù)

并發(fā)用戶數(shù)是指系統(tǒng)可以同時承載的正常使用系統(tǒng)功能的用戶的數(shù)量。與吞吐量相比,并發(fā)用戶數(shù)是一個更直觀但也更籠統(tǒng)的性能指標(biāo)。

實(shí)際上,并發(fā)用戶數(shù)是一個非常不準(zhǔn)確的指標(biāo),因?yàn)橛脩舨煌氖褂媚J綍?dǎo)致不同用戶在單位時間發(fā)出不同數(shù)量的請求。

一網(wǎng)站系統(tǒng)為例,假設(shè)用戶只有注冊后才能使用,但注冊用戶并不是每時每刻都在使用該網(wǎng)站,因此具體一個時刻只有部分注冊用戶同時在線,在線用戶就在瀏覽網(wǎng)站時會花很多時間閱讀網(wǎng)站上的信息,因而具體一個時刻只有部分在線用戶同時向系統(tǒng)發(fā)出請求。

這樣,對于網(wǎng)站系統(tǒng)我們會有三個關(guān)于用戶數(shù)的統(tǒng)計(jì)數(shù)字:注冊用戶數(shù)、在線用戶數(shù)和同時發(fā)請求用戶數(shù)。由于注冊用戶可能長時間不登陸網(wǎng)站,使用注冊用戶數(shù)作為性能指標(biāo)會造成很大的誤差。而在線用戶數(shù)和同事發(fā)請求用戶數(shù)都可以作為性能指標(biāo)。

相比而言,以在線用戶作為性能指標(biāo)更直觀些,而以同時發(fā)請求用戶數(shù)作為性能指標(biāo)更準(zhǔn)確些。

4.4 QPS每秒查詢率(Query Per Second)

每秒查詢率QPS是對一個特定的查詢服務(wù)器在規(guī)定時間內(nèi)所處理流量多少的衡量標(biāo)準(zhǔn),在因特網(wǎng)上,作為域名系統(tǒng)服務(wù)器的機(jī)器的性能經(jīng)常用每秒查詢率來衡量。對應(yīng)fetches/sec,即每秒的響應(yīng)請求數(shù),也即是最大吞吐能力。

從以上概念來看吞吐量和響應(yīng)時間是衡量系統(tǒng)性能的重要指標(biāo),QPS雖然和吞吐量的計(jì)量單位不同,但應(yīng)該是成正比的,任何一個指標(biāo)都可以含量服務(wù)器的并行處理能力。當(dāng)然Throughput更關(guān)心數(shù)據(jù)量,QPS更關(guān)心處理筆數(shù)。

4.5 CPU利用率

CPU Load Average < CPU個數(shù) 核數(shù) 0.7

Context Switch Rate就是Process(Thread)的切換,如果切換過多,會讓CPU忙于切換,也會導(dǎo)致影響吞吐量。

《高性能服務(wù)器架構(gòu)》這篇文章的第2節(jié)就是說的是這個問題的。

究竟多少算合適?google 了一大圈,沒有一個確切的解釋。

Context Switch大體上由兩個部分組成:中斷和進(jìn)程(包括線程)切換,一次中斷(Interrupt)會引起一次切換,進(jìn)程(線程)的創(chuàng)建、激活之類的也會引起一次切換。CS的值也和TPS(Transaction Per Second)相關(guān)的,假設(shè)每次調(diào)用會引起N次CS,那么就可以得出

Context Switch Rate = Interrupt Rate + TPS* N

CSR減掉IR,就是進(jìn)程/線程的切換,假如主進(jìn)程收到請求交給線程處理,線程處理完畢歸還給主進(jìn)程,這里就是2次切換。

也可以用CSR、IR、TPS的值代入公式中,得出每次事物導(dǎo)致的切換數(shù)。因此,要降低CSR,就必須在每個TPS引起的切換上下功夫,只有N這個值降下去,CSR就能降低,理想情況下N=0,但是無論如何如果N >= 4,則要好好檢查檢查。另外網(wǎng)上說的CSR<5000,我認(rèn)為標(biāo)準(zhǔn)不該如此單一。

這三個指標(biāo)在LoadRunner 中可以監(jiān)控到;另外,在 linux 中,也可以用 vmstat 查看r(Load Arerage),in(Interrupt)和cs(Context Switch)

5. 工具

uptime

dmesg

top查看進(jìn)程活動狀態(tài)以及一些系統(tǒng)狀況

vmstat查看系統(tǒng)狀態(tài)、硬件和系統(tǒng)信息等

iostat查看CPU 負(fù)載,硬盤狀況

sar綜合工具,查看系統(tǒng)狀況

mpstat查看多處理器狀況

netstat查看網(wǎng)絡(luò)狀況

iptraf實(shí)時網(wǎng)絡(luò)狀況監(jiān)測

tcpdump抓取網(wǎng)絡(luò)數(shù)據(jù)包,詳細(xì)分析

mpstat查看多處理器狀況

tcptrace數(shù)據(jù)包分析工具

netperf網(wǎng)絡(luò)帶寬工具

dstat綜合工具,綜合了vmstat, iostat, ifstat, netstat 等多個信息

Reference

[if !supportLists]·?[endif]

http://tmq.qq.com/2016/07/it-is-necessary-to-know-the-background-performance-test/https://www.ibm.com/developerworks/java/library/j-nativememory-linux/http://www.oracle.com/technetwork/java/javase/index-137495.htmlhttp://www.hollischuang.com/archives/303

[if !supportLists]·?[endif]

轉(zhuǎn)載自Zane Blog,原文為《服務(wù)調(diào)優(yōu)》



"W?>???|

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML標(biāo)準(zhǔn)。 注意:講述HT...
    kismetajun閱讀 28,867評論 1 45
  • Python語言特性 1 Python的函數(shù)參數(shù)傳遞 看兩個如下例子,分析運(yùn)行結(jié)果: 代碼一: a = 1 def...
    時光清淺03閱讀 571評論 0 0
  • Java基礎(chǔ)面試 Java基礎(chǔ)面試... 1 1. Java基礎(chǔ)知識... 5 1.1. Java源程序的擴(kuò)展名是...
    來著何人閱讀 1,292評論 0 1
  • 那時候的喊麥, 年輕人的澎湃, 所有人都去愛, 現(xiàn)在已過時代, 逐漸漸漸失去, 逐漸迷失記憶, 誰還迷戀那時Mc的...
    伊利奶牛牛ing閱讀 209評論 0 1
  • 今天陪業(yè)力伙伴我們一起展業(yè),但是展業(yè)效果不好。 目標(biāo):幫助業(yè)力伙伴廖明元達(dá)成公司鉆石,每天給10個客戶講保險知識,...
    冰山軒兒閱讀 335評論 0 1

友情鏈接更多精彩內(nèi)容