首页 小编推荐 正文

备忘录,超实用服务异常处理指南,秘密花园

1. 服务反常的处理流程


2. 负载

2.1备忘录,超有用服务反常处理攻略,隐秘花园 检查机器 cpu 的负载

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

2.2 查找 cpu 占用率高的线程

top -p 25603 -H
printf 0x%x 25842
jstack 256ps软件下载03 | grep 0x64f2
cat /proc/interrupts


(1)CPU

(2)Memory

(3)IO

(4)Network

能够从以下几个方面监控CPU的信息:

(1)中止;

(2)上下文切换;

(3)可运转行列;

(4)CPU 利用率。

3. 内存

3.1 体系内存

free 指令

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

这儿的默许显现单位是 kb。

各项目标解说

  • total:总计物理内存的巨细。
  • used:已运用多大。
  • free:可用有多少。
  • Shared:多个进程同享的内存总额。
  • buffers: 磁盘缓存的巨细。
  • cache:磁盘缓存的巨细。
  • -/+ buffers/cached): used:已运用多大,free:可用有多少。
  • 已用内存 = 体系used memory - buffers - cached
  • (47000 = 3250000-201000-3002000)
  • 可用内存 = 体系free memory + buffers + cached
  • (3213000 = 10000+201000+3002000)

什么是buffer/cache?

  • buffer 指 Linux 内存的:Buffer cache,缓冲区缓
  • cache 指 Linux内存中的:Page cache,页面缓存

page cache

page cache 首要用来作为文件体系上的文件数据的缓存来用,尤其是针对当进程对文件有 read/write 操作的时分。

假设你细心想想的话,作为能够映射文件到内存的体系调用:mmap是不是很天然的也应该用到 page cache?在当时的体系完结里,page cache 也被作为其它文件类型的缓存设备来用,所以事实上 page cache 也担任了大部分的块设备文件的缓存作业。

buffer cache

buffer cache 首要用来在体系对块设备进行读写的时分,对块进行数据缓存的体系来运用。这意味着某些对块的操作会运用 buffer cache 进行缓存,比方咱们在格式化文件体系的时分。

一般情况下两个缓存体系是一同合作运用的,比方当咱们对一个文件进行写操作的时分,page cache 的内容会被改动,而 buffer cache 则能够用来将 page 标记为不同的缓冲区,并记载是哪一个缓冲区被修正了。这样,内核在后续履行脏数据的回写(writeback)时,就不必将整个 page 写回,而只需求写回修正的部分即可。

在当时的内核中,page cache 是针对内存页的缓存,说白了便是,假设有内存是以page进行分配办理的,都能够运用page cache作为其缓存来办理运用。

当然,不是一切的内存都是以页(page)进行办理的,也有许多是针对块(block)进行办理的,这部分内存运用假设要用到 cache 功用,则都会集到 buffer cache中来运用。(从这个视点动身打狗针多少钱,是不是buffer cache改名叫做block cache更好?)可是,也不是一切块(block)都有固定长度,体系上块的长度首要是依据所运用的块设备决议的,而页长度在X86 上无论是 32位仍是 64位都是 4k。

3.2 进程内存

3.2.1 进程内存计算

/proc/[pid]/status

经过/proc//status能够检查进程的内存运用情况,包含虚拟内存巨细(VmSize),物理内存巨细(VmRSS),备忘录,超有用服务反常处理攻略,隐秘花园数据段巨细(VmData),栈的巨细(VmStk),代码段的巨细(VmExe),同享库的代码段巨细(VmLib)等等。

