タイムアウトが定義されたJavaHTTPクライアント要求


91

クラウド内の多数のサーバーにBIT(ビルトインテスト)を作成したいと思います。大きなタイムアウトでリクエストが失敗する必要があります。

Javaでこれをどのように行う必要がありますか?

以下のようなことを試みてもうまくいかないようです。

public class TestNodeAliveness {
 public static NodeStatus nodeBIT(String elasticIP) throws ClientProtocolException, IOException {
  HttpClient client = new DefaultHttpClient();
  client.getParams().setIntParameter("http.connection.timeout", 1);

  HttpUriRequest request = new HttpGet("http://192.168.20.43");
  HttpResponse response = client.execute(request);

  System.out.println(response.toString());
  return null;
 }


 public static void main(String[] args) throws ClientProtocolException, IOException {
  nodeBIT("");
 }
}

-編集:使用されているライブラリを明確にします-

私はapacheのhttpclientを使用しています。これが関連するpom.xmlセクションです。

 <dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
   <version>4.0.1</version>
   <type>jar</type>
 </dependency>

すべてのHTTP機能にどのライブラリを使用していますか?
nojo 2010年

コメントありがとうございます。投稿を更新しました。
Maxim Veksler 2010年

回答:


119
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

...

    // set the connection timeout value to 30 seconds (30000 milliseconds)
    final HttpParams httpParams = new BasicHttpParams();
    HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
    client = new DefaultHttpClient(httpParams);

1
これは何をしますか?それが設定するもののタイムアウト?stackoverflow.com/questions/3000767/を
Maxim Veksler 2010年

84
ApacheのHttpClientには、2つの別個のタイムアウトがあります。TCP接続の確立を待機する時間のタイムアウトと、後続のデータバイトを待機する時間のタイムアウトです。HttpConnectionParams.setConnectionTimeout()は前者であり、HttpConnectionParams.setSoTimeout()は後者です。
benvolioT 2011年

7
デフォルトのタイムアウトは何ですか?0 =無限ですか?
トビア2014年

1
http.connection.timeout整数接続が確立されるまでのタイムアウト。ゼロの値は、タイムアウトが使用されないことを意味します。
マーベロイド2016

26
将来の読者へ:ここで参照されているクラスは現在非推奨になっていることに注意してください(2016-07-05現在)。ただし、これは2010年に投稿されたときはおそらく良い答えでした。この答えを参照してください:stackoverflow.com/a/ 19153314/192801もう少し最新のもの。
FrustratedWithFormsDesigner 2016

125

Http Clientバージョン4.3以降を使用している場合は、次を使用する必要があります。

RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30 * 1000).build();
HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();

4
ありがとう!私は少なくとも20分を費やして、あなたの答えを見つける前に、これを行うために非推奨のコマンドを取り除く方法を見つけようとしました。
vextorspace 2014

忘れたSocketTimeout。また、「default」はHttpClientHttpClientBuilderfrom create()がthroughbuild()メソッドに与えるすべてのデフォルトであることを意味しますか?それとも通過するものだけsetDefaultRequestConfig(requestConfig)ですか?私は理にかなっていますか?
ADTC 2015

@ADTCあなたの質問は少し紛らわしいです:)。デフォルトのリクエスト設定は、そのHttpClientの「のみ」を使用するすべてのHttpPost、HttpGet、...インスタンスに使用されます。別のHttpClientインスタンスを作成した場合、この要求構成はそのクライアントでは使用されません。
サンダー

35

HttpParamsは、新しいApacheHTTPClientライブラリで非推奨になりました。Lazが提供するコードを使用すると、非推奨の警告が表示されます。

代わりに、HttpGetまたはHttpPostインスタンスでRequestConfigを使用することをお勧めします。

final RequestConfig params = RequestConfig.custom().setConnectTimeout(3000).setSocketTimeout(3000).build();
httpPost.setConfig(params);

「上記のコードを使用する」 << SOはフォーラムではなく、いくつかの要因により回答が上下に移動するため、どのコードを参照しているかわかりません。「xyzの答えのコードを使用する」のようなことを言うことができますか?
ADTC 2015

4
ところで、きちんとした答え。しかし、Thunderの回答と比較すると、をデフォルトとして設定するのではなく、RequestConfigすべてに設定することの違いは何ですか?HttpPostHttpClient
ADTC 2015

2
はい、その通りです。上記のコードは、時間の経過とともに変化してはならない「受け入れられた回答」を示しています。私は..とにかく私の答えを更新します
pmartin8

10

HttpClient APIを使用しているようですが、コアJavaを使用してこれに似たものを作成できます。

