2016-08-05 5 views
1

私はページのコンテンツをスクラップするJavaコードを持っています。私は2500スレッドを実行し、各スレッドはスクラップする100のURLを持っています。すべてのスレッドは正常に実行されますが、例外がスローされることなくスレッドがハングします。生産サーバとしてのubuntuの使用。ラインの下で立ち往生 コード:私は、接続を行うと、時間を読み出しているJava Thread in Multi Threading何時でも例外を投げずにハングします

InputStream in = urlConnection.getInputStream(); 

は、それが効果的です。少数のスレッドでは、読み込みタイムアウトも機能せず、これは永遠にハングします。 私は多くの回避策を試して失敗しました。

私も(アプローチを推奨しない))(Thread.stopを使用して絞首刑スレッドを殺したが、絞首刑スレッドのTCP接続がLinuxサーバに持続します。

java 7325 root 2675u IPv4   284078467  0t0  TCP scrapper-new-instance-2.c.quantum-tracker-93805.internal:37068->104.131.210.5:22225 (ESTABLISHED) 
java 7325 root 2688u IPv4   284077787  0t0  TCP scrapper-new-instance-2.c.quantum-tracker-93805.internal:38132->104.131.210.5:22225 (ESTABLISHED) 
java 7325 root 2723u IPv4   284057771  0t0  TCP scrapper-new-instance-2.c.quantum-tracker-93805.internal:43661->104.131.210.5:22225 (ESTABLISHED) 

どのように私はこのisseをデバッグし修正することができますか?

int counter = 0; 
    int maxAttempts = (config.getProperty("maxAttempts") != null ? Integer.parseInt(config 
       .getProperty("maxAttempts")) : 100); 
    Proxy proxy = null; 
    while (counter < maxAttempts) { 
     try { 
      Type proxyType = Proxy.Type.HTTP; 
      String proxyIP = ""; 
      int proxyPort; 

      int proxyIndex = getRandomNumber(1, httpProxies.size()); 

      if(httpProxies.get(proxyIndex).split(":").length == 4){ 
       proxyIP = httpProxies.get(proxyIndex).split(":")[0]; 
       proxyPort = Integer.parseInt(httpProxies.get(proxyIndex).split(":")[1]); 

       if (httpProxies.get(proxyIndex).split(":").length == 3) { 
        if (httpProxies.get(proxyIndex).split(":")[2].toLowerCase().contains("socks")) 
         proxyType = Proxy.Type.SOCKS; 
       } 
      }else{ 
       counter = counter - 1; 
       throw new Exception("Escapeing for IP --- "+httpProxies.get(proxyIndex)); 

      } 

      URL url = new URL(urlSring); 
      InetSocketAddress inetSocketAddress = new InetSocketAddress(proxyIP, proxyPort); 
      proxy = new Proxy(proxyType,inetSocketAddress); 

      int userAgentIndex = getRandomNumber(1, userAgents.size()); 

      logger.info("Attempt = " + counter + " using proxy " + httpProxies.get(proxyIndex) + " (" + proxyType.name() 
         + ") for url " + urlSring); 

      HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(proxy); 

      if (config.getProperty("connectionTimeoutInMilliSecs") != null) 
       urlConnection 
          .setConnectTimeout(Integer.parseInt(config.getProperty("connectionTimeoutInMilliSecs"))); 
      else 
       urlConnection.setConnectTimeout(CONNECTION_TIMEOUT_VALUE); 

      if (config.getProperty("readTimeoutInMilliSecs") != null) 
       urlConnection.setReadTimeout(Integer.parseInt(config.getProperty("readTimeoutInMilliSecs"))); 
      else 
       urlConnection.setReadTimeout(READ_TIMEOUT_VALUE); 


      System.setProperty("http.agent", ""); 

      urlConnection.setRequestProperty("User-Agent", ""); 
      urlConnection.setRequestProperty("User-Agent", userAgents.get(userAgentIndex)); 
      urlConnection.addRequestProperty("Accept-Encoding", "gzip, deflate, br"); // to avoid server returned http response code 403 
      urlConnection.setInstanceFollowRedirects(true); 

      //Few Thread hang here for ever 
      InputStream in = urlConnection.getInputStream(); 

      if(null != urlConnection.getContentEncoding() && urlConnection.getContentEncoding().equals("gzip")){ 
       in = new GZIPInputStream(in); 
      } 

      String output = IOUtils.toString(in, Charset.forName("UTF-8").name()); 

      logger.info("Proxy Address:-"+proxy.address()+ " HTTP Response Code : " + urlConnection.getResponseCode() + " HTTP Response Message : " 
         + urlConnection.getResponseMessage() + " for url ---" + urlSring); 



      logger.info("Success scraping for url --- "+urlSring+ " --- using proxy --- "+httpProxies.get(proxyIndex)); 
      // Close Input Stream 
      if(in != null){ 
       in.close(); 
      } 

      // Close url connection and release underlying socket if exists. 
      if(urlConnection != null){ 
       urlConnection.disconnect(); 
      } 

      url = null; 
      urlConnection = null; 
      return output; 

     } catch (Exception e) { 
      logger.info(e); 
      counter++; 
      /* 
      * logger.info("Exception : " + e.getMessage() + " while using proxy " + proxy.address() + 
      * ".Trying next proxy."); 
      */ 

      if (config.getProperty("shouldSleepBetweenRequests") != null 
         && config.getProperty("shouldSleepBetweenRequests").equalsIgnoreCase("true")) { 
       Random r = new Random(); 
       int low = config.getProperty("minSleepTime") != null ? Integer.parseInt(config 
          .getProperty("minSleepTime")) : 0; 
       int high = config.getProperty("maxSleepTime") != null ? Integer.parseInt(config 
          .getProperty("maxSleepTime")) : 5; 
       int timeToSleep = r.nextInt(high - low) + low; 
       logger.info("Sleeping for " + timeToSleep + " seconds ... "); 
       try { 
        Thread.sleep(timeToSleep * 1000); 
       } catch (InterruptedException e1) { 
        e1.printStackTrace(); 
       } 
      } 
     } 
    } 

    if (counter >= maxAttempts) 
     logger.info("Stoping after " + maxAttempts + " attempts ...for url "+ urlSring); 

    return ""; 

あなたのアイデアを共有し、私は問題を解決する方法を教えてください:

は、以下のコードの一部です。 私は、ハングしたスレッドを殺すのではなく、できるだけそのシナリオのタイムアウトを短く実装したいと思っています。

答えて

1

することは、すなわちJettyとあなたはソケット接続のタイムアウトを設定することができ、より洗練されたHTTPクライアントを使用してみてください:

HttpClient httpClient = new HttpClient(); 
httpClient.start(); 

//socket connection timeout in ms 
httpClient.setConnectTimeout(500) 

// One liner: 
httpClient.GET("http://localhost:8080/").getStatus(); 

// Building a request with a timeout for request/response conversation 
ContentResponse response = httpClient.newRequest("http://localhost:8080") 
     .timeout(5, TimeUnit.SECONDS) 
     .send(); 
+0

私は桟橋で試してみるだろう、私はすでにApacheのHttpクライアントをしようと、同様の問題を得ました。 –

関連する問題