20160229日某農商行由於FTP下載功能有問題,致使當天全部涉及FTP文件下載的交易都不能正常使用,對於銀行來講影響仍是比較大。現將當天出問題的緣由及處理過程解析以下,忘能給碰到相似問題的同行以供參考。java
當天早上一上班就接到電話有人說信貸系統不少交易用不了,查看日誌都是報的找不到文件,沒法解析。正則表達式
後通過多方人員的共同努力查找和排查,最終確認是ReceiveFileTransfer.java類中的transfer()方法調用Apache組件commons-net-1.4.1.jar的listFiles時返回空問題引發,結合網上結論推斷緣由是目標服務器的中文語言環境,致使文件的修改日期格式,不能被apache正確解析形成的。(2月29)apache
問題緣由是定位到了,當務之急是如何快速讓生產環境恢復正常運行,而不影響平常業務開展。服務器
通過多方討論共提供三種解決方案:測試
一、將目標服務器中當天使用頻繁的交易所生成的文件臨時改到20160228目錄下;優化
二、根據網上處理經驗替換commons-net-1.4.1.jar包中的兩個文件(FTPTimestampParserImplExZH.class、UnixFTPEntryParser.class)spa
三、第2點的變向處理,不改jar包,使用時動態選擇解析類;unix
以上三種方案,當時先用第1種解決燃眉之急,以保證重要交易能正常使用;第2種考慮仍是會存在必定風險,由於該系統使用年數比較舊,jdk版本也比較底,直接修改jar中的內容,一時沒法保證對其它功能沒有影響;因此最後的永久處理方案仍是選擇了第3點。下面就針對這種解決方案作如下詳述:日誌
如下是代碼跟蹤步驟及解決方法:orm
1) 由如下代碼可知,FTP下載前會檢查listFiles()所獲得的fileList.size()是否大於0,只有你們於0的時候纔會調附件下載的方法。
2) 經過反編譯commons-net-1.4.1.jar代碼可知,listFiles()方法調用的是jar中FTPClient.class類的對應方法。(也能夠去官網下載源碼)
3) 再往下追蹤可知,FTPListParseEngine.class這個解析引擎類會針對不一樣系統建立不一樣的解析工廠。
"([bcdlfmpSs-])(((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-])))\\+?\\s+(\\d+)\\s+(\\S+)\\s+(?:(\\S+)\\s+)?(\\d+)\\s+((?:\\d+[-/]\\d+[-/]\\d+)|(?:\\S+\\s+\\S+))\\s+(\\d+(?::\\d+)?)\\s+(\\S*)(\\s*.*)" |
以上正則表達式串,正是爲了匹配unix類系統的文件目錄結構,但存在bug
-rw-r--r-- 1 root system 0 Feb 29 16:19 ECDS_4017692698500000382783.txt |
4) 根據網上建議對該解析類的正則表達式進行優化,但直接反編譯jar包中源代碼不可取,會存在風險;因此採用了相似對該解析類重寫的方式處理,首先在EOS的如下目錄增長兩個java文件。
將UnixFTPEntryParser中正表達式進行優化
5) 再在調用listFiles()方法以前先讓該方法的解析類指向新加的解析類,代碼以下:
6) 爲了對該功能的影響降到最底,故對代碼又作了特殊處理,只有2月29的狀況才調用新加的解析類,其它日期仍是延用以前的代碼。
7) 爲此完成全部改動點總共涉及5個java文件,打包到測試1和測試3初步驗證無問(延用了他原來的工廠類模式)。