try {

   HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
   con.setRequestMethod("HEAD");
   con.setConnectTimeout(5000); //set timeout to 5 seconds
   return (con.getResponseCode() == HttpURLConnection.HTTP_OK);

} catch (java.net.SocketTimeoutException e) {
   return false;
} catch (java.io.IOException e) {
   return false;
}

2
これは、ApacheHTTPクライアントのタイムアウトには影響しません。
laz 2010年

9
主張したことはありません;)
dbyrne 2010年

5
HttpURLConnectionのタイムアウトの概念は不十分です。サーバーが応答を開始した後、ハングした場合、タイムアウトに達することはありません。この違いがあるため、ApacheのHttpClientの方が適しています。
benvolioT 2011年

7

タイムアウト設定を設定しHttpConnectionParamsHttpConnectionManagerも、問題が解決しないことがわかりました。org.apache.commons.httpclientバージョン3.0.1の使用に制限されています。

結局、java.util.concurrent.ExecutorServiceを使用してHttpClient.executeMethod()通話を監視しました。

これは小さな自己完結型の例です

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author Jeff Kirby
 * @since <pre>Jun 17, 2011</pre>
 */
public class Example {

   private static final String SITE = "http://some.website.com/upload";
   private static final int TIME_OUT_SECS = 5;

   // upload a file and return the response as a string
   public String post(File file) throws IOException, InterruptedException {
      final Part[] multiPart = { new FilePart("file", file.getName(), file) };
      final EntityEnclosingMethod post = new PostMethod(SITE);
      post.setRequestEntity(new MultipartRequestEntity(multiPart, post.getParams()));
      final ExecutorService executor = Executors.newSingleThreadExecutor();
      final List<Future<Integer>> futures = executor.invokeAll(Arrays.asList(new KillableHttpClient(post)), TIME_OUT_SECS, TimeUnit.SECONDS);
      executor.shutdown();
      if(futures.get(0).isCancelled()) {
         throw new IOException(SITE + " has timed out. It has taken more than " + TIME_OUT_SECS + " seconds to respond");
      }
      return post.getResponseBodyAsString();
   }

   private static class KillableHttpClient implements Callable<Integer> {

      private final EntityEnclosingMethod post;

      private KillableHttpClient(EntityEnclosingMethod post) {
         this.post = post;
      }

      public Integer call() throws Exception {
         return new HttpClient().executeMethod(post);
      }
   }
}

7

Lazによる最高のアップを持つ前述のメソッドは、バージョン4.3以降で非推奨になりました。したがって、Request Config Objectを使用してから、HTTPクライアントを構築することをお勧めします。

    private CloseableHttpClient createHttpClient()
        {
        CloseableHttpClient httpClient;
        CommonHelperFunctions helperFunctions = new CommonHelperFunctions();
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(306);
        cm.setDefaultMaxPerRoute(108);
        RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(15000)
            .setSocketTimeout(15000).build();
        httpClient = HttpClients.custom()
            .setConnectionManager(cm)
            .setDefaultRequestConfig(requestConfig).build();
        return httpClient;
        }

PoolingHttpClientConnectionManagerは、ルートごとの接続の最大デフォルト数と接続の最大数を設定するユーザーです。それぞれ306と108に設定しました。ほとんどの場合、デフォルト値では不十分です。

タイムアウトの設定: RequestConfigオブジェクトを使用しました。接続マネージャからの接続を待機するためのタイムアウトを設定するために、プロパティ接続要求タイムアウトを設定することもできます。


5

これは、上記のbenvoliotによるコメントですでに言及されています。しかし、それは確かに頭を悩ませたので、トップレベルの投稿の価値があると思います。他の誰かを助ける場合に備えて、これを投稿しています。

私は簡単なテストクライアントを作成しましたがCoreConnectionPNames.CONNECTION_TIMEOUT、その場合はタイムアウトが完全に機能します。サーバーが応答しない場合、リクエストはキャンセルされます。

私が実際にテストしようとしていたサーバーコードの内部では、同じコードがタイムアウトすることはありません。

CoreConnectionPNames.SO_TIMEOUTHTTP接続(CoreConnectionPNames.CONNECTION_TIMEOUT)ではなくソケット接続アクティビティ()でタイムアウトするように変更すると、問題が修正されました。

また、Apacheのドキュメントを注意深く読んでくださいhttp//hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/params/CoreConnectionPNames.html#CONNECTION_TIMEOUT

言うビットに注意してください

このパラメータは、特定のローカルアドレスにバインドされている接続にのみ適用できることに注意してください。

私が経験したすべての頭を掻く他の誰かを救うことを願っています。それは私にドキュメントを完全に読まないように教えてくれます!


2

Opは後で、Apache Commons HttpClient3.0.1を使用していると述べました。

 HttpClient client = new HttpClient();
        client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
        client.getHttpConnectionManager().getParams().setSoTimeout(5000);

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.