Name: gedit /*进程的程序名*/
State: S (sleeping) /*进程的情况信息,详细拜见http://blog.chinaunix.net/u2/73528/showart_1106510.html*/
Tgid: 9744 /*线程组号*/
Pid: 9744 /*进程pid*/
PPid: 7672 /*父进程的pid*/
TracerPid: 0 /*盯梢进程的pid*/
VmPeak: 60184 kB /*进程地址空间的巨细*/
VmSize: 60180 kB /*进程虚拟地址空间的巨细reserved_vm:进程在预留或特别的内存间的物理页*/
VmLck: 0 kB /*进程现已锁住的物理内存的巨细.锁住的物理内存不能交换到硬盘*/
VmHWM: 18020 kB /*文件内存映射和匿名内存映射的巨细*/
VmRSS: 18020 kB /*运用程序正在运用的物理内存的巨细,便是用ps指令的参数rss的值 (rss)*/
VmData: 12240 kB /*程序数据段的巨细(所占虚拟内存的巨细),寄存初始化了的数据*/
VmStk: 84 kB /*进程在用户态的栈的巨细*/
VmExe: 576 kB /*程序所具有的可履行虚拟内存的巨细,代码段,不包含使命运用的库 */
VmLib: 21072 kB /*被映像到使命的虚拟内存空间的库的巨细*/
VmPTE: 56 kB /*该进程的一切页表的巨细*/
Threads: 1 /*同享运用该信号描绘符的使命的个数*/


3.2.2 JVM 内存分配

java内存组成介绍:堆(Heap)和非堆(Non-heap)内存

依照官方的说法:“Java 虚拟机具有一个堆,堆是运转时数据区域,一切类实例和数组的内存均从此处分配。堆是在 Java 虚拟机发动时创立的。” “在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。

能够看出JVM首要办理两种类型的内存:堆和非堆。

简略来说堆便是Java代码可及的内存,是留给开发人员运用的;非堆便是JVM留给自己用的。

所以办法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运转时常数池、字段和办法数据)以及办法和结构办法 的代码都在非堆内存中。

  1. JVM 自身需求的内存,包含其加载的第三方库以及这些库分配的内存
  2. NIO 的 DirectBuffer 是分配的 native memory
  3. 内存映射文件,包含 JVM 加载的一些 JAR 和第三方库,以及程序内部用到的。上面 pmap 输出的内容里,有一些静态文件所占用的巨细不在 Java 的 heap 里,因而作为一个Web服务器,赶忙把静态文件从这个Web服务器中人移开吧,放到nginx或许CDN里去吧。
  4. JIT, JVM会将Class编译成native代码,这些内存也不会少,假设运用了Spring的AOP,CGLIB会生成更多的类,JIT的内存开支也会随之变大,并且Class自身JVM的GC会将其放到Perm Generation里去,很难被回收掉,面临这种情况,应该让JVM运用ConcurrentMarkSweep GC,并启用这个GC的相关参数答应将不运用的class从Perm Generation中移除, 参数装备:
  5. -XX:+UseConcMarkSweepGC -X:+CMSPermGenSweepingEnabled -X:+CMSClassUnloadingEnabled,假设不需求移除而Perm Generation空间不行,能够加大一点:-X:PermSize=256M -X:MaxPermSize=512M
  6. JNI,一些JNI接口调用的native库也会分配一些内存,假设遇到JNI库的内存走漏,能够运用valgrind等内存走漏东西来检测
  7. 线程栈,每个线程都会有自己的栈空间,假设线程一多,这个的开支就很显着了
  8. jmap/jstack 采样,频频的采样也会添加内存占用,假设你有服务器健康监控,记住这个频率别太高,不然健康监控变成致病监控了。


1.办法区

也称”永久代” 、“非堆”,它用于存储虚拟机加载的类信息、常量、静态变量、是各个线程同享的内存区域。默许最小值为 16 MB,最大值为 64 MB,能够经过-XX: PermSize 和 -XX: MaxPermSize 参数约束办法区的巨细。

运转时常量池:是办法区的一部分,Class文件中除了有类的版别、字段、办法、接口等描绘信息外,还有一项信息是常量池,用于寄存编译器生成的各种符号引证,这部分内容将在类加载后放到办法区的运转时常量池中。

2.虚拟机栈

