2016-04-07 9 views
5

サービスを停止する要求を同時に送信するときに問題があります。リクエスト数に応じて、クライアント(Apache JMeter)のメッセージは「接続リセット」されます。たとえば、100個のリクエストを送信し、サーバーのレスポンスは100%成功しますが、500個のリクエストを送信すると、応答の%はエラーです。RESTサービス(スカラ/スプレー)を消費する接続のリセット

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) 

私は、コンテンツが次で、 "application.confを" 修正:

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

JVMの設定は次のとおりです。

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

重要:タマンロジックは、necesaryであるため、サーバが同時にトランザクションをサポートすること。 5秒以内に500件の個別接続(トランザクション)。

答えて

2

あなたのtimeoutの設定はうまく見えますが、毎秒500リクエストを処理することは間違いありません。

リクエストが処理に時間がかかりすぎる可能性があります。つまり、request-timeout + timeout-timeout = 32秒以上です。あなたはあなたのアーキテクチャをチェックし、それがどこで、そしてなぜそれが多くの時間を費やすのかを知る必要があります。これは、ほとんどのリクエストがミリ秒単位で完了する通常のWebサービスにとってはまれなことです。あなたがしなければならない処理が重い場合は、タイムアウトよりも時間がかかります。202 Acceptedで返信し、バックグラウンドで処理してください。クライアントが要求のステータスを確認できるURIを返すことができます。また、クライアントやその他のメカニズムに対するコールバックを使用して、要求が完了したことを伝えることもできます。

ルート自体をブロックしないと、他のすべての要求が効果的にブロックされるため、タイムアウトエラーが発生する可能性があります。例えば、Use a Dispatcher with Spray HttpServiceと答えてください。ノンブロッキング要求処理を実装するには、How does spray.routing.HttpService dispatch requests?を参照してください。

トラブルシューティングのためのいくつかのアイデア:1)単一のリクエストを処理するのにかかる時間を測定し、どのようにスケーリングするかを確認します。リソースの競合がありますか? 2)あなたのネットワークとクライアントがタイムアウトを起こさないことを確認してください。タイムアウトはサーバのタイムアウトよりも大きくする必要があります。

1

ご協力いただきありがとうございます。Aleksey Izmailov

Spray Documentationの場合、パラメータspray.can.servertimeout-timeout = 500sを設定する必要があります。この設定では、サーバーは要求の応答を受け入れるために500秒を受け取ります。応答がない場合、サーバーは要求を完了するためにエラーを送信します。

これを実行する目的は、サーバーに応答を受信するためのタイムアウトをとることで、アプリケーションの待ち時間が終了しました(私の場合はrequest-timeout = 30 s)。この時間(timeout-timeout)が満たされ、明らかに応答がない場合、サーバーは最後に要求を終了します。

spray.can { 
    server { 
    ... 
    timeout-timeout = 500 s 
    ... 
    } 
    } 
関連する問題