aoao-linux性能问题排查

  1. 排查步骤
  2. 分析结果
  3. 总结

系统很卡-CPU一直长期处于100%的状态

排查步骤

  1. 登录服务器,查看CPU占用最高的所在进程,执行top -c,发现是 java 程序导致CPU飚高;

  2. 查看服务器日志,是否是因为请求量过大和机器性能不行,查看后不是这原因,于是进行下一步;

  3. 由于采用的是docker部署,所以宿主机查看 pid 无法定位具体问题,这里直接采用 arthas 定位到具体的问题;

  4. docker stats 查看容器CPU占用最高的,然后使用docker exec -it {容器id} /bin/bash 进入容器

  5. 由于 docker 安装都是最小化镜像,没有jdk环境,只有jre运行环境,无法执行类似于 jps 命令,所以先临时在docker容器中安装个jdk,然后启动 arthas 进行排查;

  6. 安装jdk和启动arthas命令步骤如下:

    复制

    # 下载jdk
    wget https://mirrors.huaweicloud.com/java/jdk/8u202-b08/jdk-8u202-linux-x64.tar.gz
    # 解压
    tar -zxvf jdk-8u202-linux-x64.tar.gz
    # 下载 arthas
    wget https://arthas.aliyun.com/arthas-boot.jar
    # 启动  arthas
    ./jdk-8u202-linux-x64/bin/java -jar arthas-boot.jar
    
  7. 执行 thead -n 3 查看cpu最忙的3个线程,记录下pid;

  8. 继续执行 thead pid号,定位到具体的代码,我这里的日志如下:

    复制

    [arthas@1]$ thread 5781
    "http-nio-8080-exec-211" Id=5781 RUNNABLE
        at java.util.regex.Pattern$CharProperty.match(Pattern.java:3778)
        at java.util.regex.Pattern$Branch.match(Pattern.java:4606)
        at java.util.regex.Pattern$GroupHead.match(Pattern.java:4660)
        at java.util.regex.Pattern$Loop.match(Pattern.java:4787)
        at java.util.regex.Pattern$GroupTail.match(Pattern.java:4719)
        at java.util.regex.Pattern$BranchConn.match(Pattern.java:4570)
        at java.util.regex.Pattern$CharProperty.match(Pattern.java:3779)
        at java.util.regex.Pattern$Branch.match(Pattern.java:4606)
        at java.util.regex.Pattern$GroupHead.match(Pattern.java:4660)
        at java.util.regex.Pattern$Loop.match(Pattern.java:4787)
        at java.util.regex.Pattern$GroupTail.match(Pattern.java:4719)
        at java.util.regex.Pattern$BranchConn.match(Pattern.java:4570)
        at java.util.regex.Pattern$CharProperty.match(Pattern.java:3779)
        at java.util.regex.Pattern$Branch.match(Pattern.java:4606)
        at java.util.regex.Pattern$GroupHead.match(Pattern.java:4660)
        at java.util.regex.Pattern$Loop.match(Pattern.java:4787)
        at java.util.regex.Pattern$GroupTail.match(Pattern.java:4719)
        at java.util.regex.Pattern$BranchConn.match(Pattern.java:4570)
        at java.util.regex.Pattern$CharProperty.match(Pattern.java:3779)
    

分析结果

根据排查的结果发现是因为正则匹配的时候循环浪费的资源,这个正则表达式代码只有在一个接口中做前置判断有用到,就快速定位到了是正则表达式的问题,查阅相关资料和询问ChatGPT后,大概确定问题就是因为正则表达式不规范导致循环进行失控模式,分析参考文章链接,感兴趣的可以点进去看下,最后采用修改正则表达式然后重新发布服务CPU使用恢复正常。

总结

在本次操作过程中,遇到了很多问题坑,很多参考文章都是基于linux的指令和借助jstack、jps命令来排查,然后也不是针对于容器内的java程序进行排查,并且容器对应的pid和宿主机对应的pid不是一回事,所以只有靠定位到具体容器,进入容器再进行排查,一般容器使用的基础镜像为了保证足够精简,所以常常命令也是太简单,所以需要临时安装一些环境,这里推荐给大家arthas这款工具确实能够大大减少针对java程序排查问题的复杂度。

最后还是要提醒多久爱,写正则表达式参考网上的很可能有问题,使用前还是多斟酌,以免出现类似的线上问题。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 xieaoao@qq.com QQ:1296454177

×

喜欢就点赞,疼爱就打赏