运维常见问题解决方案

我所在的团队主要的稳定性工作,一部分是“大促稳定性”,一部分是“日常稳定性”。其中“日常稳定性”我们是通过一个叫“技术健康度”的评分机制来通晒的,这个“技术健康度”目前包括“应用、变更、数据库、搜索引擎”这四个治理维度,通过已经识别的风险提炼出来的规则,进行日常的扫描,同时再搭配上“技术工单准时完结率”,客观评价各团队的稳定性和质量的水位。最后每个团队可以看到一个总分数和以上四个治理维度各自的分数,看到自己的长短板,辅助一线开发阶段性的对某几个方面进行提升。

这里列举一些“应用”视角下的常见运维问题定位和解决的方案。

CPU消耗过高

【人工排查手段】

  1. 部分机器问题,还是全局问题,如果是全局问题需要考虑是否是上有流量变大、消息量变多等原因导致,依赖限流保护自己(sentinel 系统保护限流)。
  2. top查看CPU占用较高的进程情况,CPU占用高的进程的线程情况,jstack、pstack分析线程的合理性。
  3. arthas、perf抓取火焰图分析。

【可能的原因以及人工解决方案】
Q1:全局问题。
A1:报警、限流、扩容。
Q2:不合理的流量已经代码逻辑造成开销比较大。
A2:代码性能优化【场景比较复杂,分支多】。

【辅助定位以及变更托管可能性】
● 执行相关的命令,并分析对应的结果:top 、top -H -p、perf、asyncprofile。
● 分析堆栈数据、perf产出数据,找出不合理的代码逻辑。
● 根据分析建议,产出修复代码,并完成代码变更上线。

磁盘利用率高

【人工排查手段】

  1. 命令查看结果:du -h * 、df -h、lsof 。
  2. 查看是否存在句柄未正常释放的场景,du、df 数值不匹配,lsof 持有未释放句柄。
  3. 大日志文件(不同分片聚合)。

【可能的原因以及人工解决方案】
Q1:句柄未正常释放导致的磁盘利用率过高。
A1:重启机器可以临时恢复;根治方案需要排查未正常释放的原因,多见于logagent bug、日志清理配置不合理、人为操作。

Q2:大文件导致的磁盘利用率过高。
A1:业务日志类文件,截取一段日志,分析占比较高的日志打印,评估是否合理,如果不合理关闭对应的日志打印;非业务日志类文件,多见于Core dump文件,这类上传分析,或者距离比较久的直接删除;历史比较久的大量文件,属于日志清理策略配置不合理导致的问题,需要调整日志清理策略。

【辅助定位以及变更托管可能性】
● 执行相应的命令,并分析结果;du -h、df -h、lsof;日志分析以及提取。
● 在应用水位合理的条件下,执行单机的应用重启操作,临时释放磁盘利用率。
● 根据分析,优化日志的打印方式:不打印、抽样打印、仅打印必要的内容。

RT类问题

【人工排查手段】

  1. 利用鹰眼采集RT超过一定阈值的数据。
  2. 分析鹰眼trace,找到耗时消耗比较大的调用,分析耗时高的合理性。

【可能的原因以及人工解决方案】
Q1:下游资源达到瓶颈,影响自身;比如数据库、下游应用负载过高。
A1:可能是自身的调用量大,导致下游异常,也可能是下游异常,导致自身受影响。这两类需要单独分析。
Q1:自身GC、线程池、负载等问题,导致RT升高。
A1:结合Sunfire监控指标(CPU、HSF线程数、GC耗时)辅助确认原因。深度分析鹰眼日志,以及堆栈信息,判断是否存在锁争抢、内部线程资源竞争等问题。产出优化建议

【辅助定位以及变更托管可能性】
● 通过系统监控平台分析相关资源的利用率情况。
● 通过链路平台分析耗时的调用上下游。
● 分析堆栈锁情况和多资源争抢的场景,并产出优化建议。
● 产出代码优化建议,并协助功能验证。

HSF错误率

【人工排查手段】

  1. 通过链路平台看全局的问题,明确具体失败率上涨的接口、错误码、调用trace等信息。
  2. 查看hsf的日志,内部会有错误相关的堆栈信息。

【可能的原因以及人工解决方案】
Q1:限流导致的部分接口问题。
A1:为了保护自身的合理限流,此时需要推动上游优化调用方式;调用量增加导致的非预期限流,拉群联系上游owner明确调用是否合理。
Q1:超时导致的限流问题。
A1:同RT类问题相同的排查治理思路。

