【发布时间】:2014-09-18 14:35:37
【问题描述】:
问题在于 Camel 和 CXF(端点和客户端)以及同时触发的多个请求。
这是我们得到的异常:
java.net.SocketException: Unexpected end of file from server
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:772)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:633)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1323)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.getResponseCode(URLConnectionHTTPConduit.java:266)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1543)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1513)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1318)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:632)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:570)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:479)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:382)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:335)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:135)
我尝试使用 SoapUI 负载测试直接命中端点,但无法重现该问题。它只会通过 spring jaxws:client bean 发生。
来自客户端的一次请求可以正常工作,我们永远不会看到错误,只有当我们尝试执行多个请求时。
还在线程等待时执行了线程转储,所有请求(其中 5 个)如下所示:
http-listener-1(1)" daemon prio=5 tid=0x00007fa2843e8800 nid=0x9d07 in Object.wait() [0x000000018a266000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000001708b27e8> (a org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduit$AsyncWrappedOutputStream)
at org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduit$AsyncWrappedOutputStream.getHttpResponse(AsyncHTTPConduit.java:562)
- locked <0x00000001708b27e8> (a org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduit$AsyncWrappedOutputStream)
at org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduit$AsyncWrappedOutputStream.getResponseCode(AsyncHTTPConduit.java:674)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1543)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1513)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1318)
at org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduit$AsyncWrappedOutputStream.close(AsyncHTTPConduit.java:383)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:632)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
- locked <0x00000001704175f8> (a org.apache.cxf.phase.PhaseInterceptorChain)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:570)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:479)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:382)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:335)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:135)
我也尝试过使用异步客户端,虽然堆栈跟踪和线程转储看起来不同,但结果是一样的。
这似乎也只发生在我们的开发实例(Mac 笔记本电脑)上,我们在带有 JDK 1.7.x 的 Glassfish 4.0 中运行它(我的机器上为 1.7u65,其他版本略有不同)
其中一条骆驼路线,虽然它似乎会影响所有路线(并且它们的设置方式相同)
from("cxf:/structure?serviceClass=" + StructureEndpoint.class.getName() + "&loggingFeatureEnabled=true")
.routeId("structure")
.to("log:com.test.camel")
.recipientList(simple("direct:structure:${header.operationName}"));
发生这种情况时,我从未看到由 loggingFeatureEnabled 启用的 camel/cxf 日志输出,因此我们也看不到 .to("log:*") 输出。它永远不会到达这里。
可重复测试:
SoapUI,简单的负载测试。在 5 处开始/结束线程 开始测试,前 5 个请求出现错误。 测试通过我们的前端,它使用 cxf 客户端来访问后端的 camel/cxf 服务。
直接点击 camel/cxf 服务不会导致任何问题。
环境测试更新
我们还有 2 个在 Linux 上运行的其他环境,都在 JDK 1.7.0u60 上,相同版本的 glassfish 没有表现出这种行为。所有受影响的机器都仅限 OS X。 (不久将测试一个 Windows 框)
【问题讨论】:
标签: java multithreading spring cxf apache-camel