簡體   English   中英

連接重置消耗REST服務(scala / spray)

[英]Connection reset consuming REST service (scala / spray)

我發送並發請求休息服務時遇到問題; 客戶端(Apache JMeter)中的消息對於某些請求是“連接重置”,具體取決於請求數量,例如,我發送100個請求並且服務器的響應是100%成功,但是如果我發送500個請求,則30 %的回復是錯誤的。

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

重要提示:由於bussines邏輯,服務器支持並發事務是必要的; 少於5秒的500個單獨連接(交易)。

您的timeout設置看起來很好,每秒處理500個請求絕對不是問題。

很可能您的請求處理時間太長,即超過request-timeout + timeout-timeout = 32秒。 您需要檢查您的架構,看看它花費了多少時間和原因。 對於常規Web服務而言,這是非常不尋常的,其中大多數請求以毫秒范圍完成。 如果您需要執行一些繁重的處理,這需要花費超過超時的時間,您可以使用202 Accepted進行回復並在后台進行處理。 您可以返回一個URI,其中客戶端可以檢查請求的狀態,或使用回調到客戶端或任何其他機制來通知請求已完成。

記住不要阻塞路由本身,否則你會有效地阻止所有其他請求,你可能會遇到超時錯誤。 例如,請參閱此答案: 使用帶有Spray HttpService的Dispatcher 要實現非阻塞請求處理,請參閱: spray.routing.HttpService如何調度請求?

一些故障排除的想法:1)測量處理單個請求所需的時間,並查看它如何擴展 - 您是否有資源爭用? 2)檢查您的網絡和客戶端是否不會導致超時 - 它們的超時應該高於服務器的超時。

感謝您的合作和您的時間Aleksey Izmailov

咨詢噴塗文檔 ,我必須設置參數spray.can.server timeout-timeout = 500s ,使用此配置服務器有500s用於接受請求完成的響應。 如果沒有respose,服務器會發送一條錯誤消息來完成請求。

這樣做的目的是對服務器進行超時以接收答案,因此您已完成應用程序的等待時間(在我的情況下request-timeout = 30 s )。 如果滿足此時間( timeout-timeout )並且肯定沒有響應,則服務器最終結束請求。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM