JAX-WS中的异步Web服务调用:使用wsimport支持异步还是自行开发?

5
这里有一篇优秀的文章 by Young Yang,讲述如何使用wsimport创建具有异步Web服务调用的Web服务客户端工件。 异步性要求WSDL在其绑定部分中具有标记

<enableAsyncMapping>true</enableAsyncMapping>

如果您使用带注释的JAX-WS Java类的自下而上方法,则无法直接在WSDL中执行此操作,因为WSDL是Web服务器上生成的工件。 相反,您可以使用构建工具(如Ant或Maven)在对WSDL执行wsimport时包含此绑定。

生成的客户端工件具有异步方法调用,返回一个

Future<?>

或者一个

Response

这是一个Future。

在阅读杨的文章后,我的问题是为什么不使用Executors和Futures自己编写异步Web服务调用。 wsimport创建的工件是否比自己编写的方法具有某些我看不到的优势?

如果有人对两种方法都有经验或见解,我将非常感谢您的反馈。


此帖子提到的文章现在可以在此处查看:https://web.archive.org/web/20081103104132/http://today.java.net/pub/a/today/2006/09/19/asynchronous-jax-ws-web-services.html - ab853
2个回答

12

理论上,生成的异步客户端不需要阻塞线程。通过传递AsyncHandler,系统可以使用NIO在web服务调用完成时注册事件,并调用该处理程序。根本不需要阻塞任何线程。

如果将同步的web服务调用放入执行器中,它仍然会阻塞一个线程,直到结果到达,尽管这种阻塞至少被限制在执行器的线程池中。

一旦有数百个线程漂浮在周围,由于上下文切换,系统性能将降低。

底层的web服务库是否实际使用了NIO是另一回事。JAX-WS规范似乎并不要求使用NIO。我使用JDK 1.6并在服务器端设置断点后,启动了100个客户端来调用服务器。使用JVisualVM连接到客户端,我可以看到它为每个对服务器的调用创建了一个新线程。太差劲了!

在网上搜索后,我发现Apache CXF支持限制异步调用中使用的线程池数量。果然,使用CXF生成的客户端,并将讨论此处的正确库放在类路径上,重新测试显示只使用了25个线程。

那么为什么要使用jax-ws API而不是构建自己的API呢?因为构建自己的API需要更多的工作;-)


10

我知道这并不是提示问题的答案,但只是补充其中一个包含在问题中的信息:

“相反,您可以使用构建工具(如Ant或Maven)在执行WSDL上的wsimport时包含此绑定。”

通过向wsimport添加自定义xml文件使用选项-b,可以生成异步客户端:

例如:

wsimport -p helloAsyncClient -keep http://localhost:8080/helloservice?wsdl -b customAsync.xml

自定义Async.xml内容:

<jaxws:bindings
        wsdlLocation="http://localhost:8080/helloservice?wsdl"
        xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
        <jaxws:enableAsyncMapping>true</jaxws:enableAsyncMapping>
</jaxws:bindings>

这只是使用 ant 或 maven 以外的一种生成异步客户端的方法 :)


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