描绘的是java 办法履行的内存模型:每个办法被飞信履行的时分 都会创立一个“栈帧”用于存储局部变量表(包含参数)、操作栈、办法出口等信息。

每个办法被调用到履行完的进程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的进程。声明周期与线程相同,是线程私有的。

局部变量表寄存了编译器可知的各种根本数据类型(boolean、byte、char、short、int、float、long、double)、目标引证(引证指针,并非目标自身),其间64位长度的long和double类型的数据会占用2个局部变量的空间,其他数据类型只占1个。

局部变量表所需的内存空间备忘录,超有用服务反常处理攻略,隐秘花园在编译庞克莱门捷夫期间完结分配,当进入一个办法时,这个办法需求在栈帧中分配多大的局部变量是彻底确认的,在绾运转期间栈帧不会改动局部变量表的巨细空间。

3.本地办法栈

与虚拟机栈根本相似,差异在于虚拟机栈为虚拟机履行的java办法服务,而本地办法栈则是为Native办法服务。

4.堆

也叫做java 堆、GC堆是java虚拟机所办理的内存中最大的一块内存区域,也是被各个线程同享的内存区域,在JVM发动时创立。

该内存区域寄存了目标实例及数组(一切 new 的目标)。其巨细经过 -Xms (最小值) 和 -Xmx (最大值) 参数设置,-Xms为 JVM 发动时恳求的最小内存,默许为操作体系物理内存的 1/64 但小于 1G;

-Xmx 为 JVM 可恳求的最大内存,默许为物理内存的1/4但小于 1G,默许当空余堆内存小于 40% 时,JVM 会增大 Heap 到 -Xmx 指定的巨细,可经过 -XX:MinHeapFreeRation= 来指定这个比列;

当空余堆内存大于70%时,JVM 会减小 heap 的巨细到 -Xms 指定的巨细,可经过XX:MaxHeapFreeRation= 来指定这个比列,关于运转体系,为防止在运转时频频调整 Heap 的巨细,一般 -Xms 与 -Xmx 的值设成相同。

因为现在搜集器都是选用分代搜集算法,堆被划分为新生代和老时代。新生代首要存储新创立的目标和尚未进入老时代的目标。老时代存储经过屡次新生代GC(Minor GC)任然存活的目标。

5.程序计数器

是最小的一块内存区域,它的作用是当时线程所履行的字节码的行号指示器,在虚拟机的模型里,字节码解说器作业时便是经过改动这个计数器的值来选取下一条需求履行的字节码指令有备无患是什么意思,分支、循环、反常处理、线程康复等根底功用都需求依靠计数器完结。

3.2.3 直接内存

直接内存并不是虚拟机内存的一部分,也不是Java虚拟机规范中界说的内存区域。jdk1.4中新参加的NIO,引入了通道与凉粉的做法缓冲区的IO办法,它能够调用Native办法直接分配堆外内存,这个堆外内存便是本机内存,不会影响到堆内存的巨细。

3.2.4 JVM 内存剖析

检查 JVM 堆内存情况

jmap -heap [pid]

[root@server ~]$ jmap -heap 837
Attaching to process ID 837, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.71-b01
using thread-local object allocation.
Parallel GC with 4 thread(s)//GC 办法
Heap Configuration: //堆内存初始化装备
MinHeapFreeRatio = 0 //对应jvm发动参数-XX:MinHeapFreeRatio设置JVM堆最小闲暇比率(default 40)
MaxHeapFreeRatio = 100 //对应jvm发动参数 -XX:MaxHeapFreeRatio设置JVM堆最大闲暇比率(default 70)
MaxHeapSize = 2082471936 (1986.0MB) //对应jvm发动参数-XX:MaxHeapSize=设置JVM堆的最大巨细
NewSize = 1310720 (1.25MB)//对应jvm发动参数-XX:NewSize=设置JVM堆的‘新生代’的默许巨细
MaxNewSize = 17592186044415 MB//对应jvm发动参数-XX:MaxNewSize=设置JVM堆的‘新生代’的最大巨细
OldSize = 5439488 (5.1875MB)//对应jvm发动参数-XX:OldSize=:设置JVM堆的‘老生代’的巨细
NewRatio = 2 //对应jvm发动参数-XX:NewRatio=:‘新生代’和‘老生代’的巨细比率
SurvivorRatio = 8 //对应jvm发动参数-XX:SurvivorRatio=设置年青代中Eden区与Survivor区的巨细比值
PermSize = 21757952 (20.75MB) //对应jvm启檀郎动参数-XX:PermSize=:设置JVM堆的‘永生代’的初始巨细
MaxPermSize = 85983232 (82.0MB)//对应jvm发动参数-XX:MaxPermSize=:设置JVM堆的‘永生代’的最大巨细
G1HeapRegionSize = 0 (0.0MB)
Heap Usage://堆内存运用情况
PS Young Generation
Eden Space://Eden区内存散布
capacity = 33030144 (31.5MB)//Eden区总容量
used = 1524040 (1.4534378051757812MB) //Eden区已运用
free = 31506104 (30.04656219482422MB) //Eden区剩下容量
4.614088270399305% used //Eden区运用比率
F双月湾rom Space: //其间一个Survivor区的内存散布
capacity = 5242880 (5.0MB)
used = 0 (0.0MB)
free = 5242880 (5.0MB)
0.0% used
To Space: //另一个Survivor区的内存散布
capacity = 5242880 (5.0MB)
used = 0 (0.0MB)
free = 5242880 (5.0MB)
0.0% used
PS Old Generation //当时的Old区内存散布
capacity = 86507520 (82.5MB)
used = 0 (0.0MB)
free = 86507520 (82.5MB)
0.0% used
PS Perm Generation//当时的 “永生代” 内存散布
ca095187pacity = 22020096 (21.0MB)
used = 2备忘录,超有用服务反常处理攻略,隐秘花园496528 (2.3808746337890625MB)
free = 19523568 (18.619125366210938MB)
11.337498256138392% used
670 interned Strings occupying 43720 bytes.

关于这儿的几个generation网上材料一大把就不细说了,这儿算一下求和能够得知前者总共给Java环境分配了644M的内存,而ps输出的VSZ和RSS分别是7.4G和2.9G,这到底是怎么回事呢?

前面jmap输出的内容里,MaxHeapSize 是在指令行上配的,-Xmx4096m,这个java程序能够用到的最大堆内存。

VSZ是指已分配的线性空间巨细,这个巨细一般并不等于程序实践用到的内存巨细,发生这个的或许性许多,比方内存映射,同享的动态库,或许向体系恳求了更多的堆,都会扩展线性空间巨细,要检查一个进程有哪些内存映射,能够运用 pmap 指令来检查:

pmap -x [pid]

[root@server ~]$ pmap -x 837
837: java
Address Kbytes RSS Dirty Mode Mapping
0000000040000000 36 4 0 r-x-- java
0000000040108000 8 8 8 rwx-- java
00000000418cduration9000 13676 13676 13676 rwx-- [ anon ]
00000006fae00000 83968 83968 83968 rwx-- [ anon ]
0000000700000000 527168 451636 451636 rwx-- [ anon ]
00000007202d0000 1270想你的夜40 0 0 ----- [ anon ]
...
...
00007f55ee124000 4 4 0 r-xs- az.png
00007fff017ff000 4 4 0 r-x-- [ anon ]
ffffffffff600000 4 0 0 r-x-- [ anon ]
---------------- ------ ------ ------
total kB 7796020 3037264 3023928

这儿能够看到许多anon,这些表明这块内存是由mmap分配的。

RSZ是Resident Set Size,常驻内存巨细,即进程实践占用的物理内存巨细, 在现在这个比如傍边,RSZ和实践堆内存占用差了2.3G,这2.3G的内存组成分别为:

