2016-04-07 9 views
5

Ich habe ein Problem beim Senden gleichzeitig Anfragen an den Rest Service; Die Nachrichten im Client (Apache JMeter) ist "Connection Reset" für einige Anfragen, abhängig von der Anzahl der Anfragen, zum Beispiel, ich sende 100 Anfragen und die Antwort des Servers ist 100% erfolgreich, aber wenn ich 500 Anfragen sende, die 30 % der Antworten sind Fehler.Verbindung zurückgesetzt, REST-Service (Scala/Spray)

java.net.SocketException: Connection reset 
    at java.net.SocketInputStream.read(SocketInputStream.java:196) 
    at java.net.SocketInputStream.read(SocketInputStream.java:122) 
    at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:166) 
    at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:90) 
    at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:281) 
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:92) 
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:61) 
    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:254) 
    at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:289) 
    at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:252) 
    at org.apache.http.impl.conn.ManagedClientConnectionImpl.receiveResponseHeader(ManagedClientConnectionImpl.java:191) 
    at org.apache.jmeter.protocol.http.sampler.MeasuringConnectionManager$MeasuredConnection.receiveResponseHeader(MeasuringConnectionManager.java:201) 
    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:300) 
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:127) 
    at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:715) 
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:520) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805) 
    at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.executeRequest(HTTPHC4Impl.java:517) 
    at org.apache.jmeter.protocol.http.sampler.HTTPHC4Impl.sample(HTTPHC4Impl.java:331) 
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy.sample(HTTPSamplerProxy.java:74) 
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1146) 
    at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1135) 
    at org.apache.jmeter.threads.JMeterThread.process_sampler(JMeterThread.java:434) 
    at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:261) 
    at java.lang.Thread.run(Thread.java:745) 

I modifiziert, um die "application.conf", wird der Inhalt der nächste ist:

spray.can { 
    server { 
    server-header = spray-can/${spray.version} 
    ssl-encryption = off 
    pipelining-limit = 16 
    idle-timeout = 60 s 
    request-timeout = 30 s 
    timeout-timeout = 2 s 
    timeout-handler = "" 
    reaping-cycle = 250 ms 
    stats-support = on 
    remote-address-header = off 
    raw-request-uri-header = off 
    transparent-head-requests = on 
    chunkless-streaming = off 
    verbose-error-messages = on 
    request-chunk-aggregation-limit = 1m 
    response-header-size-hint = 512 
    bind-timeout = infinite 
    unbind-timeout = 1s 
    registration-timeout = 1s 
    default-host-header = "" 
    automatic-back-pressure-handling = on 
    back-pressure { 
     noack-rate = 10 
     reading-low-watermark = infinite 
    } 
    parsing = ${spray.can.parsing} 
    } 
    client { 
    user-agent-header = spray-can/${spray.version} 
    idle-timeout = 60 s 
    request-timeout = 40 s 
    reaping-cycle = 250 ms 
    response-chunk-aggregation-limit = 1m 
    chunkless-streaming = off 
    request-header-size-hint = 256 
    max-encryption-chunk-size = 1m 
    connecting-timeout = 30s 
    proxy { 
     http = default 
     https = default 
    } 
    ssl-tracing = off 
    parsing = ${spray.can.parsing} 
    } 
    host-connector { 
    max-connections = 80 
    max-retries = 8 
    max-redirects = 0 
    pipelining = enabled 
    idle-timeout = 30 s 
    client = ${spray.can.client} 
    } 
} 

Die Einstellungen der JVM sind:

-Xms1024M 
-Xmx2048M 
-Xss1M 
-XX:MaxPermSize=1024m 

WICHTIG: Da Logik bussines ist necesary dass der Server gleichzeitig Transaktionen unterstützt; 500 einzelne Verbindungen (Transaktionen) in weniger als 5 Sekunden.

Antwort

2

Ihre timeout Einstellungen sehen gut aus, und die Verarbeitung von 500 Anfragen pro Sekunde ist definitiv kein Problem.

Höchstwahrscheinlich dauert die Verarbeitung Ihrer Anfragen zu lange, d. H. Mehr als request-timeout + timeout-timeout = 32 Sekunden. Sie müssen Ihre Architektur überprüfen und sehen, wo und warum sie so viel Zeit verbringt. Dies wäre für reguläre Webdienste, bei denen die meisten Anfragen im Millisekundenbereich enden, ziemlich ungewöhnlich. Für den Fall, dass Sie eine schwere Verarbeitung haben, die länger dauert als die Zeitüberschreitung, können Sie mit 202 Accepted antworten und die Verarbeitung im Hintergrund durchführen. Sie können einen URI zurückgeben, in dem der Client den Status der Anfrage überprüfen kann oder den Rückruf an den Client oder einen anderen Mechanismus verwenden kann, um zu kommunizieren, dass die Anfrage ausgeführt wurde.

Denken Sie daran, nicht in der Route selbst zu blockieren, sonst würden Sie effektiv alle anderen Anfragen blockieren und Sie könnten Timeout-Fehler bekommen. Siehe diese Antwort zum Beispiel: Use a Dispatcher with Spray HttpService. Um die Verarbeitung von nicht blockierenden Anforderungen zu implementieren, siehe: How does spray.routing.HttpService dispatch requests?.

Einige Ideen für die Fehlerbehebung: 1) Messen Sie, wie viel Zeit es dauert, einzelne Anfrage zu verarbeiten, und sehen, wie es skaliert - haben Sie Ressourcenkonflikte? 2) überprüfen Sie, dass Ihr Netzwerk und Client kein Timeout verursachen - ihr Timeout sollte höher sein als der des Servers.

1

Vielen Dank für Ihre Mitarbeit und Ihre Zeit Aleksey Izmailov.

Beratung Spray Documentation, muss ich den Parameter spray.can.servertimeout-timeout = 500s, mit dieser Konfiguration der Server hat 500s für die Annahme der Antwort der Anfrage getan. Wenn der Server keine Antwort hat, senden Sie eine Nachricht über den Fehler zum Ausfüllen der Anfrage.

Der Zweck ist, eine Zeitüberschreitung auf dem Server zu nehmen, um die Antwort zu erhalten, so dass Sie die Wartezeit der Anwendung beendet haben (in meinem Fall request-timeout = 30 s). Wenn diese Zeit (timeout-timeout) erfüllt ist und definitiv keine Antwort, beendet der Server schließlich die Anfrage.

spray.can { 
    server { 
    ... 
    timeout-timeout = 500 s 
    ... 
    } 
    } 
Verwandte Themen