赞
踩
java应用线上一般会出现什么问题?一般可以分为业务上的问题,还有系统上的问题。常见的情况:
比如:找不到服务、业务异常报错、运行时异常报错
比如内存溢出、内存泄漏、CPU飙升、磁盘IO居高、磁盘空间不足、网络IO突然升高、线程资源不够。
这里主要是出现资源问题的分析。
一个JAVA应用是通过JVM运行在操作系统上(当然有一些还部署在类似tomcat这种容器中)。所以涉及的资源本身有:
JVM的资源:堆栈内存、线程、创建的异步队列等相关资源
操作系统:CPU、内存、磁盘、网络、磁盘空间等指标
外部依赖:跟外部中间件相关的连接池、及外部中间件:如数据库、redis等
第三方依赖:依赖外部第三方的系统服务。
1、主动发现:相关owner每天查看系统监控情况,主动发现了一些异常的现象。
2、拨测:通过定时对应用进行连通性测试,如果发现服务不可用时进行告警;一般这种主要针对依赖的第三方系统服务
3、监控系统告警:应用上线的时候,需要对这些资源进行监控,建立监控指标,如果超过指标时进行告警。比如应用响应时间在某个时间段上升了,资源层面cpu、内存、io、tcp连接数、disk、线程数、GC、连接池等各个服务器指标异常,可能是某台的服务器出现了异常,但是业务还未受到大面积影响
4、人工发现:客户反馈
1、系统本身:cpu、内存、io、tcp连接数、disk空间、线程数,等指标
2、应用:GC次数、数据库连接池,常见日志Error比如OutOfMemoryError
3、中间件依赖:中间件的状态、中间件服务器的CPU、内存、磁盘等指标
4、数据库层面:慢sql日志,锁日志,RO延迟等等。
5、Redis:redis的状态、cpu、内存容量、磁盘容量
6、外部依赖:服务状态、cpu、内存、磁盘等
对于7*24小时的应用一般都需要快速恢复服务,留给排查的时间窗口其实不多,很可能需要最短时间内重启应用,所以需要快速保留现场,比如dump。
如果有多个运维的话,可以进行分组配合:(切流量抓快照、重启应用、线上分析、迅速限流)
怎么利用工具快速定位问题:
操作系统命令:free、top、netstat
常用的jvm命令:jstack、jmap、jstat
工具的使用:mat、gcviewer
在线运维工具:arthas
日志及监控:skywalking、elk
最慢:关注慢交易、慢sql等相关指标;可以通过skywalking或者其他监控工具发现
最多:关注线程数很多的交易,如果同个交易线程数特别多,那可能问题出现在线程方面;可以通过jstack的堆栈日志进行分析。
最高:占用CPU最高的线程,一般是通过top,top -Hp pid的方式,配合jstack日志进行分析。一般如果CPU占比不是GC线程,而是业务线程;那最有可能是当前的交易产生的问题。
最大:占用内存最多的对象或者线程,CPU是比较容易捕获的信息,内存对象一般需要dump,而且需要内存分析工具才能查看,所以最好能快速判断,然后进行dump日志,最后采用mat、或者gcviewer进行分析。VM启动参数最好也指定gc日志及出现内存溢出时生成dump文件。
1、限流:当定位到某个交易出现异常的时候,针对该交易进行限流,可以避免故障进行蔓延。
2、隔离:对于没办法快速优化、而又需要持续在线的服务,可以抽离出来单独部署,进行故障隔离。
3、优化:对功能分析进行优化,同时进行压测,避免重复问题出现。
线上很多突如其来的意外,往往都带着必然性。比如:功能迭代越来越复杂,接口越来越慢;线上的容量在快速增长是不是被忽视了,大客户的报表功能是否有做过压测,在线上有没有分析过sql性能等等。
所以在日常对系统的健康情况需要不定时巡检,可以的话就做成自动化脚本。比如:慢接口的监控、慢sql的监控、redis大key的梳理、交易量增速的监控、数据库表数据量监控等。
开发过程中,需要对每个交易的设计方案进行评审,同时对交易的流量进行预估,对流量较大的交易在上线前需要进行压测。
1、动态条件查询未做非空判断,load出全表数据,导致内存溢出,引起CPU占用100%并引发事故
2、生成树形结构数据时,结果parentID等于自己导致循环查数据
3、while(true)循环没有退出条件
4、慢sql引起数据库上升,其他sql挂起,系统短时不可用
5、外调第三方服务没有加超时时间,导致线程数爆掉
6、Redis节点容量不够导致业务异常
7、使用一些性能不好的API,比如POI的XLS,生成excel文件数据量过大时,很容易就CPU暴涨。
最后欢迎读者在评论区留下你们遇到过的线上问题及分析思路。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。