记一次线上处理的用户反馈

今天忽然有用户反馈各个端都不能使用咱们的产品了,出于经验,应该是和最近的一次上线有关,最近的一次上线是升级java版本,1.6->1.8。java

按照用户反馈,马上去线上grep各个机器这个用户的错误日志,未果;跟用户要客户端的本地日志,一样没有发现问题,遂进一步联系用户,开fiddler抓包,看看服务器究竟返回了什么,抓包后,发现返回的是:unknown exception,这下不淡定了,这个异常通常是没有捕获致使的,因此在线上也没有grep到任何详细的日志。算法

后来,又仔细研究用户日志,发现用户始终在作同一个操做,并且各个端都不能用,而后根据用户刚才的操做,定位到具体的机器上,查看该用户的操做记录,根据时间和处理线程编号,定位到如下错误异常:服务器

Caused by: java.lang.IllegalArgumentException: Comparison method violates its general contract!
        at java.util.TimSort.mergeLo(TimSort.java:777)
        at java.util.TimSort.mergeAt(TimSort.java:514)
        at java.util.TimSort.mergeCollapse(TimSort.java:441)
        at java.util.TimSort.sort(TimSort.java:245)
        at java.util.Arrays.sort(Arrays.java:1512)
        at java.util.ArrayList.sort(ArrayList.java:1454)
        at java.util.Collections.sort(Collections.java:175)

定位到错误,google以后,处理起来就很快了。测试

**出错缘由:**JDK7之后的版本中排序的Collections.Sort排序算法改为了TimSort,这个算法要求,若是两个值是相等的,那么compare方法须要返回0,不然可能会在排序时抛错,而JDK6是没有这个限制的。google

另外,因为用户操做是带有事务的,在事务的最后,有个排序,排序出错后,事务回滚,致使操做失败,因此日志中看到日志是用户在作同一个操做,代码中对这个异常没有进行捕获打印详细信息,因此很难定位。线程

这个问题在测试的时候没有反应出来,线上也是小几率复现日志

搜了全部的项目代码,找到相关的代码,进行了修改,联系用户,各个端均恢复正常。code

代码修改

关于TimSort的详细信息,能够参考这个: http://blog.2baxb.me/archives/993blog

相关文章
相关标签/搜索