在我的应用程序中,我们有一个名为getFoo()的webservice方法,它返回一个Foo对象。 getFoo()方法每秒调用几百次。 Foo对象使用Apache CXF从我们的Java对象编组到SOAP XML响应。
通过分析我们的应用程序,我们确定该对象的编组(java对象 - > soap编码的xml)是CPU周期的最大消费者。并且因为我们的Foo对象不是经常变化,每次都不需要重新编组这个对象。
我认为这是一个常见的优化,并想知道其他人如何解决它。 我简要地看了一下CXF文档,还有一个我可以使用的Marshall拦截器。我可以创建一个可以将Foo对象映射到XML编码版本的Map。但是,还有一些其他的问题出现了,如果不再需要它们如何从这个地图中删除对象等等。如果内置支持以某种方式检测对象的更改并重新编组,那就太好了。没有什么不可能,但不想重新发明轮子。
编辑(6/16/09):通过制作自定义BareOutInterceptor并修改拦截器链以调用自定义链来取得一些进展。自定义添加了一些额外的逻辑,只调用“writeParts(....)”方法,该方法仅对给定的java对象执行一次编组操作。完成后会发布解决方案。另外,我重新命名了这个问题。
答案 0 :(得分:3)
好的,不完全是您正在寻找的答案,但无论如何:REST在具有高流量的Web服务中使用的原因(例如Google)是REST被设计为可缓存的 - 而SOAP并不是设计为可高速缓存的。
SOAP基本上是基于(每个HTTP定义)不可缓存的POST请求,而REST使用GET - 这很容易缓存。
在进入实际Web服务之前,您必须检查SOAP(POST)请求,即使用代理。 “标准”代理通常不了解SOAP语法。
IBM's WebSphere Application Server though can do that
此致 奥拉夫
答案 1 :(得分:0)
SOAP中没有严格的要求您需要使用像CXF这样的框架来处理服务器或客户端SOAP端点。当使用基于Axis 1.4的SOAP客户端与基于Axis 1.1的服务器通信时,我们遇到了客户端线程死锁,并通过抛弃Axis并在手写代码中发出请求来修复它们。我们不得不撒谎到Axis服务器,告诉它我们还有一个Axis客户端,但感到没有悔意! ; - )
同样,您应该能够绕过CXF并在您自己的手写java代码中生成SOAP响应。然后,您可以使用Map缓存已编组的(未解析的,序列化的)XML字符串并消除此热点。
非常赞同Olaf关于REST:如果你充分利用HTTP,那么所有这些缓存都会在服务器和客户端之间的所有中间缓存中免费发生。对于新服务来说,这当然是值得考虑的事情。
更新:CXF具有可自定义interceptor chains的概念。一种类型的出站拦截器用于MARSHAL阶段,所以听起来你可以在那里添加这个缓存,而不必抛弃CXF。或许CXF专家可以为我们验证这一点吗?
答案 2 :(得分:0)
使用Apache CXF将Foo对象从我们的Java对象编组到SOAP XML响应 .. CPU周期的最大消费者。由于我们的Foo对象不经常更改,因此每次都不需要重新编组此对象。
客户端应用程序是否需要立即或尽快知道Foo中的更改?
为什么不将它缓存在消费者/客户端?您每秒数百次调用相同Web服务方法的设计可能不是最好的。