2017-11-02 14 views
0

私は、以下のメソッドが多数のスレッド(約300)によって並列に実行されるマルチスレッドのJavaアプリケーションを実行しています。そして、スレッド数が50よりも少ない場合にのみ、スレッド数が多い場合にこの例外が表示されます。 stackoverflowでいくつかのポストを読み、コードが何の説明文に苦情を出していますか。どんな助けもありがとう。前もって感謝します。java.net.SocketException:ソケットクローズイベント入出力ストリームが読み込み後に閉じているが、書き込み

public static String invokeWebService(String request, String fwfmId, BatchVO batchVO){ 
    String responseString = ""; 
    //log the request string 
    Logger_trace.info("Service request for input "+ fwfmId +":: "+CommonUtil.removeCrLf(request)); 
    try { 
      URL url = new URL(batchVO.getWebServiceUrl()); 
      HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); 
      urlConnection.setRequestMethod("POST"); 
      urlConnection.setRequestProperty("Content-type", "text/xml; charset=utf-8"); 

      urlConnection.setDoOutput(true); 
      urlConnection.setDoInput(true); 
      urlConnection.setConnectTimeout(Integer.parseInt(batchVO.getConnectionTimeOut())); 
      urlConnection.setReadTimeout(Integer.parseInt(batchVO.getReadTimeOut())); 
      OutputStream outputStream = urlConnection.getOutputStream(); 
      outputStream.write(request.getBytes()); 
      outputStream.flush(); 

      //get response form input stream and convert into string 
      InputStreamReader inputStreamReader = new InputStreamReader(urlConnection.getInputStream()); 
      BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 
      String inputLine; 
      StringBuffer response = new StringBuffer(); 

      while ((inputLine = bufferedReader.readLine()) != null) { 
       response.append(inputLine); 
      } 

      responseString = response.toString(); 

      //close resources 
      bufferedReader.close(); 
      inputStreamReader.close(); 
      outputStream.close(); 

      //log the response string 
      logger_trace.info("Service response for input "+ fwfmId +":: "+ CommonUtil.removeCrLf(responseString)); 

      //Update Database columns 
      updateRecordInTable(request, responseString, fwfmId, batchVO.getDataSource(), batchVO.getBatchId());  

     } catch (SocketConnectException e) { 
      logger_trace.error("WebserviceHandler.invokeWebService : SocketConnectException block : "+fwfmId +" ", e); 
      updateRecordInTableWithTimeout(fwfmId, batchVO.getDataSource(), batchVO.getBatchId()); 
     } catch (SocketTimeoutException e) { 
      logger_trace.error("WebserviceHandler.invokeWebService : SocketTimeoutException block : "+ fwfmId+" ", e); 
      updateRecordInTableWithTimeout(fwfmId, batchVO.getDataSource(), batchVO.getBatchId()); 
     } catch (MalformedURLException e) { 
      logger_trace.error("WebserviceHandler.invokeWebService : MalformedURLException block : ", e); 
     } catch (IOException e) { 
      logger_trace.error("WebserviceHandler.invokeWebService : IOException block : ", e); 
     } catch(Exception e){ 
      logger_trace.error("WebserviceHandler.invokeWebService : General Exception block : ", e); 
     } 
     return responseString; 
    } 

例外::興味深い

[ERROR] 2017-10-31 03:18:54,435 [main] TRACE - 
WebserviceHandler.invokeWebService : IOException block : 
java.net.SocketException: Socket Closed 
     at java.net.AbstractPlainSocketImpl.setOption(AbstractPlainSocketImpl.java:212) 
~[?:1.8.0_131] 
     at java.net.Socket.setTcpNoDelay(Socket.java:980) ~[?:1.8.0_131] 
     at weblogic.net.http.HttpClient.openServer(HttpClient.java:411) 
~[wlfullclient.jar:12.2.2.0.0] 
     at weblogic.net.http.HttpClient.openServer(HttpClient.java:511) 
