分布式java应用笔记系列---寻找系统系能瓶颈

读书笔记,感谢林昊
 
系统的瓶颈表象一般不外乎以下几点:
 1.资源消耗过多
  --资源的消耗主要是在CPU、IO、网络、以及内存方面
 2.外部处理系统的性能不足
  --例如数据库系统的性能不足。不满足高并发快响应。其原因大多也是资源消耗过多引起的
 3.资源消耗不多,但是程序的响应速度确达不到要求
  --主要原因是代码不合理。例如多线程锁机制使用不合理,存在激烈的竞争。。
  
  
===========================================================================================================================================
CPU消耗分析
CUP方面知识:
CUP主要是用于终端、系统内核以及用户近程的任务处理。优先级为中断>内核>用户进程
  1.上下文切换:context(上下文这个概念挺频繁的啊。。spring里面也有)
  一个cpu同一时刻只能执行一个线程,当切换线程的时候(时间片结束、阻塞、打断),会存储当前线程状态,并且运行要执
  行的线程,这个称作上下文切换。上下文切换多发生在文件IO、网络IO、锁等待和线程sleep的时候。
  2.运行队列。个人理解就是平均每个cpu上分配到的任务。比如java启动了8个线程,并且8个线程都是可运行状态,共有4
核的cpu,则load值就为8/4=2。一般建议为1~3为好。★这个也就是做apache-mima的时候,为什么要制定accptor的数量为
cpu核数*2+1的原因
 3.利用率。利用率实是指cpu在用户近程,内核,中断处理,io等待以及空闲等待五部分使用的百分比。这五个指标用来
 分析cpu的情况能够反应出是什么原因导致cpu效率降低
 
 在ubuntu下执行命令top>top.txt,然后cat top.txt可以看到当前近程以及系统资源的消耗情况
详图如    寻找系统系能瓶颈_1.jpg
乱码问题top|col -b>top.txt但是还是不行
 ★us(user)表示用户近程占用的百分比
 ★sy(system)表示系统线程所占用的百分比
 ★id(idle)表示系统空闲占用的百分比
 ★wa(iowait)表示在执行过程中因为io等待所占用的时间的百分比
 ★hi(hard interrupt)硬件中断占用百分比
 ★si(soft interrupt)软件中断占用百分比
 ★ni(nice命令?这是什么?)为nice命令改变优先级的任务所占得百分比
 
在top命令的视图下,按下1,能够反映出各个cpu的使用率。在按一下就切回来了
在top命令的视图下,按下shift+h,能够反映出各个线程的使用情况,但是貌似不太好使。。一闪一闪的。此时pid即为线程id
也可以使用pidstat,不过先sudo apt-get install sysstat
pid -p [pid] -t 1 5来过滤想查找的pid
截图附件

 

分布式java应用笔记系列---寻找系统系能瓶颈_第1张图片

 

也可以使用vmstat来查看,截图如附件

 

图片

 

 
 

cpu消耗严重的时候,主要体现在cpu的使用率过高,其中包括us、sy、wa、hi的值变高(wa变高是io问题,如网卡接收数据)
对于java而言,主要体现在us和sy两个参数上面:
 1.us过高主要原因是线程一直处于可运行状态(runnable),或者是频繁的GC所造成的。对于一直处于可运行状态的线程,可以适当采用使其睡眠的方法来处理,
      虽然睡眠使这个线程的执行效率变低,但是可以使cpu有机会来处理其他的线程。不会造成其他线程的“饥饿”,从而程序的整体运行水平提高
      ★在top中根据pid找到使用率太高的线程12345,然后用jstack [pid] |grep 'nid=12345'来确定。需要多做几遍
    
 2.sy过高的主要原因是线程上下文的切换过于频繁。锁的使用出现了问题。同样用jstack -l[pid]的方法找到该线程
     

===========================================================================================================================================
文件IO消耗分析
linux的系统,会采用cache的机制使用文件。这样就会发现linux的可用物理内存不是很多,但是cache所占得内存却很多(内存都被cache占用了)。
如果内存足够的话,那么只有第一次加载文件和写出文件会产生真正的文件IO,其他的情况都不会产生文件IO。
JAVA中造成io大量消耗掉的原因主要可能为多个线程需要进行大量的内容写入写出(例如log的写入)。磁盘的本身处理速度慢
文件本身就很大(数据库数据量一大就会发生查询插入过慢)。
 
1.使用pid -t -d -p[pid]1 100,如果不知道pid的什么,就直接pid -d -t直接查看文件IO的使用情况
如图: 查找到占用资源高的pid即可

 

分布式java应用笔记系列---寻找系统系能瓶颈_第2张图片

 

2.使用iostat,截图如下

 

分布式java应用笔记系列---寻找系统系能瓶颈_第3张图片

 

===========================================================================================================================================
网络IO消耗
可以使用sar -n FULL 1 2命令查看网络IO的情况,或者使用tcpdump来查看
但是一般的java应用并不会产生大量的网络IO
===========================================================================================================================================
内存消耗分析:
目前的java只有在创建线程和DerectByteBuffer的时候才会在JVM堆以外的JVM内存(其中创建线程实在JVM方法栈上,DerectByteBuffer消耗JVM以外的物理内存)。
其中对内存的消耗关注点主要集中在两点
第一:对JVM以外的内存消耗关注(Swap区的消耗和物理内存消耗):
 采用vmstat命令,管关注memory下的swpd、free、buff、cache、以及swap下的si和so
  ★swpd是虚拟内存已经使用了的部分kb
  ★free表示空闲物理内存
  ★buff表示缓冲内存
  ★swap下的si是每秒从disk读入到内存的数据量,so为写入disk的
 还可以采用sar命令
 但是貌似是pidstat -r -p [pid] 1 100比较好
第二:对JVM以内的内存消耗关注:
 这个参考一下jvm的内存分配机制就自然明白了,主要是对象和GC之间的矛盾
===========================================================================================================================================
程序资源消耗正常,但是程序的执行速度很慢分析
1.锁竞争激烈,常见的有数据库连接池。10个大小的池子,如果有50个线程来链接,那么就必须有40个等待了
2.没有充分使用硬件资源。能够多线程操作的东西却一直在使用单线程
3.数据量的增长。例如数据库的数据文件太大。
尝试去使用Jprifiler这个商业工具。。。
 
总结命令:
top jstat pidstat vmstat iostat jstack

你可能感兴趣的:(分布式java应用笔记系列---寻找系统系能瓶颈)