`

排查Java线上服务故障的方法和实例分析

阅读更多

 

前言

作为在线系统负责人或者是一个技术专家,你可能刚刚接手一个项目就需要处理紧急故障,或者被要求帮忙处理一些紧急的故障,这个时候的情景是:(1)你可能对这个业务仅仅是听说过,而不怎么真正了解;(2)你可能没有这个故障的详细信息,比如可能仅仅是有使用方反馈服务中断了10分钟;(3)你对代码细节还没有仔细研究过。

 

这个时候该怎么解决问题呢?根据以前的经验,工程师们常常倾向于直接登上服务器检查代码,试图立刻修改问题。或者是把某些可能是问题的配置做修改,但并不是100%确认这就是问题的根本原因。但结果往往是在解决问题的同时引入了新的问题,或者是没有找到问题的根本原因,导致用户的再次投诉。

 

因此我把处理和排除故障分为4个必须得步骤:紧急处理、添加监控、使用JDK性能监控工具和分析源代码。从治标不治本,到治标又治本。

紧急处理

紧急处理,顾名思义,是检查和评度当前故障的影响范围,并尽快使服务先恢复起来。其中检查和评估当前故障的影响范围是非常重要的。以微博系统举例,一般用户的投诉率为千分之1,如果有超过10起用户投诉,就可能是大面积故障。如果只是负责线上跟踪的QA人员反馈的问题,而没有用户投诉,则可以有较多的时间去处理。对于紧急的大面积故障,首先想到的不应该是检查问题。而是需要立刻追查最近线上系统是否有更改,我们的经验是95%的故障都是在新代码上线后的12小时内发生的。此时应该立刻回滚新更改。另外5%的故障大部分是由于业务扩展导致的。互联网业有一个规律,线上系统每半年需要重构一次,否则无法对应业务量的增长。对于这种业务量增长造成的故障,通常可以通过重启服务来紧急处理。

 

因此紧急处理的首选是立刻回滚新更改。

添加监控

紧急处理之后,服务已经恢复了,但是问题并没有找到。如果是新代码上线造成的故障,回滚之后,工程师会有各种手段,在测试环境追查问题。而针对系统容量不足造成的故障,需要特别添加监控作为追查问题的重要手段。因为互联网业务请求高峰和低谷差别非常明显,微博业务中的请求高峰往往出现在晚上10点左右,而且不是稳定的出现。要求工程师们每天悲催的坐在电脑前守到晚上10点,却不见得能发现问题,是非常低效的。监控一般用一个简单的脚本就可以搞定,比如http服务监控,

 

MAX_LATENCY_TIME=5

curl -m $MAX_LATENCY_TIME "http://1.2.3.4:8011/...."

if [ $? -ne 0 ] ; then
        sIp=`hostname`
        errmsg="gexin install latency > "$MAX_LATENCY_TIME"s"
        // 具体告警的处理
        echo $errmsg
        echo send success
fi
 

使用JDK性能监控工具

刚刚添加的监控开始报警了。登上服务器,该做些什么呢?一般需要做如下动作,

(1)首先要查看日志,看看有没有Exception。另外日志中常常有对接口调用,缓存使用的监控告警信息。

(2)看看目前gc的状况如何,使用JDK自带的工具就可以。jstat -gc -h 10 vmid 5000,每5秒打出一次。我遇到过两次线上故障,都是简单的通过jstat就找到了问题。一次是Permanent区分配过小,JVM内存溢出。另一次是发生了过多的Full GC,使得系统停止响应。内存造成的问题通过简单的重启服务就可以使得服务恢复,但重启之后往往很快又出现问题。这个期间你要监控gc,看看期间发生了什么事情。如果是old区增长的过快,就可能是内存泄露。这个时候,你需要看看到底是什么对象占用了你的内存。

(3)jmap -histo vmid > jmap.log,该命令会打出所有对象,包括占用的byte数和实例个数。分享一个线上jmap实例,

 num     #instances         #bytes  class name
----------------------------------------------
   1:      10540623      668712400  [B
   2:      10532610      252782640  com.google.protobuf.ByteString
   3:       4305941      234036872  [Ljava.lang.Object;
   4:       1066822      170691520  cn.abc.data.protobuf.UserWrap$User
   5:       3950998      158039920  java.util.TreeMap$Entry
   6:       3950159      126405088  com.google.protobuf.UnknownFieldSet$Field
   7:        780773      118677496  cn.abc.data.protobuf.StatusWrap$Status
   8:       4305047      103321128  java.util.ArrayList
   9:       4301379      103233096  java.util.Collections$UnmodifiableRandomAccessList
  10:       3207948      102654336  java.util.HashMap$Entry
  11:       2571737       82300280  [C
  12:       2569460       82222720  java.lang.String
  13:       3952892       63246272  java.lang.Integer
  14:       1314438       63093024  java.util.TreeMap
  15:       2533229       60797496  java.lang.Long
  16:       1065093       51124464  cn.abc.data.protobuf.PostSourceWrap$PostSource
  17:       1314430       42061760  java.util.Collections$UnmodifiableMap
  18:        284198       40924512  cn.sina.api.data.protobuf.CommentWrap$Comment
  19:          4273       34273568  [Ljava.util.HashMap$Entry;
  20:        459983       33118776  cn.abc.data.protobuf.AbcMessageWrap$AbcMessage
  21:        458776       22021248  java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask
  22:        458776       22021248  java.util.concurrent.FutureTask$Sync
  23:       1314416       21030656  com.google.protobuf.UnknownFieldSet
  24:        459982       11039568  cn.sina.datapush.notifier.core.DispatcherBase$MessageProcessor
  25:        458776       11010624  java.util.concurrent.Executors$RunnableAdapter
  26:        458776        7340416  cn.abc.datapush.notifier.core.DispatcherBase$MessageProcessor$1
  27:         40897        5909152  <constMethodKlass>
  28:         40897        4917592  <methodKlass>
  29:          3193        3748688  <constantPoolKlass>
  30:         62093        3274344  <symbolKlass>
 

排名前几位的都是Byte,Char,String,Integer之类的,不要灰心,继续往下看,后面会出现一些有趣的对象。第22位发现了45万个FutureTask,很显然这是不正常的。应该是某线程响应过慢,造成待处理任务出现了堆积。查看代码,果然处理线程只有4条,大量的请求得不到响应。通过gc分析,每5秒钟会产生100M左右的对象得不到处理,所以JVM heap很快就被耗尽。将线程数改为36条,问题立刻得到了解决。

 

(4)检查目前cpu占用情况,top -H,然后按“1”,会看到当前进程中每个线程所占CPU的比例。注意观察前几名,然后jstack -l vmid > jstack.log打出线程堆栈,看看是什么线程占用了CPU。这里需要注意的是,top -H显示的线程id是十进制,而jstack打出的线程堆栈是16进制。看看那些最忙的thread是不是那些真正应该忙的thread,如果是一些“黑马”线程,则要考虑是否是代码有死循环或者是意外的问题。

分析源代码

分析源代码是最有技术含量的事情,也是比较耗时而且不见得有效果的事情。所以我把源码分析放到解决线上问题的最后一步,因为必须要做到“有的放矢”。带着问题去分析代码,会比较容易。通过20%代码的修改,就可以解决80%的性能问题。比如上面这个线上问题,肯定是线程处理慢造成的问题。需要针对线程的调用,同步异步等进行分析。

1
0
分享到:
评论

相关推荐

    Java线上故障排查方案(2).pdf

    本文档围绕Java线上故障排查提供了详尽的方案和知识点,覆盖了从问题定位到解决方案的多个方面。 首先,了解Java线上常见问题的分类是非常重要的。在生产环境中,问题可大致分为系统异常和业务异常两大类。系统异常...

    以线上实例来看,内存泄漏的图文解决方案.docx

    本文将以一个具体的线上实例为背景,介绍如何逐步排查并解决内存泄漏问题。通过图文并茂的方式,帮助读者更好地理解内存泄漏的诊断方法。 #### 二、问题背景 在一个项目中,开发团队新上线了一个API接口,并选择了...

    基于java的校园二手交易市场系统设计与实现(源代码+部署视频+数据库).zip

    本项目是针对校园内二手商品交易需求而设计的一款系统,采用Java编程语言进行开发,旨在提供一个便捷、安全的线上交易平台,促进学生之间的资源共享和交流。系统包括源代码、部署视频以及数据库等关键组成部分,为...

    dubbo-monitor-simple-2.8.4

    在日常运维中,dubbo-monitor-simple为我们提供了宝贵的诊断工具,通过监控服务的调用情况,可以及时发现并解决问题,避免线上故障的发生。同时,它也提供了优化服务性能的数据依据,通过对调用延迟、失败率等指标的...

    dubbo-admin

    "分布式" 表明 dubbo-admin 能够处理复杂的分布式服务架构问题,而 "监控平台" 暗示了它的主要功能是收集、展示和分析服务运行的各种指标。 **dubbo-admin 的主要功能与特性:** 1. **服务发现**:dubbo-admin ...

    开源阿里JVM诊断工具最新版arthas-packaging-3.6.6

    4. **动态代码注入**:`execute`和`print`命令允许在运行时执行Java代码,查看对象属性和方法结果,甚至修改运行时行为。 5. **日志增强**:Arthas的`log`命令可以帮助调整日志级别,快速定位日志输出问题。 6. **...

    百套毕设之-java(演示+源码)springboot校园在线拍卖系统.zip

    2. 监控与日志:Actuator监控系统状态,Logback或Log4j记录日志,便于故障排查。 3. 自动化部署:使用Jenkins或GitLab CI/CD实现持续集成和部署。 总的来说,这个校园在线拍卖系统项目涵盖了Java开发的多个方面,从...

    SOLR的应用教程

    解答关于Solr使用过程中可能遇到的问题,如乱码和查不到结果的排查方法。 这个SOLR应用教程涵盖了从基础概念到实际应用,包括安装配置、索引和搜索操作、SolrJ的使用以及性能优化等多个方面,为读者提供了一个全面...

    基于ssm微信小程序的自习室预约系统源码数据库.zip

    同时,还需要考虑系统的监控、日志管理和故障排查,以确保系统稳定运行。 10. **用户体验**:微信小程序的交互设计和UI设计是吸引用户的关键,良好的用户体验可以提高用户的满意度和使用频率。因此,在开发时需注重...

    学士后网上书城

    运维方面,可能会涉及日志监控、性能优化、故障排查等内容。 8. **项目文档**:虽然未明确提及,但完整的项目通常会附带详细的设计文档、API接口说明、数据库设计文档等,帮助用户理解和使用。 通过分析"学士后...

    “红灯笼”网上汽车租赁系统的设计与实现-全文标注报告

    论文还可能包含了性能测试和故障排查的部分,通过模拟用户并发请求,测试系统的负载能力和响应时间,以确保在高峰期系统能够稳定运行。对于可能出现的问题,如数据一致性、并发冲突等,作者可能会提出相应的解决方案...

    开源企业搜索引擎SOLR的应用教程

    Solr提供了一个强大的管理界面,可以进行索引管理、查询分析、系统监控等操作,方便了系统维护和故障排查。 #### SOLR服务原理 - **索引**:Solr通过解析和分析文档内容,将关键信息抽取出来,形成倒排索引,便于...

    solr教材-PDF版

    - **7.1 出现乱码或者查不到结果的排查方法**:提供了一套系统化的故障排查方案,帮助用户解决常见的问题。 以上是关于《solr教材-PDF版》的详细知识点介绍,涵盖了从Solr的基本概念到具体应用场景,再到性能调优等...

    Solrj 中文教程

    ### Solrj 中文教程知识点概览 #### 一、企业搜索引擎方案选型与Solr简介 ##### 1.1 企业搜索引擎方案选型 在选择企业级搜索引擎时,主要...- **7.1 出现乱码或者查不到结果的排查方法**:解决常见问题的方法和步骤。

Global site tag (gtag.js) - Google Analytics