我正在使用一个实现自定义功能的jar文件,它使用jersey作为REST客户端(版本2.22.1)。虽然一切似乎都适用于一些调用,但对于特定的HTTP调用,我得到一个错误:写入服务器",,但仅限于在ubuntu中运行。
在我的两台ubuntu开发PC上运行单元测试时发生错误。我的开发PC都是带有Oracle JDK的Ubuntu 16.04:
~$ java -version
java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)
$ java -version
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)
从Windows机器运行相同的测试,没有错误。在我的Windows机器上:
java -version
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
完整错误的堆栈跟踪是:
javax.ws.rs.ProcessingException:java.io.IOException:写入时出错 服务器在 org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:287) 在 org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:255) 在 org.glassfish.jersey.client.JerseyInvocation $ 1.call(JerseyInvocation.java:684) 在 org.glassfish.jersey.client.JerseyInvocation $ 1.call(JerseyInvocation.java:681) 在org.glassfish.jersey.internal.Errors.process(Errors.java:315)at org.glassfish.jersey.internal.Errors.process(Errors.java:297)at org.glassfish.jersey.internal.Errors.process(Errors.java:228)at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444) 在 org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:681) 在 org.glassfish.jersey.client.JerseyInvocation $ Builder.method(JerseyInvocation.java:437) 在 org.glassfish.jersey.client.JerseyInvocation $ Builder.put(JerseyInvocation.java:326)
....
引起:java.io.IOException:写入服务器时出错 sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:666) 在 sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:678) 在 sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1534) 在 sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441) 在 java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) 在 org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:394) 在 org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:285)
... 40多
我只能假设错误的两个原因:
此错误出现在具有大量http加载的特定请求中。各个帖子中的许多同事都建议在大型http请求期间发生这种情况,但是我没有找到任何建议解决方案或将其与Ubuntu特定相关的帖子。
任何提示?
影响此类功能的网络参数是哪个?我怎么能改变/适应它们?
是否需要特定的jvm配置?
答案 0 :(得分:2)
解决方案是在TCP级别而不是在JVM版本或配置上。我更改了我的ubuntu网络设置,错误消失了。我想,它只发生在大型HTTP请求中,因为TCP窗口太小或者其他东西。
我按照http://www.slashroot.in/linux-network-tcp-performance-tuning-sysctl文章中的说明设置了以下设置:
net.ipv4.tcp_window_scaling = 1
net.core.rmem_max = 16777216
net.ipv4.tcp_rmem = 4096 137380 16777216
net.ipv4.tcp_wmem = 4096 137380 16777216
请注意,在HTTP请求中发生错误,负载大约为90千字节。为了成功,我需要使用分配给每个TCP连接(137380)的窗口的值。
请注意,这可能会在您的网络中产生其他副作用,我无法预见或解释。使用较大的窗口值进行测试会导致其他请求出现延迟,我无法解释。因此,增加TCP窗口大小并非适合所有解决方案。