Java HTTP client Request with defined timeout

Chciałbym zrobić BIT (Wbudowany W testy) na kilka serwerów w mojej chmurze. Potrzebuję, żeby prośba nie powiodła się przy dużym limicie czasu.

Jak to zrobić z Javą?

Próba czegoś takiego jak poniżej nie wydaje się działać.

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("");
 }
}

-- Edit: Clarify what library is being used --

Używam httpclient z apache, tutaj jest odpowiedni pom.sekcja xml

 <dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
   <version>4.0.1</version>
   <type>jar</type>
 </dependency>
Author: Maxim Veksler, 2010-06-08

9 answers

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);
 112
Author: laz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-01 14:19:34

Jeśli używasz klienta Http w wersji 4.3 i wyższej powinieneś używać tego:

RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30 * 1000).build();
HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
 101
Author: Thunder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-03 07:29:46

HttpParams jest przestarzały w nowej bibliotece HTTPClient Apache. Użycie kodu dostarczonego przez Laz prowadzi do ostrzeżeń o deprecjacji.

Sugeruję użycie RequestConfig zamiast na instancji HttpGet lub HttpPost:

final RequestConfig params = RequestConfig.custom().setConnectTimeout(3000).setSocketTimeout(3000).build();
httpPost.setConfig(params);
 26
Author: pmartin8,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-15 12:50:03

Wygląda na to, że używasz HttpClient API, o którym nic nie wiem, ale możesz napisać coś podobnego za pomocą core 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;
}
 10
Author: dbyrne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-08 19:32:55

Stwierdziłem, że ustawienie ustawień time out w HttpConnectionParams i HttpConnectionManager nie rozwiązało naszej sprawy. Ograniczamy się do używania org.apache.commons.httpclient w wersji 3.0.1.

Skończyłem używając java.util.concurrent.ExecutorService do monitorowania połączenia HttpClient.executeMethod().

Oto mały, samodzielny przykład

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
Author: Kirby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-17 19:08:21

Wspomniana metoda z najwyższymi up ' ami autorstwa Laz jest przestarzała od wersji 4.3. Dlatego lepiej jest użyć obiektu Config Request, a następnie zbudować klienta 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;
        }

Menedżer PoolingHttpClientConnectionManager jest użytkownikiem, który ustawia maksymalną domyślną liczbę połączeń i maksymalną liczbę połączeń na trasie. Ustawiłem go odpowiednio jako 306 i 108. Wartości domyślne nie będą wystarczające w większości przypadków.

Dla ustawienia Timeout: Korzystałem z Obiekt RequestConfig. Można również ustawić właściwość Connection Request Timeout dla ustawienia timeoutu oczekiwania na połączenie z Menedżera połączeń.

 6
Author: Arun Thundyill Saseendran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-03 08:26:53

To było już wspomniane w komentarzu benvoliot powyżej. Ale myślę, że warto post na najwyższym poziomie, ponieważ na pewno mnie drapał po głowie. Umieszczam to na wypadek, gdyby pomogło komuś innemu.

Napisałem prostego klienta testowego i CoreConnectionPNames.CONNECTION_TIMEOUT timeout działa w tym przypadku idealnie. Żądanie zostanie anulowane, jeśli serwer nie odpowie.

Wewnątrz kodu serwera próbowałem przetestować jednak identyczny kod nigdy się nie kończy.

Zmieniając go na przerwa w aktywności połączenia z gniazdem (CoreConnectionPNames.SO_TIMEOUT) zamiast połączenia HTTP (CoreConnectionPNames.CONNECTION_TIMEOUT) naprawiła problem dla mnie.

Przeczytaj też uważnie Apache docs: http://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/params/CoreConnectionPNames.html#CONNECTION_TIMEOUT{[5]

Zwróć uwagę na bit, który mówi

Proszę zauważyć, że ten parametr może być stosowany tylko do połączeń, które są powiązane z konkretnym adresem lokalnym.

I hope to oszczędza komuś innemu drapanie się po głowie, przez które przeszedłem. To nauczy mnie nie czytać dokładnie dokumentacji!

 5
Author: Dan Haynes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:37

HttpConnectionParams.setSoTimeout(params, 10*60*1000);// for 10 mins i have set the timeout

Równie dobrze możesz określić wymagany czas przerwy.

 1
Author: Mohammed Irfan Tirupattur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-04 02:43:55

Op później stwierdził, że używają Apache Commons HttpClient 3.0.1

 HttpClient client = new HttpClient();
        client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
        client.getHttpConnectionManager().getParams().setSoTimeout(5000);
 1
Author: rtaft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-09 17:33:15