推广 热搜: csgo  vue  angelababy  2023  gps  新车  htc  落地  app  p2p 

curl命令java_Java 应用线上问题排查思路、工具小结

   2023-07-11 网络整理佚名2290
核心提示:阿里开源的现在已经几乎包揽了我们线上排查问题的工作,提供了一个很完整的工具集。一个常常被讨论的问题(惯性思维)是在生产环境中GC日志是否应该开启。的)命令,然后使用MAT、、等可视化内存分析工具。上述前两种问题的排查办法,一般都是通过查看日志或者一些监控组件。应用线上排查实际非常考究一个人基础是否扎实、解决问题能力是否过关。

本文总结了一些Java应用在线常见问题的定位步骤。 分享的主要目的是让接触网上问题较少的同学有一个预认知,以免遇到实际问题时手忙脚乱。 毕竟作者本人也是从匆忙的时代走过来的。

这里只是提醒一下。 请记住,在线应急过程中,总体目标只有一个:“尽快恢复服务,消除影响”。 无论处于哪个紧急阶段,我们首先要考虑的是恢复问题。 恢复问题不一定能定位问题,也不可能有完美的解决方案。 可能是凭经验判断,也可能是预设的开关等,但可能会让问题变得更糟。 我们达到快速恢复的目的,然后保留部分站点,然后再去定位问题,解决问题,复查磁盘。

好的,现在让我们言归正传。

1. CPU 利用率高/激增❝

注:CPU使用率是衡量系统繁忙程度的重要指标。 但“CPU 使用率的安全阈值是相对的,取决于你的系统是 IO 密集型还是计算密集型。” 一般来说,计算密集型应用的CPU占用率高、负载低,而IO密集型应用则相反。

“常见原因:”

模拟

这里为了演示,用最简单的死循环来模拟CPU飙升的场景。 以下是模拟代码,

在最简单的Web项目中添加这个类,


@Component
public class CpuReaper {
    @PostConstruct
    public void cpuReaper() {
        int num = 0;
        long start = System.currentTimeMillis() / 1000;
        while (true) {
            num = num + 1;
            if (num == Integer.MAX_VALUE) {
                System.out.println("reset");
                num = 0;
            }
            if ((System.currentTimeMillis() / 1000) - start > 1000) {
                return;
            }
        }
    }
}
复制代码

打包成jar后,在服务器上运行。 java -jar cpu-.jar &

第一步:定位有问题的线程 方法一:传统方法 top 定位CPU最高的进程 执行top命令,查看所有进程占用系统CPU的顺序,定位是哪个进程造成的。 在本例中,它是我们的 java 进程。 PID 列是进程号。 (不清楚指标含义的请参见【附录】) top -Hp pid 定位CPU最高的线程 '0x%x' tid 将线程id转换为16进制

   > printf '0x%x' 12817
   > 0x3211

PID | grep tid 查找线程堆栈

   > jstack 12816 | grep 0x3211 -A 30

方法b:show-busy-java-

这个脚本来自之前的开源项目,该项目提供了很多有用的脚本,show-busy-java-就是其中之一。 使用这个脚本,可以直接简化方法A中繁琐的步骤。 如下,

> wget --no-check-certificate https://raw.github.com/oldratlee/useful-scripts/release-2.x/bin/show-busy-java-threads
> chmod +x show-busy-java-threads
> ./show-busy-java-threads

show-busy-java-threads
# 从所有运行的Java进程中找出最消耗CPU的线程(缺省5个),打印出其线程栈
# 缺省会自动从所有的Java进程中找出最消耗CPU的线程,这样用更方便
# 当然你可以手动指定要分析的Java进程Id,以保证只会显示你关心的那个Java进程的信息
show-busy-java-threads -p <指定的Java进程Id>
show-busy-java-threads -c <要显示的线程栈数>

方法c:

阿里开源现在几乎接管了我们在线排查工作,提供了一套非常完整的工具。 在这种场景下,只需要一个-n命令即可。

> curl -O https://arthas.gitee.io/arthas-boot.jar # 下载

需要注意的是, 的 cpu 比率与前面两种 cpu 比率统计方法不同。 前两个针对的是从Java进程启动到现在的CPU占用率。 这是一个采样间隔内当前JVM中每个线程占用的CPU时间占总CPU时间的百分比。

详情见官网:..io/artha s/.html

❞ 后续行动

通过第一步之后,找到有问题的代码之后,观察线程堆栈之后。 我们“需要根据具体问题具体分析”。 这里有一些例子。

情况1:发现GC线程占用CPU最高。

GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007fd99001f800 nid=0x779 runnable
GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007fd990021800 nid=0x77a runnable 
GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007fd990023000 nid=0x77b runnable 
GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007fd990025000 nid=0x77c runnabl
复制代码

关于gc的调查有很多,所以我决定稍后单独写一篇。

情况2:发现业务线程占用CPU最多。 2.频繁GC 1.回顾GC流程

在理解下面的内容之前,请先花点时间回顾一下GC的整个流程。

接续前面的内容,这种情况下,我们很自然的想到去检查gc的具体情况。

这里对开启gc log进行补充说明。 经常讨论(惰性思维)的一个问题是生产环境中是否应该启用GC日志记录。 因为它产生的开销通常非常有限,所以我的答案是它需要“打开”。 但启动JVM时不需要指定GC日志参数。

JVM 有一类特殊的参数,称为可管理参数。 对于这些参数,它们的值可以在运行时修改。 我们在这里讨论的所有参数以及以“”开头的参数都是可管理的参数。 这样我们就可以随时打开或关闭GC日志。 例如,我们可以使用JDK自带的jinfo工具来设置这些参数,或者通过JMX客户端调用的方法来设置这些参数。

这里再赞一个❤️,它提供的命令可以直接查看和更新​​VM诊断相关的参数。

获取gc log后,可以上传至GC easy帮助分析,获得可视化图表分析结果。

2、GC的原因及部位

” “

从S区提升的对象不能放入老年代(如果fgc回收无效,会抛出OOM)。

可能的原因:

也可以从full GC的效果来推断问题所在。 正常情况下,一次full GC应该回收大量内存,所以“正常的堆内存曲线应该是锯齿形的”。 如果发现full GC后堆内存几乎没有下降,可以推断:“堆中存在大量无法回收的对象,并且在不断膨胀,使得堆使用率超过full GC触发阈值,但无法回收,导致一直执行full GC。”也就是说,可能是“内存泄漏”。

一般来说,GC相关的异常推断需要涉及到“内存分析”,使用jmap等工具转储内存快照(或)命令,然后使用MAT、、等可视化内存分析工具。

至于内存分析之后的步骤,需要根据具体问题来分析。

3.线程池异常

Java线程池以有界队列的线程池为例。 当提交新任务时,如果运行的线程少于2个,则会创建一个新线程来处理该请求。 如果正在运行的线程数等于 ,则将新任务添加到队列中,直到队列满。 当队列满时,会继续开辟新的线程来处理任务,但不能超过。 当任务队列满了,并且已经开启了最大线程数,此时又有新的任务到来,就会拒绝服务。

常见问题及原因

此类线程池异常一般有以下几种原因:

“下游服务响应时间RT过长” 这种情况可能是下游服务异常造成的。 作为消费者,我们需要设置合适的超时时间和熔断降级机制。 另外,针对这种情况,一般需要有相应的监控机制:比如日志监控、监控报警等,不要等到目标用户感觉到异常、从外部反映了问题才去检查日志。 “数据库慢sql或数据库死锁”

查看日志关键字

“Java 代码死锁” –l pid | grep -i –E ' | '

前两个问题的排查方法一般是通过查看日志或者一些监控组件。

4.常见问题恢复❝

这部分内容参考自这篇文章

五,

这里我还是想单独一节来使用这个工具。

它是阿里巴巴开源的Java诊断工具。 基于Java Agent方法,通过该方法修改字节码来进行Java应用诊断。

以上内容摘自官方文档。

另外,它还集成了ognl这个轻量级的表达引擎,通过ognl,你可以用它来实现很多“展示”操作。

其他的我这里就不多说了。 如果有兴趣可以查看官方文档和issue。

6. 涉及的工具

我们来谈谈一些工具。

结语

我知道我的这篇文章对线上异常的总结并不全面,很多异常场景如“网络(超时、TCP队列溢出...)”、堆外内存等都没有涵盖。主要原因是我有接触的很少,也没有深入的了解。 如果强行写出来,几乎毫无意义,而且还怕别人误解。

另外我想说的是,网上考察Java应用其实很讲究一个人的基础是否扎实,解决问题的能力是否良好。 比如线程池运行机制、gc分析、Java内存分析等等,如果基础不扎实的话会比较混乱。 另外,多看网上一些关于异常排查的好的经验文章,这样即使暂时没有遇到,也会在脑海中慢慢总结出一套解决类似问题的结构框架。 当你真正遇到他们的时候,只是类比的问题。

如果这篇文章对你有帮助,希望你能点赞,这就是对我最大的动力

 
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报
Powered By DESTOON