news center新闻中心
Home
>
新闻中心
>
技术资料
>
新闻详情

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

云起科技:2021-01-25 16:23:30     阅读数:137    

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

 

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

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

    

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

    更实际的情形是,应用出现高应用或者高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历史记录去回溯。