Socket發送請求“超時”——接收數據方式引起的bug

Socket發送請求“超時”——接收數據方式引起的bug


一、場景描述

前段時間對接某家銀行的資管外圍系統,測試環境測試通過,聯調報告經銀行風控部門審批通過,上線時出現嚴重問題(不能正常發送/接收請求):發送請求成功、接收數據失敗並拋出SocketTimeoutException。

對接使用的技術:Socket(接觸的兩家銀行(一家股份制商業銀行、一家國有銀行(四大行之一))的外圍系統都是使用Socket,是不是銀行對外接口大多使用Socket?)

二、分析過程

出現問題後,馬上向銀行方技術團隊反饋,希望他們能夠給出一些有效的解決方案;首先要確定的就是他們是否接收到請求,因爲他們沒有權限登錄到服務器查看信息,所以只能第二天去看(正好第二天要去投產),所以約定好投產之後查看日誌確定是否接受到請求(第二天告訴我沒收到我們這邊的請求,表示很無奈);我這邊也跟蹤一下路由,看看網絡通信這些是否正常,使用traceroute命令看時並沒有發現問題,發送/接收都很正常。這時候猜想可能是銀行方給的請求的jar有點小瑕疵。在對接羣裏找其他接入方問問吧,看看他們有沒有出現過類似的問題,我勒個去,除了我 沒人有這問題。

個人感覺代碼的問題應該也不大,但就是不知道問題在哪(後來問銀行的技術團隊,他們的告訴我那個jar(其實就是幾個java文件)後來改過,但是他們手上沒有最新的,要第二天才能給我,找其他對接方要吧,人在出差得回去才能給我)。

沒辦法,只能根據他們說的問題自己改了(原來的接收數據方式比較慢);首先試了下把超時時間加大,從原來的60秒增加到120秒(我的天,一個請求完成大概用了70秒左右),接收數據正常,確定能夠正常發送/接收後,改了下接收數據的方式(先獲取數據長度,再根據長度獲取報文數據)。

三、部分代碼

原來的接收數據處理方式:

				// 接收消息
				BufferedReader socketIn = new BufferedReader(
						new InputStreamReader(sslSocket.getInputStream()));// 接受到的信息
				String rtnStr = "";
				String valueString = "";
				while ((valueString = socketIn.readLine()) != null) {
					rtnStr += valueString;
				}
				if (StringUtils.isEmpty(rtnStr) || rtnStr.length() <= 8) {
					throw new FcsAppException("SDER01", "銀行無應答數據");
				}

更改後的接收數據處理方式:

				// 接收消息
				BufferedReader socketIn = new BufferedReader(
						new InputStreamReader(sslSocket.getInputStream()));// 接受到的信息
				char[] messageLenChars = new char[XML_MESSAGE_LENGTH];
				socketIn.read(messageLenChars);
				int dataLen = Integer.valueOf(new String(messageLenChars));// 先獲取報文長度
				String rtnStr = "";
				if (dataLen > 0) {
					char[] dataChars = new char[dataLen];
					socketIn.read(dataChars);
					rtnStr = new String(dataChars);
				}
				if (StringUtils.isEmpty(rtnStr) || rtnStr.length() <= 8) {
					throw new FcsAppException("SDER01", "銀行無應答數據");
				}

三、總結

測試環境使用的是Socket

正式環境使用的是SSLSocket


使用readLine時,連接正式環境出現SocketTimeoutException,可能是外圍資管系統響應數據後沒有主動結束,導致已知等待;已知數據長度,直接使用read(char[])讀取數據,避免等待。



發佈了26 篇原創文章 · 獲贊 15 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章