~[wlfullclient.jar:12.2.2.0.0] 
     at weblogic.net.http.HttpClient.New(HttpClient.java:313) ~[wlfullclient.jar:12.2.2.0.0] 
     at weblogic.net.http.HttpURLConnection.getHttpClient(HttpURLConnection.java:314) 
~[wlfullclient.jar:12.2.2.0.0] 
     at weblogic.net.http.HttpURLConnection.getInputStream(HttpURLConnection.java:760) 
~[wlfullclient.jar:12.2.2.0.0] 
     at weblogic.net.http.SOAPHttpURLConnection.getInputStream(SOAPHttpURLConnection.java:41) 
~[wlfullclient.jar:12.2.2.0.0] 
     at ca.bell.webservice.WebServiceHandler.invokeWebService(WebServiceHandler.java:56) 
[MigrationTool.jar:?] 
     at ca.bell.webservice.ExecuteMigrationWork.performRun(ExecuteMigrationWork.java:40) 
[MigrationTool.jar:?] 
     at ca.bell.workmanagement.work.Work.call(Work.java:155) [MigrationTool.jar:?] 
     at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_131] 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
[?:1.8.0_131] 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
[?:1.8.0_131] 
     at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131] 

答えて

0

は、ここに私の方法です。例外の最も近いソースから始めて、スタックトレースの分析から始めましょう。 AbstractPlainSocketImplsource codeから施行最初の前提条件があり、:

public void setOption(int opt, Object val) throws SocketException { 
    if (isClosedOrPending()) { 
    throw new SocketException("Socket Closed"); 
    } 
... 

あなたHttpURLConnectionの範囲は、法invokeWebServiceに制限されているので、我々はソケット上の同時行動の仮説を排除し、罰金だので、することができます何この分析では疑問があるが、なぜある

public boolean isClosedOrPending() { 
    /* 
    * Lock on fdLock to ensure that we wait if a 
    * close is in progress. 
    */ 
    synchronized (fdLock) { 
     if (closePending || (fd == null)) { 
      return true; 
     } else { 
      return false; 
     } 
    } 
} 

:方法とソケットを閉じていないが、私はソケットのファイルディスクリプタがnullisClosedOrPending戻りtrueであるため、と信じています10ファイル記述子はnullです。しかし、これは現時点では重要ではありません。私たちが前提を信じなければならないのは、あなたのシステムが処理する接続が非常に多く作成されているということです。

どうすれば解決できますか?ここで少し前に戻り、コードをリファクタリングして同時接続数を制限できるかどうかを確認する必要があります。他に無限である設計候補を絞り込むためには、具体的な実装の詳細をもっと必要とします。例えば、接続プールは適切でしょうか?私たちは背圧をかけてクライアントを絞るべきでしょうか?我々は水平に拡大して負荷を分散すべきか?

+0

ありがとうございます。私の必要条件は、Webサービスレスポンスに基づいて、DBからデータを読み取り、Webサービスリクエストを作成し、サービスを呼び出し、ステータス(成功/失敗)でDBを更新するマルチスレッドのJavaツールを実装することです。これを実装するために、私はThreadPoolExecutorフレームワークを使用しました。プロパティファイルからコアと最大スレッドサイズを動的に取得し、各WebサービスリクエストのworkItemを作成し、各workItemのinvokeWebservice()を呼び出します。 – user1510335

+0

ありがとう@ user1510335 - 負荷を分析するのに役立つさまざまなメトリックについて知りたいのですが、1秒あたりの中央値/ピーク要求(または分)は何ですか?あなたのスレッドプールのサイズは何ですか?どのように使用しますか?クライアントの要求が処理される前にキューに入れられますか? –

+0

こんにちはアレックス、1秒あたりのピークリクエスト数は約400で、最大スレッドサイズも400に設定されています。スレッド数を最大にしてスレッドを管理する明示的なコードがない場合、フレームワーク(ThreadPoolExecutor)がリクエストを待ちます。 – user1510335

関連する問題