【发布时间】:2018-08-13 08:49:44
【问题描述】:
我在我的 Spring Boot 应用程序中配置了一个 CXF 客户端,如下所示:
@Bean
public ConsumerSupportService consumerSupportService() {
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
jaxWsProxyFactoryBean.setServiceClass(ConsumerSupportService.class);
jaxWsProxyFactoryBean.setAddress("https://www.someservice.com/service?wsdl");
jaxWsProxyFactoryBean.setBindingId(SOAPBinding.SOAP12HTTP_BINDING);
WSAddressingFeature wsAddressingFeature = new WSAddressingFeature();
wsAddressingFeature.setAddressingRequired(true);
jaxWsProxyFactoryBean.getFeatures().add(wsAddressingFeature);
ConsumerSupportService service = (ConsumerSupportService) jaxWsProxyFactoryBean.create();
Client client = ClientProxy.getClient(service);
AddressingProperties addressingProperties = new AddressingProperties();
AttributedURIType to = new AttributedURIType();
to.setValue(applicationProperties.getWex().getServices().getConsumersupport().getTo());
addressingProperties.setTo(to);
AttributedURIType action = new AttributedURIType();
action.setValue("http://serviceaction/SearchConsumer");
addressingProperties.setAction(action);
client.getRequestContext().put("javax.xml.ws.addressing.context", addressingProperties);
setClientTimeout(client);
return service;
}
private void setClientTimeout(Client client) {
HTTPConduit conduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy policy = new HTTPClientPolicy();
policy.setConnectionTimeout(applicationProperties.getWex().getServices().getClient().getConnectionTimeout());
policy.setReceiveTimeout(applicationProperties.getWex().getServices().getClient().getReceiveTimeout());
conduit.setClient(policy);
}
同一个服务 bean 被同一个应用程序序列中的两个不同线程访问。如果我连续 10 次执行此特定序列,我将至少 3 次从服务调用中获得连接超时。我看到的是:
Caused by: java.io.IOException: Timed out waiting for response to operation {http://theservice.com}SearchConsumer.
at org.apache.cxf.endpoint.ClientImpl.waitResponse(ClientImpl.java:685) ~[cxf-core-3.2.0.jar:3.2.0]
at org.apache.cxf.endpoint.ClientImpl.processResult(ClientImpl.java:608) ~[cxf-core-3.2.0.jar:3.2.0]
如果我更改顺序以使其中一个线程不调用此服务,那么错误就会消失。所以,这里似乎发生了某种竞争条件。如果我查看该服务的代理管理器中的日志,我可以看到两个服务调用都非常快速地返回响应,但是第二个服务调用似乎卡在代码中的某个地方并且从未真正放开连接直到达到超时值。我一直在尝试追查此问题的原因很长一段时间,但没有成功。
关于 CXF 客户端代理是否是线程安全的,我读过一些不同的意见,但我的印象是它们是。如果事实并非如此,我应该为每次调用创建一个新的客户端代理,还是使用代理池?
【问题讨论】:
标签: spring-boot cxf jax-ws