Ich muss eine Zeitüberschreitung für die HTTP-Anfrage festlegen, die wir an einen Dienst (nicht an einen Webdienst) richten. Wir verwenden den Apache HTTP Client. Ich habe diese 2 Codezeilen hinzugefügt, um das Zeitlimit auf Anfrage und Antwort auf den Dienst festzulegen.
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 10000);
1) Derzeit habe ich 10 Sekunden als Zeitlimit festgelegt, da die Antwort vom Dienst fast augenblicklich angezeigt wird. Sollte ich das Timing erhöhen oder verringern?
2) Was passiert, wenn die Antwort länger als 10 Sekunden dauert? Wird es eine Ausnahme auslösen und welche Ausnahme wird es sein? Muss ich noch etwas hinzufügen, um die Zeitüberschreitung im folgenden Code festzulegen?
public HashMap<String, Object> getJSONData(String url) throw Exception{
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpParams params = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 10000);
HttpHost proxy = new HttpHost(getProxy(), getProxyPort());
ConnRouteParams.setDefaultProxy(params, proxy);
URI uri;
InputStream data = null;
try {
uri = new URI(url);
HttpGet method = new HttpGet(uri);
HttpResponse response = httpClient.execute(method);
data = response.getEntity().getContent();
}
catch (Exception e) {
e.printStackTrace();
}
Reader r = new InputStreamReader(data);
HashMap<String, Object> jsonObj = (HashMap<String, Object>) GenericJSONUtil.fromJson(r);
return jsonObj;
}
Die Ausnahmen, die Sie sehen werden, sind ConnectTimeoutException
und SocketTimeoutException
. Die tatsächlich verwendeten Timeout-Werte sollten die maximale Wartezeit Ihrer Anwendung sein. Ein wichtiger Hinweis zum Lesezeitlimit ist, dass es dem Zeitlimit bei einem Socket-Lesevorgang entspricht. Es ist also nicht die Zeit, die für das Eintreffen der vollständigen Antwort vorgesehen ist, sondern die Zeit, die für einen einzelnen Socket-Lesevorgang angegeben wird. Wenn es also 4 Socket-Lesevorgänge gibt, die jeweils 9 Sekunden dauern, beträgt Ihre Gesamtlesezeit 9 * 4 = 36 Sekunden.
Wenn Sie eine Gesamtzeit für das Eintreffen der Antwort angeben möchten (einschließlich Verbindungs- und Gesamtlesezeit), können Sie den Aufruf in einen Thread einbinden und dafür ein Thread-Timeout verwenden. Zum Beispiel mache ich normalerweise so etwas:
Future<T> future = null;
future = pool.submit(new Callable<T>() {
public T call() {
return executeImpl(url);
}
});
try {
return future.get(10, TimeUnit.SECONDS);
}
catch (InterruptedException e) {
log.warn("task interrupted", name);
}
catch (ExecutionException e) {
log.error(name + " execution exception", e);
}
catch (TimeoutException e) {
log.debug("future timed out", name);
}
Einige Annahmen, die im obigen Code getroffen wurden, sind: 1) Dies ist in einer Funktion mit einem URL-Parameter, 2) Es ist in einer Klasse mit einer Namensvariablen, 3) Log ist eine log4j-Instanz und 4) Pool ist ein Thread-Pool-Executor . Beachten Sie, dass Sie auch bei Verwendung eines Thread-Zeitlimits ein Zeitlimit für Verbindung und Socket im HttpClient angeben sollten, damit langsame Anforderungen die Ressourcen im Thread-Pool nicht verschlingen. Beachten Sie auch, dass ich einen Thread-Pool verwende, da ich diesen normalerweise in einem Webdienst verwende, sodass der Thread-Pool von mehreren Tomcat-Threads gemeinsam genutzt wird. Ihre Umgebung kann anders sein, und Sie möchten möglicherweise einfach für jeden Aufruf einen neuen Thread erstellen.
Außerdem werden die Zeitüberschreitungen normalerweise über die Mitgliedsfunktionen der Parameter wie folgt festgelegt:
params.setConnectionTimeout(10000);
params.setSoTimeout(10000);
Aber vielleicht funktioniert auch Ihre Syntax (nicht sicher).
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen