"错误:写入服务器" - 只在ubuntu

时间:2016-09-27 06:56:15

标签: rest networking jersey-2.0 jersey-client ubuntu-16.04

我正在使用一个实现自定义功能的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多

我只能假设错误的两个原因:

  1. jvm版本
  2. 的区别
  3. 两个操作系统之间的不同网络设置
  4. 此错误出现在具有大量http加载的特定请求中。各个帖子中的许多同事都建议在大型http请求期间发生这种情况,但是我没有找到任何建议解决方案或将其与Ubuntu特定相关的帖子。

    任何提示?

    影响此类功能的网络参数是哪个?我怎么能改变/适应它们?

    是否需要特定的jvm配置?

1 个答案:

答案 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窗口大小并非适合所有解决方案。