在 IBM Bluemix 云平台上开发并部署您的下一个应用。 引言SOAP最初是作为一种通过 HTTP(Internet)进行同步RPC调用的简单方式出现的,但是后来它发展成可以通过多种协议进行同步和异步RPC调用。 在过去的几年中,企业级应用使用异步传输已经成为了一种趋势。从可靠性处理的角度来看(也就是重发、超时和复制检测),与异步传输分离能够使应用程序具有更好的可伸缩性,并且简化了应用程序中的处理逻辑。因为Web服务是一种快速集成应用程序的技术,所以将现有的企业应用公开为Web服务(服务提供者)已经成为了一种趋势。这样的服务的客户(服务消费者)可以访问这些具有多层可靠性的服务,取决于访问服务所用的协议。 当通过HTTP访问这些服务时,在传输层可以得到有限的保证,并且客户端应用有责任检查超时、重发和复制检测。对于访问响应时间有限的短期业务流程的低容量应用而言,这是一个低成本的解决方案。因为应用必须处理的事情不只是业务逻辑,所以在多应用中传输的低成本被重复实现的复杂性所抵消。 不过,当通过可靠异步传输访问服务提供者时,服务消费者应用可以减少它的某些责任,因为面向消息的中间件(Message Oriented Middleware,MOM)代表该应用处理这些问题,因而应用可以更多地关注业务逻辑。在将遗留MQ应用(支持 fire和forget模型)公开为服务提供者时尤其如此。 基于异步传输的SOAP是一种应用模式,它由于种种原因而赢得了大量的关注,比如长期的业务流程、服务提供者和服务消费者的松散耦合(从服务可用性和组件边界点的分离的角度看)、增强的服务可伸缩性使异步模型执行路径的长度缩短。可以通过两种方式使Web服务的可靠性提高,第一种方式是在SOAP消息本身使用确认(例如,ebXML),另一种方式是在比HTTP更可靠的传输中携带SOAP有效载荷。本文档的重点是,展示为通过异步协议(如Series)携带SOAP有效载荷设计的可选方案,不过,相同的理论可以应用到其他MOM厂商的产品。 本文档假定您基本理解Web服务堆栈和WebSphere MQ。
使用第一种方法,绑定应该是WebSphere MQ或JMS吗?没有工业标准方式来扩展WSDL绑定, 而不同的厂商正在通过把本地传输协议绑定到传输协议中来实现WSDL扩展,不过,与此同时,基于JMS的绑定应该是一种可行的方式,而且Apache的WSIF接近于为这样的绑定指定XMLSchema。参见参考资料部份可以获得更多关于WSIF的更多信息。但是,更困难的部分在于工具(java2wsdl和wsdl2java)的可用性,这两种工具可以用于生成处理异步传输的stub和skeleton,而在当前的WSIF中,这两种工具是不可用的。 第二种方法的例子是Apache的Axis框架(framework),它允许在客户端和服务器锻连接处理器。第三种方法的例子将在本文中提及(参见参考资料)。
在本文中,我们的兴趣在于评估单向和请求/应答通信模式的设计实现。要求/响应、通知和pub/sub模型是超出了本文讨论范围的传输方式。体系结构中与安全性相关的细节将在下一篇文章中进行讨论。 体系结构下面展示了Axis所用的通过SOAP over HTTP建立调用服务的方式。Java2Wsdl工具生成带有HTTP绑定的WSDL。Wsdl2Java工具生成客户端应用所需的stub和服务器端所用的skeleton。 当客户端实现进行RPC调用时,stub会将请求编组并使参数序列化。与此操作有关的其他问题是Java编程语言类型的编码方式和 XML类型的编码方式之间的转换。WSDL将成为服务的组件接口。这一部分将分析上述三种设计方案中头两种。 方案
SupportPac为Apache Axis Web Services框架提供插件传输,并且允许在客户端和在这些环境的某一种中编写的服务之间进行基于WebSphere MQ传输协议的互操作性。 客户端程序通常调用适当的Axis框架。stub把该调用编组成SOAP请求消息,和SOAP/HTTP完全一样。 当stub标识URI [wmq:xxx]时,它调用MA0R SupportPac中所提供的WebSphere MQ传输发送者代码。然后将其传送到也是由MA0R提供的侦听者。此侦听者阅读传入的SOAP请求,然后将其交给适当的Web服务体系结构。该体系结构调用服务,方式和为基于HTTP传输协议传入的消息所做的完全一样。 它然后将响应编组成SOAP响应消息,并且把它送回到MA0R侦听者。该侦听者将通过WebSphere MQ传输的消息送回到MA0R发送者,MA0R发送者再将它传送到客户端Web服务体系结构。客户端体系结构解析响应SOAP消息,然后将结果送回到客户端应用。
这个方案利用Axis框架Flexible Transport(灵活传输)的特征,而不利用WSDL扩展。下图展示了该方案的体系结构。 在这种情况下,没有stub/skeleton生成。客户端将会把传输处理器设置为在应用中进行调用,并且使用SOAP
API调用Web服务。
分析对于特定的问题描述,这一部分比较两种解决方案(根据前一部分确定的两种可选方案而提出的)的部署、客户端实现、执行和操作的难易程度。注意到消息传递是持久化的而最优化客户端代码可以获得更好的性能(指出了可以应用这些的地方),这一点很重要。使用非持久化WebSphere MQ比使用HTTP更昂贵,因为它没有提高可靠性特征。 问题描述
清单1. SimpleTransformation public class SimpleTransformation { public int setupTransformation(byte[] b1, byte[] b2) throws Exception, SAXException,TransformerConfigurationException{ // Instantiate a TransformerFactory. tFactory = TransformerFactory.newInstance(); // convert the incoming byte array to InputStreams ..... ..... InputSource isource = new InputSource(is2); Source source = new SAXSource( isource ); Result result = new SAXResult( serializer.asContentHandler()); //transform transformer = tHandler.getTransformer(); transformer.transform( source , result); return 1; } } 试验设备
实现客户端 清单2. 客户端代码片断 public class WMQClient { public static void main( String[] args ) throws IOException, javax.xml.rpc.ServiceException { // Must register WMQ transport extensions before doing SOAP/MQ com.ibm.mq.ma0r.usage.Util.registerExtensions(); Options opts = new Options( args ); int result=0; byte[] b1; byte[] b2; try { // Use the locator to get a handle to the service on a specific WSDL Port SimpleTransformationService locator = new SimpleTransformationServiceLocator (); SimpleTransformation service= locator.getJavaDemosServerSimpleTransformation_Wmq(); /* Convert the data in .xml and .xsl file to byte array to be passed *to the web service */ ..... ..... result = service.setupTransformation( b1,b2 ); } catch ( Exception e ){ System.out.println("\\n>>> EXCEPTION WHILE RUNNING ProxyClient DEMO <<<\\n"); e.printStackTrace(); System.exit( 2 ); } } } 注意:The 在调用Web服务之前,生成的stub使用base64编码对SOAP有效载荷进行编码。如果再没有编码之前就发送SOAP有效载荷,将会对性能造成很大的影响。 执行
现在,可以执行客户端程序以访问“SimpleTransformation”Web服务。 优点和缺点
方案
清单3. 用于服务提供者的WSDD <deployment xmlns="http://xml./Axis/wsdd/" xmlns:java="http://xml./Axis/wsdd/providers/java" name="TransformationService"> <service name="SimpleTransformation" provider="java:RPC"> <parameter value="javaDemos.server.SimpleTransformation" name="className"/> <parameter value="*" name="allowedMethods"/> </service> </deployment>
5. 将“SimpleTransformation”的WSDD文件部署到Axis引擎java org.apache.Axis.utils.Admin server SimpleTransformation.wsdd中[使用java org.apache.Axis.utils.Admin服务器] 清单4. 用于消费者的WSDD <deployment xmlns="http://xml./Axis/wsdd/" xmlns:java="http://xml./Axis/wsdd/providers/java"> <handler name="JMSMQSender" type="java:javaDemos.jms.JMSSOAPSender"/> <transport name="JMSTransport" pivot="JMSMQSender"/> </deployment>
7. 要部署客户端WSDD,请执行以下命令: 实现客户端 清单5. AXIS客户端代码片断 public static void main(String args[]) { // Method Name to invoke for the Web Service String methodName = "setupTransformation"; /* Read the files .xml and .xsl and convert them into byte * arrays to be sent to the Web service */ ... ... JMSTransport transport = new JMSTransport(connectorMap, cfMap); // Create the Service call Service service = new Service(); Call call = (Call) service.createCall(); QName qname= new QName("SimpleTransformation", methodName); call.setOperationName(qname); call.addParameter(new javax.xml.namespace.QName("", "byte1"), new javax.xml.namespace.QName( "http://www./2001/XMLSchema", "base64Binary"), byte[].class, javax.xml.rpc.ParameterMode.IN); call.addParameter(new javax.xml.namespace.QName("", "byte2"), new javax.xml.namespace.QName( "http://www./2001/XMLSchema", "base64Binary"), byte[].class, javax.xml.rpc.ParameterMode.IN); call.setTransport(transport); call.setReturnType(XMLType.XSD_INT); result = call.invoke(new Object[] { b1, b2 }); ... ... } 执行 清单6. JMS provisioning def qcf(MQ_JMS_MANAGER) qmgr(MQJMS.QManager) press Enter def q(JMS_RequestQueue) qmgr(MQJMS.QManager) queue(RequestQueue) press Enter def q(JMS_ResponseQueue) qmgr(MQJMS.QManager) queue(ResponseQueue) press Enter 现在,我们已经将队列绑定到JNDI对象中。 性能性能研究只针对响应时间而不针对吞吐量。假定客户端是单线程模型。 响应时间
不出所料,最初的JVM启动时间和类的装载对数量少的请求有高的开销。随着请求的数量的增加,这种情况得到了缓解。纯HTTP的情况显示了良好的可伸缩性,表明它也可以用于大容量的通信。 结束语根据上面的讨论,两种方法都既有优点也有缺点。新的标准还在不断地涌现,而部署的简易性也在日益提高。HTTP是一种更快速和更便宜的解决方案,但是在节省时间和成本的同时损失的却是可靠性。建议在可靠性不是非常重要的情况下使用HTTP,例如,报告消息而不是数值方面的事务。HTTP的可伸缩性也表明,它可以用于高容量的应用。与HTTP相比,在持久化MQ消息上携带SOAP有效负荷有将近60-80%的额外开销。WSDL生成器简化了客户端代码,同时也使部署更容易。从操作的角度来看,两种方法没有什么大的不同。Axis适配器添加处理器(例如验证)更容易。从互操作的角度来看,接口的设计是非常重要的,而很好地理解参数编码也相当关键。 |
|