2016-04-07 22 views
5

Ho un problema nell'invio di richieste al servizio di riposo; I messaggi nel client (Apache JMeter) sono "Connection reset" per alcune richieste, a seconda del numero di richieste, ad esempio, invio 100 richieste e la risposta del server è riuscita al 100%, ma se invio 500 richieste, il 30 % delle risposte sono errori.Connessione ripristinata che consuma servizio REST (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) 

ho modificato il "application.conf", il contenuto è il seguente:

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} 
    } 
} 

Le impostazioni della JVM sono:

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

IMPORTANTE: poiché la logica di bussines, è necesary che il server supporta contemporaneamente transazioni; 500 singole connessioni (transazioni) in meno di 5 secondi.

risposta

2

Le tue impostazioni timeout sembrano buone e la gestione di 500 richieste al secondo non rappresenta un problema.

Molto probabilmente le vostre richieste impiegano troppo tempo per essere elaborate, vale a dire più di request-timeout + timeout-timeout = 32 secondi. Devi controllare la tua architettura e vedere dove e perché spende così tanto tempo. Ciò sarebbe piuttosto insolito per i normali servizi Web, dove la maggior parte delle richieste viene completata in millisecondi. Nel caso in cui si abbia un po 'di elaborazione pesante che si deve fare che richiede più tempo del timeout, è possibile rispondere con 202 Accepted ed eseguire l'elaborazione in background. È possibile restituire un URI in cui il client può verificare lo stato della richiesta o utilizzare la richiamata al client o qualsiasi altro meccanismo per comunicare che la richiesta è stata eseguita.

Ricordare di non bloccare la route stessa altrimenti si bloccherebbero tutte le altre richieste e si potrebbero verificare errori di timeout. Vedi questa risposta per esempio: Use a Dispatcher with Spray HttpService. Per implementare l'elaborazione della richiesta non bloccante, vedere questo: How does spray.routing.HttpService dispatch requests?.

Alcune idee per la risoluzione dei problemi: 1) misurare il tempo necessario per elaborare una singola richiesta e vedere come viene ridimensionata: si hanno conflitti di risorse? 2) controlla che la tua rete e il tuo client non causino il timeout: il loro timeout dovrebbe essere superiore a quello del server.

1

Grazie per la collaborazione e il vostro tempo Aleksey Izmailov.

Consulenza Spray Documentation, Devo impostare il parametro spray.can.servertimeout-timeout = 500s, con questa configurazione il server ha 500 s per accettare la risposta della richiesta effettuata. Se non ha risposta il server invia un messaggio l'errore per il completamento della richiesta.

Lo scopo di tale operazione è di richiedere un timeout al server per ricevere la risposta, quindi è stato terminato il tempo di attesa dell'applicazione (nel mio caso request-timeout = 30 s). Se questa volta (timeout-timeout) è soddisfatto e sicuramente nessuna risposta, il server termina la richiesta.

spray.can { 
    server { 
    ... 
    timeout-timeout = 500 s 
    ... 
    } 
    } 
Problemi correlati