服务器cpu占用100%分析---jdk的Pattern臭虫

背景描述

服务器在一个晚上的时间cpu从2%彪到100%,本身是8核的cpu,load average彪到了12多。内存,连接数,流量都没有明显变化。

问题分析

从显现来看,单纯的cpu变高,比较明显的知道应该是程序的某一个线程或者多个线程有个死循环,直接跑满。通过top可以看下是哪个服务
输入
top

之后,可以用shift+h显示出最高使用的进程

服务器cpu占用100%分析---jdk的Pattern臭虫_第1张图片



可以分析出:252963这个java进程使用cpu最高,但是分析到这里没有用,因为我们要找到这个进程里面的某个线程的占用情况,然后结合jstack进行分析。

使用命令:
ps mp 252963 -o THREAD,tid >ps.log 

   可以得到类似:
服务器cpu占用100%分析---jdk的Pattern臭虫_第2张图片

这就是这个进程里面的线程的情况,如果要分析,知道cpu占用率和最后的tid,用如下命令:

awk '{print $2,$8}' ps.log  | sort | uniq -c | sort -nr >s.log  
能统计出最高cpu的tid,如下:
服务器cpu占用100%分析---jdk的Pattern臭虫_第3张图片

拿到占用cpu最高的tid:224805,。后续我们会用到这个id

我们拿到这个线程id后,我们如果想找到这个线程的情况,就需要jdk的jstack命令进行分析:
具体jstack的格式不做赘述,只说下跟这回分析有关的东西

执行:
jstack -l 252963 > stack.log
查看stack.log会在开头看到如下图一些线程

服务器cpu占用100%分析---jdk的Pattern臭虫_第4张图片

其中attach listener并不是我们关注的进程,我们需要关注一些用户级别的线程,而不是jvm线程,大部分时候我们需要关注的线程是下面的resin-442之类的用户线程

当拿到stack.log的时候是不是觉得很大,不知道无从下手,不要慌,在这里只需要找到有问题的线程就可以了,有问题的线程就是上面辛辛苦苦拿到的tid:224805
但是,在stack文件中并不会表示这个id,他是以这个id的16进制展示的,tid:224805的16进制--36e25,搜索这个key,会找到:
服务器cpu占用100%分析---jdk的Pattern臭虫_第5张图片

其中nid就是tid的16进制,ok,找到这个stack信息后就可很清晰的发现时Pattern这里死循环了。

解决问题:Pattern臭虫Or正则效率Or真的需要那么复杂的正则?

发现这个问题之后,会在这个log下面找到自己的代码所使用正则的地方。
上网查下这个bug,会发现基本描述的是一样的,是在某种特殊的正则的情况下会出现这个bug,至今jdk没有修复这个问题,
具体这个问题怎么复现网上查下,有很多,这里不做重点,但是基本都是有个共同点,就是“|”这个正则符号的祸,
sun公司当初有个回答是,并不是正则的bug,而是使用正则的人的正则表达式太过复杂,太过奇葩。
比如:1到5或者5-9,不如直接写成1-9,类似于这种奇葩正则所导致的问题。

所以,我这里的建议是:
1:先要考虑是否一定要用正则?
  比如,这回我们出现的问题是在邮箱的正则表达式上,我们会验证邮箱格式,然后给这个邮箱发邮件进行验证。那么问题就出来了。既然要发邮件验证,为什么要验证邮箱格式那?
2:正则尽量简化:
我不是一个正则的牛人,所以就不在这个多说,如果要写正则,尽量写的简洁一些,规范一些是没有错的,不要出现上述奇葩问题

3:不用正则,用其他方式验证
像验证邮箱其实也没有必要用正则,直接验证有没有@,有没有点,有没有奇葩符号,在验证下顺序就ok了,也可以跳过正则的。

你可能感兴趣的:(Business,Technology,Sharing,cpu跑满,pattern,死循环,100)