今天忽然有用户反馈各个端都不能使用咱们的产品了,出于经验,应该是和最近的一次上线有关,最近的一次上线是升级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