BindException: Adresse bereits in Verwendung auf einem Client-Socket?

stimmen
2

Ich habe eine Client-Server-Architektur abgestuftes mit dem Kunden machen RPC-ähnliche Anfragen an den Server einsehen. Ich benutze Tomcat Servlets zu hosten, und die Apache Httpclient auf, um es Anfragen.

Mein Code geht in etwa so:

    private static final HttpConnectionManager CONN_MGR = new MultiThreadedHttpConnectionManager();
    final GetMethod get = new GetMethod();
    final HttpClient httpClient = new HttpClient(CONN_MGR);
    get.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
    get.getParams().setParameter(HttpMethodParams.USER_AGENT, USER_AGENT);

    get.setQueryString(encodedParams);
    int responseCode;
    try {
        responseCode = httpClient.executeMethod(get);
    } catch (final IOException e) {
        ...
    }
    if (responseCode != 200)
        throw new Exception(...);

    String responseHTML;
    try {
        responseHTML = get.getResponseBodyAsString(100*1024*1024);
    } catch (final IOException e) {
        ...
    }
    return responseHTML;

Es funktioniert großartig in einer leicht belasteten Umgebung, aber wenn ich Hunderte von Anfragen pro Sekunde zu machen beginne ich, das zu sehen -

Caused by: java.net.BindException: Address already in use
    at java.net.PlainSocketImpl.socketBind(Native Method)
    at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:336)
    at java.net.Socket.bind(Socket.java:588)
    at java.net.Socket.<init>(Socket.java:387)
    at java.net.Socket.<init>(Socket.java:263)
    at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:80)
    at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:122)
    at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)
    at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387)
    at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)

Irgendwelche Gedanken darüber, wie dieses Problem beheben? Ich vermute, es ist etwas, mit dem Kunden zu tun versuchen, die ephemeren Client-Ports wieder zu verwenden, aber warum das passiert ist / wie kann ich es beheben? Vielen Dank!

Veröffentlicht am 30/12/2009 um 03:11
quelle vom benutzer
In anderen Sprachen...                            


5 antworten

stimmen
1

Mit Hunderten von Verbindungen eines zweiten, und ohne zu wissen , wie lange Ihre Verbindungen zu öffnen halten, machen ihr Ding, in der Nähe, und recycelt bekommen, habe ich den Verdacht , dass dies nur ein Problem , das Sie haben werden. Eine Sache , die Sie tun können , ist den Fang BindExceptionim try - Block verwenden , dass alles zu tun , müssen Sie in dem bind-erfolglosen Fall tun, und wickeln den gesamten Anruf in einer whileSchleife , die auf einer Flagge hängt die angibt , ob die Bindung gelungen. Aus der Spitze von meinem Kopf:

boolean hasBound = false;
while (!hasBound) {
    try {
        hasBound = true;
        responseCode = httpClient.executeMethod(get);
    } catch (BindException e) {
        // do anything you want in the bound-unsuccessful case
    } catch (final IOException e) {
        ...
    }
}

Aktualisieren Sie mit Frage: Eine neugierige Frage: Was ist die maximale Gesamt und pro-Host - Anzahl der Verbindungen von Ihrer erlaubt MultiThreadedHttpConnectionManager? In Ihrem Code sein , dass würde:

CONN_MGR.getParams().getDefaultMaxConnectionsPerHost();
CONN_MGR.getParams().getMaxTotalConnections();
Beantwortet am 30/12/2009 um 03:23
quelle vom benutzer

stimmen
0

So Sie mehr Anfragen als TCP / IP-Ports dürfen geöffnet werden gefeuert haben. Ich tue es nicht Httpclient, so kann ich im Detail über das nicht gehen, aber in der Theorie gibt es drei Lösungen für dieses spezielle Problem:

  1. Hardware-basierte: fügen Sie ein anderes NIC (Network Interface Card).
  2. Software basiert: enge Verbindungen direkt nach dem Gebrauch und / oder die Verbindung Timeout erhöhen.
  3. Plattform basiert: erhöhen die Menge der TCP / IP-Ports, die sein dürfen geöffnet. Kann sein, OS-spezifische und / oder NIC-Treiber spezifisch. Das absolute Maximum ist 65535, von denen mehrere bereits reserviert werden kann / in Gebrauch (zB Port 80).
Beantwortet am 30/12/2009 um 03:24
quelle vom benutzer

stimmen
1

Eine sehr gute Diskussion des Problems Sie in ausführen , kann gefunden werden hier . Auf der Tomcat Seite, wird standardmäßig die Verwendung SO_REUSEADDR Option, die die Server - Sockets kann wiederverwendet werden, die in TIME_WAIT sind. Zusätzlich Keep-Alive das Apache HTTP - Client wird standardmäßig verwenden und Verbindungen erneut zu verwenden versuchen.

Ihre Probleme scheinen nicht Aufruf verursacht werden releaseConnection auf der Httpclient. Dies ist erforderlich , um für die Verbindung wiederverwendet werden. Andernfalls wird die Verbindung geöffnet bleiben , bis Garbage Collector kommt und schließt es, oder der Server trennt die Keep-Alive. In beiden Fällen wird es nicht an den Pool zurückgegeben werden.

Beantwortet am 30/12/2009 um 04:37
quelle vom benutzer

stimmen
0

So stellt sich heraus das Problem war, dass einer des anderen Httpclient Fälle versehentlich nicht den MultiThreadedHttpConnectionManager war ich mit instanziiert, so hatte ich effektiv keine aktuellen Preise überhaupt zu begrenzen. Festsetzung dieses Problem behoben geworfen die Ausnahme ist.

Vielen Dank für alle Anregungen, aber!

Beantwortet am 31/12/2009 um 02:29
quelle vom benutzer

stimmen
0

Auch wenn wir rufen HttpClientUtils.closeQuietly (Client); aber in Ihrem Code in Fall versuchen, den Inhalt von Httpresponse-Einheit wie Inputcontent = HttpResponse.getEntity () zu lesen. getContent (), dann sollten Sie die Input schließen auch dann nur Httpclient Verbindung ordnungsgemäß erhalten geschlossen.

Beantwortet am 29/06/2017 um 16:24
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more