检查 JVM 堆各个分区的内存情况

jstat -gcutil [pid]

[root@server ~]$ jstat -gcutil 837 1000 20
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 80.43 24.62 87.44 98.29 7101 119.652 40 19肉核.719 139.371
0.00 80.43 33.14 87.44 98.29 7101 119.652 40 19.719 139.371

剖析 JVM 堆内存中的目标

检查存活的目标计算

jmap -histo:live [pid]

dump 内存

jmap -dump:format=b,file=heapDump [pid]

然后用jhat指令能够参看

jhat兄妹乱伦 -port 5000 heapDump

在阅读器中拜访:http://localhost:5000/ 检查详细信息

4. 服务目标

4.1 呼应时刻(RT)

呼应时刻是指体系对恳求作出呼应的时刻。直观上看,这个目标与人对软件功用的片面感触是十分共同的,因为它完好地记载了整个计算机体系处理恳求的时刻。

因为一个体系一般会供给许多功用,而不同功用的处理逻辑也千差万别,因而不同功用的呼应时刻也不尽相同,乃至同一功用在不同输入数据的情况下呼应时刻也不相同。

所以,在评论一个体系的呼应时刻时,人们一般是指该体系一切功用的均匀时刻或许一切功用的最大呼应时刻。

当然,往往也需求对每个或每组功用评论其均匀呼应时刻和最大呼应时刻。

关于单机的没有并发操作的运用体系而言,人们普遍以为呼应时刻是一个合理且精确的功用目标。需求指出的是,呼应时刻的绝对值并不能直接反映软件的功用的凹凸,软件功用的凹凸实践上取决于用户对该呼应时刻的承受程度。

关于一个游戏软件来说,呼应时刻小于100毫秒应该是不错的,呼应时刻在1秒左右或许归于牵强能够承受,假设呼应时刻到达3秒就彻底难以承受了。

而关于编译体系来说,完好编译一个较大规划软件的源代码或许需求几十分钟乃至更长期,但这些呼应时刻关于用户来说都是能够承受的。

4.2 吞吐量(Throughput)

吞吐量是指体系在单位时刻内处理恳求的数量。关于无并发的运用体系而言,吞吐量与呼应时刻成严厉的反比联系,实践上此刻吞吐量便是呼应时刻的倒数。

前面现已说过,关于单用户的体系,呼应时刻(或许体系呼应时刻和运用延迟时刻)能够很好地衡量体系的功用,但关于并发体系,一般需求用吞吐量作为功用目标。

关于一个多用户的体系,假设只要一个用户运用时体系的均匀呼应时刻是t,当有你n个用户运用时,每个用户看到的呼应时刻一般并不是nt,而往往比nt小许多(当然,在某些特别情况下也备忘录,超有用服务反常处理攻略,隐秘花园或许比nt大,乃至大许多)。

这是因为处理每个恳求需求用到许多资源,因为每个恳求的处理进程中有许多不走难以并发履行,这导致在详细的一个时刻点,所占资源往往并不多。也便是说在处理单个恳求时,在每个时刻点都或许有许多资源被搁置,当处理多个恳求时,假设资源装备合理,每个用户看到的均匀呼应时刻并不随用户数的添加而线性添加。

实践上,不同体系的均匀呼应时刻随用户米索前列醇片数添加而增加的速度也不大相同,这也是选用吞吐量来衡量并发体系的功用的首要原因。

一般来说,吞吐量是一个比较通用的目标,两个具有不同用户数和用户运用形式的体系,假设其最大吞吐量根本共同,则能够判别两个体系的处理才干根本共同。

4.3 并发用户数

并发用户数是指体系能够一起承载的正常运用体系功用的用户的终极一班之汪皓轩数量。与吞吐量比较,并发用户数是一个更直观但也更抽象的功用目标。

实践上,并发用户数是一个十分不精确的目标,因为用户不同的运用形式会导致不同用户在单位时刻宣布不同数量的恳求。

