差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

下次修改
前次修改
java:basic:httpurlconnection:readblockingissue [2018/03/21 21:09]
tony 建立
java:basic:httpurlconnection:readblockingissue [2023/06/25 09:48] (目前版本)
行 2: 行 2:
 ====== Read Blocking of the HttpsURLConnection ====== ====== Read Blocking of the HttpsURLConnection ======
 ===== Problem ===== ===== Problem =====
 +這故事發生在某天service狀態顯示為啟動中,但卻沒執行該執行的工作。後來將heap dump出來,從thread list中看到以下狀況:​\\ 
 +{{:​java:​basic:​httpurlconnection:​read_blocking_of_httpsurlconnection.png|}}\\ 
 +我們的URLConnection是有設定timeout的:​ 
 +<code java> 
 +URLConnection conn = url.openConnection();​ 
 +conn.setConnectTimeout(connectionTimeout);​ 
 +conn.setReadTimeout(readTimeout);​ 
 +</​code>​ 
 +為什麼service已經執行好幾天了,還會存在理應timeout的連線呢?​
 ===== How to resolve? ===== ===== How to resolve? =====
 +從call stack中去查看java原始碼可以發現,在sun.net.www.protocol.https.HttpsClient.afterConnect中,會使用SSLSocketFactory去建立socket並且做handshake,期間並沒有設定readTimeout;如果http server並沒吐訊息或自動中斷連線,就有可能造成client程式block住。在這種情況下,即使你做中斷也沒用。\\ 
 +目前我們解決的方式是透過一個wrapper SSLSocketFactory,去設定default timeout: 
 +<code java> 
 +private Socket setDefaultProp(Socket socket) throws SocketException{ 
 + socket.setSoTimeout(readTimeout);​ 
 + return socket; 
 +
 +  
 +@Override 
 +public Socket createSocket(Socket aS, String aHost, int aPort, boolean aAutoClose) throws IOException { 
 + return setDefaultProp(mSocketFactory.createSocket(aS,​ aHost, aPort, aAutoClose));​ 
 +
 +</​code>​ 
 +而HttpsURLConnection會設定我們自己的SSLSocketFactory:​ 
 +<code java> 
 +HttpsURLConnection sslconn = (HttpsURLConnection) conn; 
 +sslconn.setSSLSocketFactory(mySSLSocketFactory);​ 
 +</​code>​
 =====    ===== =====    =====
 ---- ----
 \\ \\
 ~~DISQUS~~ ~~DISQUS~~