記一次線上處理的用戶反饋

今天忽然有用戶反饋各個端都不能使用咱們的產品了,出於經驗,應該是和最近的一次上線有關,最近的一次上線是升級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

相關文章
相關標籤/搜索