关于服务器性能排查的思考

原创
2019/02/17 03:46
阅读数 4.1K

    服务器上性能排查的经验不多,这里算对以往经验的一个总结吧!

 

    服务性能排查一般就两种:高内存占用或高CPU占用,需要具体问题具体分析。比如应用程序高内存占用,可能因为大文件读取、频繁IO,内存消耗频繁,导致频繁GC,进一步占用内存和CPU;比如应用程序高CPU占用,可能在执行大任务计算,或者死循环、卡死,或者不断超时、重试(活锁是容易占CPU的,死锁和饥饿是容易占内存的,因为资源不释放)。

应用进程还活着,但页面出不来、不响应,这种是高CPU,高内存是应用响应慢或者内存溢出、直接死掉。

    

    可以从这两个方向考虑,比如:

  • 高CPU占用的话,关注一下,是user态占用率高还是sys态占用率高,闲置多少;占用率高的进程是否频繁变动;load平均负载是否过载(超过70%)。如果user态CPU占用率过高,意味着应用在做高耗CPU的任务;如果sys态占用率过高,则意味着内核态的操作比较多比如IO复制;如果占用率高的线程频繁变动,则可能是CPU时间片不断调度,线程唤醒跑一下而后换另一个线程跑,需要看多线程任务是否存在大计算问题,以及线程池设置是否合适等;
  • 高内存的话,关注一下,free可用内存有多少,buff、cache还有多少;swap交换区是否过高,这通常是因为未禁用swap区而内存又不足,导致swap频繁读写,性能低下;sar内存变化曲线,是稳定上升还是高低曲线,前者意味着某个函数存在内存泄漏问题,而后者意味着有某个高内存运算任务在线程池里唤醒重试;

    更实际的情形是,应用出现高应用或者高CPU的问题时,你只有30秒到两三分钟来快速定位问题,而后就要马上重启应用,避免影响到正常业务。像高CPU,可能连日志都没有,因为请求没进来,很多时候你都需要去前后dump线程堆栈或内存堆栈,以保留现场方便后续分析工作。成熟的线上环境,一般会有仪表大盘和监控预警,内存或CPU超过阈值你就需要立马去关注了,或应用发布回滚,在线下验证问题。

 

    

    一般出问题时,首先去看监控大盘,有没有异常告警,看不出问题来再去查看系统层面有没有异常:

  1. 通过top或htop命令观察系统的整体情况,很容易拿到占用CPU或内存较高的进程ID;
    • 先通过ps aux | grep [PID]进一步确定是Java进程还是服务器上其它进程;
  2. 如果是CPU占用高,通过pidstat查看该进程,然后用perf/trace+PID,抓取CPU消耗栈来找到引发瓶颈的具体的函数名,结合业务代码来分析问题具体在哪儿;
    • 通过ps -mp pid -o THREAD,tid,time 找到具体的线程ID;
    • printf "%x\n" [TID]] 将线程id转换为16进制
  3. 如果是内存占用高,通过free命令查看内存的使用情况,然后通过pmap/jmap命令查看进程的内存分布
    • 或是通过vmstat命令查看内存使用的变化趋势,用memleak -a -p [PID]查看内存分配栈,定位到是哪个函数内存泄漏了
  4. 如果CPU、内存没问题,就要去看磁盘,通过df命令和iostat命令去查看磁盘空间和I/O情况;

load平均负载和CPU使用率是有区别的,一个是单位时间内的活跃进程数,一个是单位时间内CPU空闲时间与总CPU时间的比值。它们之间有一定的联系,比如在CPU密集型应用中,大计算量任务会导致大量的CPU被占用,平均负载升高,而在I/O密集型应用中,不可中断进程的增多会导致平均负载升高,但I/O等待不占CPU,CPU使用率并不一定会很高。

CPU性能排查时首先去查看CPU使用率,比如user用户态较高,则往应用进程的性能问题去排查;如果sys内核态较高,则往系统调用的性能问题去排查。但很多时候,监控告警之后,等你登陆服务器时性能问题已经结束了,这样在线分析就看不出问题了,就需要从load平均负载、sar历史记录去回溯。

 

    写的很粗,关于上下文切换的问题不是很懂,没写进去。如果有不同的意见建议,欢迎拍砖  

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
30 收藏
2
分享
返回顶部
顶部