Java 连接重置消耗REST服务(scala/spray)

Java 连接重置消耗REST服务(scala/spray),java,scala,rest,jmeter,spray,Java,Scala,Rest,Jmeter,Spray,我无法同时向rest服务发送请求;对于某些请求,客户端(Apache JMeter)中的消息是“连接重置”,具体取决于请求数,例如,我发送100个请求,服务器的响应是100%成功的,但如果我发送500个请求,30%的响应是错误的 java.net.SocketException: Connection reset at java.net.SocketInputStream.read(SocketInputStream.java:196) at java.net.SocketInp

我无法同时向rest服务发送请求;对于某些请求,客户端(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

重要提示:由于业务逻辑,服务器必须支持并发事务;在不到5秒内完成500个单独的连接(事务)。

您的
超时设置看起来不错,每秒处理500个请求绝对不是问题

很可能您的请求处理时间过长,即超过
请求超时时间
+
超时时间
=32秒。您需要检查您的体系结构,看看它在哪里花费了这么多时间,以及为什么花费这么多时间。这对于常规web服务来说是非常不寻常的,因为大多数请求都在毫秒范围内完成。如果你有一些繁重的处理,你必须做的事情比超时时间要长,你可以回复
202 Accepted
并在后台处理。您可以返回一个URI,客户机可以在其中检查请求的状态,或者使用对客户机的回调或任何其他机制来传达请求已完成

记住不要阻塞路由本身,否则会有效地阻塞所有其他请求,并且可能会出现超时错误。请参阅以下示例的答案:。要实现非阻塞请求处理,请参见以下内容:


排除故障的一些想法:1)测量处理单个请求所需的时间,并查看它的扩展情况—您是否存在资源争用?2) 检查您的网络和客户端是否导致超时-它们的超时值应高于服务器的超时值。

感谢您的合作和宝贵时间

咨询时,我必须设置参数
spray.can.server
timeout timeout=500s
,使用此配置,服务器有500s的时间来接受完成的请求响应。如果没有响应,服务器将发送一条消息,说明完成请求的错误

这样做的目的是让服务器超时接收答案,这样您就完成了应用程序的等待时间(在我的例子中,
request timeout=30s
)。如果满足此时间(
timeout-timeout
),并且肯定没有响应,则服务器最终结束请求

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