1、thrift無(wú)法判斷連接失效
問(wèn)題
使用thrift進(jìn)行內(nèi)部服務(wù)調(diào)用時(shí),一般使用連接池的方式來(lái)減少連接頻繁創(chuàng)建銷(xiāo)毀產(chǎn)生的開(kāi)銷(xiāo)。thrift是無(wú)法判斷連接是否有效的。
thrift判斷是否有效。判斷連接是否有效,使用TTransport類(lèi)的isOpen()函數(shù)進(jìn)行判斷,isOpen()函數(shù)的源碼中使用了jdk中Socket類(lèi)的isConnected()方法判斷。
jdk源碼如下:
/**
* Returns the connection state of the socket.
*
* Note: Closing a socket doesn't clear its connection state, which means
* this method will return {@code true} for a closed socket
* (see {@link #isClosed()}) if it was successfuly connected prior
* to being closed.
*
* @return true if the socket was successfuly connected to a server
* @since 1.4
*/
public boolean isConnected() {
? ? // Before 1.3 Sockets were always connected during creation
? ? return connected ||oldImpl;
}
所以,isConnected方法得到的并不是Socket的當(dāng)前連接狀態(tài),而是只要是Socket連接曾經(jīng)成功過(guò),isConnected始終返回true。
thrift并沒(méi)有提供一個(gè)可以獲取當(dāng)前連接狀態(tài)的方法。
解決方案
? ? 1、連接池中對(duì)象的active時(shí)間與server端的socket超時(shí)一致,避免獲取到被關(guān)閉的連接(我們使用的方案)。
? ? 2、遠(yuǎn)程調(diào)用操作失敗后,講失敗狀態(tài)寫(xiě)入當(dāng)前客戶(hù)端變量,下次校驗(yàn)時(shí),查看此變量,獲取連接狀態(tài),銷(xiāo)毀重連。這樣導(dǎo)致的結(jié)果是異常連接總會(huì)失敗一次,當(dāng)連接池中緩存的異常連接過(guò)多,會(huì)造成過(guò)多的業(yè)務(wù)請(qǐng)求失敗。
? ? 3、各個(gè)服務(wù)thrift服務(wù)端統(tǒng)一新增接口函數(shù)ping(),不做任何操作,用來(lái)進(jìn)行連接池校驗(yàn)。