【辅助定位以及变更托管可能性】
● 识别应用的报错是由于限流导致,还是由于其他原因导致。可以通过hsf日志、sentinel日志、noha日志辅助分析。

HSF线程池满

【人工排查手段】

  1. 登录线程池满的机器。
  2. 分析hsf线程池满的堆栈日志。
  3. 主动做jstack操作,同时关注线程数。
  4. 分析jstack日志。

【可能的原因以及人工解决方案】
Q1:内部存在锁等待(多个线程等待同一个锁,常见于日志打印相关)。
A1: 解决锁等待的问题,常见的方式日志异步化,日志升级等,实际处理的方式依据原因会有变化。

Q2:线程依赖的下游RT升高,造成内部多线程等待。
A2:多为下游服务的问题,但下游服务引起本身的线程池满,一方面可能是业务本身的RT设置不合理导致;另一种可能是业务自身超过承接水位的上限;【可以根据是单机问题,还是全局问题来判断】。

【辅助定位以及变更托管可能性】
● 使用jstack的辅助分析工具,分析jstack的格式,识别锁等待,以及工作线程的情况。
● 使用日志配置标准化工具,主要解决日志异步化配置改造、日志版本升级、日志配置转换(log4j->log4j2, log4j -> logback )。
● 代码变更工具:调整HSF consumer的超时时间、调整Tair的超时时间、调整Http的超时时间。

CodeCache使用率、Metaspace利用率、堆外内存利用率

【人工排查手段】

  1. 分析sunfire的监控数据,观察利用率是否会存在下降的趋势。
  2. CodeCache的利用率、CodeCache的使用量、CodeCache的最大值、Metaspace的配置值。
  3. 比较相关配置值的合理性。
  4. codecache、metaspace dump 分析。

【可能的原因以及人工解决方案】
Q1:JVM参数不合理导致的利用率报警。
A1:调整JVM的参数,适当配置Metaspace、CodeCache、堆利用率。

Q2:应用代码不合理,导致大量的类加载问题,比如Groovy、Json、反射等。
A2:分析Dump内容,识别占比较大的类的合理性、利用堆栈、代码增强等手段抓到运行过程中新增类加载的堆栈;分析对应堆栈的合理性以及优化方案。

Q3:类加载均是合理的诉求,单纯空间配置不合理。
A3:人工分析、根据应用的历史分析、占比分析确认合理诉求,调整JVM参数配置;提升规格;应用包治理。

【辅助定位以及变更托管可能性】
● 使用系统监控分析工具,分析Codecache、Metaspace、堆外内存利用率的数据。
● 使用JVM参数建议工具,如何提供一个合理准确的建议参数是一个比较大的挑战(根据应用的历史运行情况进行分析确定的值,根据类似应用的参数配置情况,参数缺失的场景)。
● 使用代码临时增强工具,可以利用arthas抓取相应的数据classloader、stack、jad;并对结果进行分析。
● 使用dump分析工具,比如Metaspace、CodeCache 这类工具需要有历史记录的对比,同应用不同机器的对比功能。
● 以及使用其他规格升级、包治理相关的配套工具。

GC类问题

【人工排查手段】

  1. 分析GC日志,观察GC频率、GC的原因、GC前后的堆空间变化。
  2. 分析监控数据,观察GC频率、JVM相关指标数据。
  3. Dump堆,并上传到Grace上进行分析。

【可能的原因以及人工解决方案】
Q1:堆外内存、Metaspace、CodeCache等导致的GC产生。
A1:参考对应利用率的应对办法。GC日志里会有相关的提示(Metaspace、System.gc等)。

Q2:常驻对象过多,导致的GC频率增加;对应的现象是GC前后堆存活兑现差异不大。
A2:根据常见的二三方包堆空间占用大小的数据可以判断是否具备治理条件,如果具备治理条件,推动治理;如果确认为内部缓存需要,则需要调整参数,甚至升级规格。

【辅助定位以及变更托管可能性】
● 通过分析常见二三方包堆空间占用大小数据,在分析Grace的结果时,可以沉淀起来。
● 使用系统监控分析工具,分析JVM相关的指标,以及报警前后的数据。
● 使用Dump分析工具,可以调用Grace的接口,拿到泄露建议、支配树分析、OQL表达式。

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------