加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

一篇超实用的服务异常处理指南

发布时间:2019-04-27 06:00:54 所属栏目:建站 来源:启迪云Tuscloud
导读: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-p25603-H printf0x%x25842 jstack25603|grep0x64f2 cat/proc/interrupts (1)CPU (2)

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]

  1. [root@server ~]$ jmap -heap 837 
  2. Attaching to process ID 837, please wait... 
  3. Debugger attached successfully. 
  4. Server compiler detected. 
  5. JVM version is 24.71-b01 
  6. using thread-local object allocation. 
  7. Parallel GC with 4 thread(s)//GC 方式 
  8. Heap Configuration: //堆内存初始化配置 
  9. MinHeapFreeRatio = 0 //对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default 40) 
  10. MaxHeapFreeRatio = 100 //对应jvm启动参数 -XX:MaxHeapFreeRatio设置JVM堆最大空闲比率(default 70) 
  11. MaxHeapSize = 2082471936 (1986.0MB) //对应jvm启动参数-XX:MaxHeapSize=设置JVM堆的最大大小 
  12. NewSize = 1310720 (1.25MB)//对应jvm启动参数-XX:NewSize=设置JVM堆的‘新生代’的默认大小 
  13. MaxNewSize = 17592186044415 MB//对应jvm启动参数-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小 
  14. OldSize = 5439488 (5.1875MB)//对应jvm启动参数-XX:OldSize=<value>:设置JVM堆的‘老生代’的大小 
  15. NewRatio = 2 //对应jvm启动参数-XX:NewRatio=:‘新生代’和‘老生代’的大小比率 
  16. SurvivorRatio = 8 //对应jvm启动参数-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值 
  17. PermSize = 21757952 (20.75MB) //对应jvm启动参数-XX:PermSize=<value>:设置JVM堆的‘永生代’的初始大小 
  18. MaxPermSize = 85983232 (82.0MB)//对应jvm启动参数-XX:MaxPermSize=<value>:设置JVM堆的‘永生代’的最大大小 
  19. G1HeapRegionSize = 0 (0.0MB) 
  20. Heap Usage://堆内存使用情况 
  21. PS Young Generation 
  22. Eden Space://Eden区内存分布 
  23. capacity = 33030144 (31.5MB)//Eden区总容量 
  24. used = 1524040 (1.4534378051757812MB) //Eden区已使用 
  25. free = 31506104 (30.04656219482422MB) //Eden区剩余容量 
  26. 4.614088270399305% used //Eden区使用比率 
  27. From Space: //其中一个Survivor区的内存分布 
  28. capacity = 5242880 (5.0MB) 
  29. used = 0 (0.0MB) 
  30. free = 5242880 (5.0MB) 
  31. 0.0% used 
  32. To Space: //另一个Survivor区的内存分布 
  33. capacity = 5242880 (5.0MB) 
  34. used = 0 (0.0MB) 
  35. free = 5242880 (5.0MB) 
  36. 0.0% used 
  37. PS Old Generation //当前的Old区内存分布 
  38. capacity = 86507520 (82.5MB) 
  39. used = 0 (0.0MB) 
  40. free = 86507520 (82.5MB) 
  41. 0.0% used 
  42. PS Perm Generation//当前的 “永生代” 内存分布 
  43. capacity = 22020096 (21.0MB) 
  44. used = 2496528 (2.3808746337890625MB) 
  45. free = 19523568 (18.619125366210938MB) 
  46. 11.337498256138392% used 
  47. 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]

  1. [root@server ~]$ pmap -x 837 
  2. 837: java 
  3. Address Kbytes RSS Dirty Mode Mapping 
  4. 0000000040000000 36 4 0 r-x-- java 
  5. 0000000040108000 8 8 8 rwx-- java 
  6. 00000000418c9000 13676 13676 13676 rwx-- [ anon ] 
  7. 00000006fae00000 83968 83968 83968 rwx-- [ anon ] 
  8. 0000000700000000 527168 451636 451636 rwx-- [ anon ] 
  9. 00000007202d0000 127040 0 0 ----- [ anon ] 
  10. ... 
  11. ... 
  12. 00007f55ee124000 4 4 0 r-xs- az.png 
  13. 00007fff017ff000 4 4 0 r-x-- [ anon ] 
  14. ffffffffff600000 4 0 0 r-x-- [ anon ] 
  15. ---------------- ------ ------ ------ 
  16. total kB 7796020 3037264 3023928 

这里可以看到很多anon,这些表示这块内存是由mmap分配的。

RSZ是Resident Set Size,常驻内存大小,即进程实际占用的物理内存大小, 在现在这个例子当中,RSZ和实际堆内存占用差了2.3G,这2.3G的内存组成分别为:

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

jstat -gcutil [pid]

  1. [root@server ~]$ jstat -gcutil 837 1000 20 
  2. S0 S1 E O P YGC YGCT FGC FGCT GCT 
  3. 0.00 80.43 24.62 87.44 98.29 7101 119.652 40 19.719 139.371 
  4. 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个用户使用时,每个用户看到的响应时间通常并不是n×t,而往往比n×t小很多(当然,在某些特殊情况下也可能比n×t大,甚至大很多)。

这是因为处理每个请求需要用到很多资源,由于每个请求的处理过程中有许多不走难以并发执行,这导致在具体的一个时间点,所占资源往往并不多。也就是说在处理单个请求时,在每个时间点都可能有许多资源被闲置,当处理多个请求时,如果资源配置合理,每个用户看到的平均响应时间并不随用户数的增加而线性增加。

实际上,不同系统的平均响应时间随用户数增加而增长的速度也不大相同,这也是采用吞吐量来度量并发系统的性能的主要原因。

一般而言,吞吐量是一个比较通用的指标,两个具有不同用户数和用户使用模式的系统,如果其最大吞吐量基本一致,则可以判断两个系统的处理能力基本一致。

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 等多个信息

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读