一网站体系为例,假定用户只要注册后才干运用,但注册用户并不是每时每刻都在运用该网站,因而详细极上亲父一个时刻只要部分注册用户一起在线,在线用户就在阅读网站时会花许多时刻阅读网站上的信息,因而详细一个时刻只要部分在线用户一起向体系宣布恳求。

这样,关于网站体系咱们会有三个关于用户数的计算数字:注册用户数、在线用户数和一起发请立秋宋刘翰求用户数。因为注册用户或许长期不登陆网站,运用注册用户数作为功用目标会形成很大的差错。而在线用户数和同事发恳求用户数都能够作为功用排五走势图目标。

比较而言,以在线用户作为功用目标更直观些,而以一起发恳求用户数作为功用目标更精确些。

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

每秒查询率QPS是对一个特定的查询服务器在规则时刻内所处理流量多少的衡量规范,在因特网上,作为域名体系服务器的机器的功用经常用每秒查询率来衡量。对应fetches/sec,即每秒的呼应恳求数,也便是最大吞吐才干。

从以备忘录,超有用服务反常处理攻略,隐秘花园上概念来看吞吐量和呼应时刻是衡量体系功用的重要目标,QPS尽管和吞吐量的计量单位不同,但应该是成正比的,任何一个目标都能够含量服务器的并行处理才干。当然Throughput更关怀数据量,QPS更关怀处理笔数。

4.5 CPU利用率

CPU Load Average < CPU个数 核数 0.7

Context Switch Rate

便是Process(Thread)的切换,假设切换过多,会让CPU忙于切换,也会导致影响吞吐量。

《高功用服务器架构 》这篇文章的第2节便是说的是这个问题的。

终究多少算适宜?google 了一大圈,没有一个切当的解说。

Context Switch大体上由两个部分组成:中止和进程(包含线程)切换,一次中止(Interrupt)会引起一次切换,进程(线程)的创立、激活之类的也会引起一次切换。CS的值也和TPS(Transaction Per Second)相关的,假定每次调用会引起N次CS,那么就能够得出

Context Switch Rate = Interrupt Rate + TPS* N

CSR减掉IR,便是进程/线程的切换,假设主进程收到恳求交给线程处理,线程处理完毕归还给主进程,这儿便是2次切换。

也能够用CSR、IR、TPS的值代入公式中,得出每次事物导致的切换数。因而,要下降CSR,就必须在每个TPS引起的切换上下功夫,只要N这个值降下去,CSR就能下降,抱负情况下N=0,可是无论如何假设N >= 4,则要好好检查检查。别的网上说的CSR<5000,我以为规范不应如此单一。

这三个目标在 LoadRunner 中能够监控到;别的,在 linux 中,也能够用 vmstat 检查r(Load Arerage),in(Interrupt)和cs(Context Switch)

5. 东西

uptime

dmesg

top

检查进程活动情况以及一些体系情况

vmstat

检查体系情况、硬件和体系信息等

iostat

检查CPU 负载,硬盘情况

sar

归纳东西,检查体系情况

mpstat

检查多处理器情况

netstat

检查网络情况

iptraf

实时网络情况监测

tcpdump

抓取网络数据包,详细剖析

mpstat

检查多处理器情况

tcptrace

数据包剖析东西

netperf

网络带宽东西

dstat

归纳东西,归纳了 vmstat, iostat, ifstat, netstat 等多个信息

Reference

  • http://tmq.qq.com/2016/07/it-is-necessary-to-know-the-background-performance-test/
  • https://www.ibm.com/developerworks/java/library/j-nativememory-lin备忘录,超有用服务反常处理攻略,隐秘花园ux/
  • http://www.oracle.com/technetwork/java/javase/index-137495.html
  • http://www.hollischuang.com/archives/303
转载自 Zane Blog,原文为《服务调优》

相关推荐

  • 暂无相关文章