Webservice - 客户端服务实例化

14

你知道创建Web服务客户端服务实例有多昂贵吗?

 JavaWebService service = new JavaWebService();
 SomePort port = service.getJavaWebServicePort(); 

在多线程环境(Web应用程序)中创建一次服务,然后重用相同的端口不危险吗?

我读到getPort和端口本身不是线程安全的,但每次创建服务可能会有问题,特别是它是一个昂贵的操作。

有任何想法吗?

谢谢。

2个回答

16
在JAX-WS参考实现中(Metro),创建JavaWebService是廉价的(在我们生成的客户端中,我们发现这大约需要20毫秒)。
第一次创建 SomePort 是相当昂贵的(对我们来说大约需要200毫秒);对同一个 JavaWebService 实例的后续调用 getSomePort() 则要快得多(对我们而言约为3毫秒)。
因此,每次需要获取 SomePort 就创建一个 JavaWebService 的实现将具有一定代价。简而言之,答案是“相当昂贵”。
然而,即使 SomePort 上的方法不是线程安全的,JavaWebService 上的方法却是线程安全的。因此,在使用Metro时,明智的使用模式是重用 JavaWebService ,因为您只会一次性地遇到高昂成本的 getSomePort() 调用。
更新
这与 Andreas Leow 的两篇帖子相吻合,Andreas Leow 是 Oracle 德国的员工之一,是 @PapaLazarou 在下面评论中引用的主题中的两位发帖人之一,他关于 Service 对象写道:
“您可以针对每个 WSDL 创建一个单独的静态 Service 实例:任何单个的 Service 对象都是完全线程安全的,并且可以被尽可能多的并发线程共享。”
关于端口的使用,他也写道:
“虽然我几乎可以确定 CXF JAX-WS 端口是线程安全的,但 Metro 的 Port 对象绝对不是线程安全的。”

2
你有这方面的参考资料吗?到目前为止,我所能找到的都是一些帖子,指出返回的端口不是线程安全的,以及CXF网页上说“客户端”(我想他们是指端口)不是线程安全的。我正在寻找的是一些官方声明,即Metro服务(而不是端口)是线程安全的,特别是调用getPort返回单独的实例。 - David Harkness
1
我发现Metro开发人员发布了一些帖子表明了这一点,但是我很难再次找到它们。最近我唯一找到的一篇文章是这个。顺便说一下,我的独立并发测试也表明了这一点。 - PapaLazarou
根据CXF文档 (http://cxf.apache.org/faq.html#FAQ-AreJAX-WSclientproxiesthreadsafe?) "对于许多使用情况,CXF代理是线程安全的。"有关详细说明,请参阅文档。 - Joern

4
如果您正在使用jax-ws,则不能在线程之间共享端口(它们不是线程安全的)。如果您担心创建端口的开销(并且已经测量并确认它是应用程序的瓶颈),那么您可以创建一个端口连接池。

我在CXF网站上读到它们不支持线程安全,但是提供了一个线程安全的getPort方法...但是我使用的是Metro stack JaxWS。那么创建服务可能会是一个繁重的操作吗?(我将开始进行一些测试,但不想重复造轮子) - Cris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接