`
sangei
  • 浏览: 336562 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

浅谈Soap/Web Service架构及其应用(转)

    博客分类:
  • SOA
阅读更多

       概述:随着计算机网络时代的到来,Internet/Intranet无可避免的成为现代商业信息化发展的必要趋势,而基于原有的局域网及企业内部网络的 二层式甚至是单机式的信息服务结构已经不能满足现代商业社会的需要,分布式应用技术自然而然成了主流的开发技术。本课程设计主要讨论Soap/Web Service架构方式、原理及其在分布式开发中的应用技术。
由于Internet/Intranet是一个多元化的计算环境,是由各种不同的实 现技术提供的服务以组成一个网网相连的集成计算环境,那么必须使用大家都接受的标准,来集成彼此的服务,Soap和Web Service就是在这种需求下产生的标准,而且迅速地成为大家都接受的开放标准。
可以看到各个知名的软件厂商的最新产品都把Web Service做为未来重要的技术来全力发展如:MicroSoft的Dot Net战略根本就是围绕WebService展开的,Inprise的Delphi Studio也把Soap/ Web Service做为重点,像Sun,IBM等厂商也以最快的速度为自己的产品中加入了对Soap的支持。所以可以预见Soap/ Web Service 是今后软件发展的必然趋势。

名词解释:
Soap: (Simple Object Access Protocol) 简单对象存取协议,1999年W3C组织公布的用于标准远程对象调用通用格式,以XML形式提供了一个简单、轻量的用于在分散或分布环境中交换结构化和类型信息的机制,目前最高版本1.2。
Web Service: 一个比较抽象的概念,它把以往在Web上应用的面向程序设计的概念,转变为面向服务型的概念,与具体的软件操作平台无关,与服务器、客户端编写的程序语言无关,即不注重以什么技术来实现Web解决方案,而是关心提供什么样的服务让客户端调用。
XML: (eXtensible Markup Language) 扩展型可标记语言。是国际标准化组织的标准通用标记语言 SGML 的子集。SGML 面向诸于飞机设计文档的大规模、长生命周期的信息储存,XML 则面向短期的临时数据处理、面向万维网络;二者是相互补充的关系。它是Soap的基础。

Soap原理:
通过阅读W3C网站中关于Soap的介绍说明(http://www.w3.org/TR/soap12-af/),我们可以了解到以下几点:
① Soap其实是一个建立于HTTP上的上层协议(Wire Protocol电报协议,这里我觉得用上层协议更好一些)
② 使用Soap的目的是定义如何调用远程终端的中的服务(方法)。
③ Soap中用多个NameSpace标准来区别各个远程服务。
④ Soap中不仅可以封装简单的数据类型,还可以封装更加复杂的数据类型,如Struct(C或C++)、Record (Pascal)等。
(P.S.由W3C网站上所提供的文档,我们可以了解到Soap封包的标准格式如下:
HTTP报头(例如:POST /PWSDMO1.EXE/SOAP HTTP / 1.1)
SOAPAction标签(指明了封包SOAP欲进行的工作。如:SOAPAction: “urn:FirstWSIntf-IFirstWS”)
CR/LF标签(指明封包中XML的版本及编码所使用方法。如:<?xml version=”1.0” encoding=’UTF-8’?>)
SOAP-Env:这里可以保存多个报头元素,即多个命名空间。用<SOAP-ENV:Body>开始,</SOAP-ENV:Body>结束
SOAP封包内容
)

所 以有人说:Soap就是XML加HTTP。这描述虽然不准确,但的确可以概括Soap的基本意义。了解一项技术的原理,最好的方法莫过于站在一个开发它的 工程师角度来看这项技术。要实现基于Soap的架构,首先我们要知道数据是如何通过Soap传递到远程服务器端的,其大致流程如下:
首先,由客户 端程序提出申请服务的要求,这个要求将被传递到客户端的处理机中,所有的申请的方法及方法所需要的参数被打成符合服务器服务标准格式的Soap封包中(即 一个符合服务器服务标准格式的XML封包),这个封包通过HTTP协议传送到服务器端,然后由服务器的XML解析器将Soap封包转化为客户端申请的方法 名及所有参数,再由编译器所提供的RTTI (RunTime Type Information)对应找到被申请的方法所在的调用堆栈地址,由服务器执行所需方法,再将方法返回的结果集通过处理机打包成XML封包传递回客户 端,由客户端解析器将结果解析输出。


知道Soap的大致流程后,我们可以发现Soap的原理十分简单,实现它也比较容易,但这里基本上可以发现存在三处比较关键的技术需要解决:
1、 如何将数据打包成标准XML封包及它如何在Internet中安全的传送?
2、 服务器编写的语言如何与Soap封包间的互相转换?
3、 客户端如何了解服务器中所提供哪些服务及服务所需要的参数?
就 第1个关键技术,现在已经有许多种现成的技术可供使用,比如IBM的XML处理引擎,MS的XML COM等,需要注意的是如果选择MS的XML COM,你将无法向Window以外的平台扩展。(Delphi6的Soap开发工程师Rick Nadler就犯下这个错误,导致现在的Kylix的Soap解决方案要重新撰写J)。
第2个关键技术是如何将Soap封包中所申请的方法转换为 调用堆栈中的地址,这项工作非常底层,已经属于编译器技术的范畴,所以在这里只作简单描述:在客户端由编译器通过处理RTTI取得客户端运行期的属性,将 其传送给处理机打包。服务器端通过RTTI找到客户端所需的服务地址,调用堆栈及传递参数。

第3个关键技术是前面没有提到过的,客户端如 何知道服务器端提供什么样的服务,服务及参数的格式又是怎样的。打个比喻来说:客户去饭店吃饭,饭店服务员必须要让客户知道本饭店提供什么样的菜,每个菜 的价格,份量等信息,这就是菜单的作用了。Soap中也是一样的,没有菜单客户端根本不知道服务器端提供什么样的服务给它,服务及服务参数是如何规定的。
生 活中的这个“菜单”在Soap中就是“Web Method”表格,这张表格中定义了服务器端所用于Web发布的方法名称、方法返回类型、参数个数、每个参数的类型及其它关键信息,当每个客户端连接至 服务器后,服务器端都会把这张表格以文件的形式传递给客户端,客户端根据表格上的内容来调用相应的服务。
这种描述Web Service功能的机制就是所谓的WSDL(Web Service Description Language),它也采用XML语言来封装内容,它规定了如何把Web Service的服务表达在WSDL中以及WSDL的封包架构等。
如何传递WSDL到客户端,可以考虑的有三种方法:
1、 以用DLL输出函数的方法来指明程序编写人员希望向Web开放的方法(C++及Pascal用EXPORTS关键字),当Web Service 需要输出WSDL时,先解析这些函数才产生WSDL,这种方法相当费时。
2、 加入关键字,比如WebMethod,当编译器遇到WebMethod时就将其写入一个Web Service表格中,一旦程序编译完成,WSDL就已经形成,客户端可直接调用,执行效率会很好,接近于虚拟方法的效率。但加入关键字到编译器中,不是 我们一般设计人员能够做到的,也存在版权问题,对于MS或Inprise这些软件厂商自然是另外一回事了。
另外,WSDL是服务器端编译时产生的,客户端如何获取?客户端可以根据服务器端传过来的WSDL反向产生一个WebMethod的表格从而来调用,但这种方法会以损失一些效率为代价,并且客户端也无法在编译期检查对服务器调用语法中的错误。
这种方法可称为动态绑定(Dynamic Binding),即客户端需要动态解析服务器端的WSDL来获取WebMethod表格以供服务。事实上,Microsoft的Soap Toolkit2.0就是使用这种方式。
3、 这种方法是目前Delphi6及以上版本所通常使用的一种方法,我个人也比较习惯的一种方法,这就是接口方式。这是一种静态绑定方法(Static Binding)弹性上没有动态绑定好,但比较有执行效率。
静态绑定的原理是在服务器程序和客户端程序编译时都对进行接口注册(作用同利用接口直接产生WebMethod表格),这样服务器和客户端生成了同样的表格,客户端在编译时也可以校验对服务器的调用是否合法了。
每 个接口是一系列方法的合集,每个Web Service也可同时输出数个服务接口,这点非常符合面向对象程序设计的精神,同时对服务器端中的服务输出管理也非常方便。需要注意的是,对于其它语言 工具所产生的Web Service,或者在调用Internet上不知何人所写的Web Service时,客户端不可能存在WebMethod表格,这时只有使用动态绑定方式,通过WSDL反向产生接口,再通过注册接口机制在客户端形成 WebMethod表格。所以在使用Delphi开发的基于Soap三层组件模型时,会遇见首次连接时会比较费时,以后再连接时就会非常快的情况,其中一 个原因是因为连接缓冲池(Link Pool),另一个重要原因就是因为注册接口。
说了这么多,目的只是让客户端了解Web Service提供哪些服务给自己,并且如何利用WSDL封装方法及参数到服务器中,这时你会发现一个比较严重的问题,如果我并不知道服务器的URL,那 么就根本没办法从中获取WSDL,更谈不上什么如何定义封装格式了。换句话说,当软件开发人员需要分发/ 部署或是使用由其他人开发的Web Service时就会出现诸如以下的问题: 
1、 如何找到Web Service?
2、 如何提供Web Service让其他的人使用?
3、 某一个Web Service代表的意义和功能是什么?
4、 如何管理Web Service?
所 以,IBM、MicroSoft、Oracle和Sun等其他数百间公司便根据公开的标准定义了解决这些的功能规格,称作UDDI(Universal Description Discovery and Integration)简单的说UDDI就是一个公开的标准,用来以结构化的方式来注册、管理企业信息以及相关的服务信息。通过UDDI软件人员可以发 布或是搜寻企业以及Web Service信息,借以达成资源共享和集成的目的。
一般来说UDDI的服务是由所谓的UDDI运算节点(UDDI Operator Nodes)提供的,这些UDDI运算节点保证使用UDDI.org组织公布的UDDI标准来提供服务,每个UDDI运算节点中,是由三种组件提供其中有 关企业以及Web Service的信息,它们是:
l White Pages – 包含了企业名称、说明信息、联络信息以及一个标识符。
l Yellow Pages – 包含了企业的类。用户可以通过企业类迅速找到相关的Web Service
l Green Pages – 包含了企业对外输出服务的技术信息。也包含了指到实现此服务的Web Service的参考链接。
UDDI在实现起来比较复杂,也与本论题关系性不大(只是做为Soap扩展时使用),仅做一般描述,其它部分可参考W3C网站上关于UDDI的文章。

Soap/Web Service的实现:
Soap 和Web Service和其它基于三层架构的组件模型最大的区别(也是它最吸引人的地方J)在于它能够集成各种不同的平台和实现技术,并且跨越平台的限制。不管所 调用的服务器是运行于什么样的平台,用什么样的语言编写的。不管这些Web Service用Java实现也好,Delphi实现也好,甚至C++实现也好,或是运行于Unix的Apache,Websphere,Resign上 执行也好,我们都可以用任何语言去调用它。这一点对于企业级及企业间的商业平台有着不可估量的作用,比如:以往的银行、电信业务间通常使用Corba做为 其企业级中间件,不同系统之间的通信只能用称为“桥”的技术(Bridge)来解决,这些“桥”由软件厂商提供给开发者使用,而且不同版本间的Corba 也不兼容,一个桥只具有相对狭窄范围内的互通作用,这给开发者和企业带来许多不便之处。且Corba在防火墙问题中处理得也不好,CORBA 2.0 引入了“ORB 间协议”(Inter-ORB Protocol,(IIOP)),防火墙注意到这个新协议,并且有的时候就阻止 ORB 通信。IIOP 很快给 CORBA 带来一个不应有的难与防火墙一起工作的坏名声。
然而,SOAP 通过建立 HTTP 连接隧道来部署自己的协议:SOAP 要求把请求参数组织在 XML 文档中,该文档然后被放到 HTTP POST 请求体中发送到运行在 Web 主机基于 SOAP 的 Web 服务。同样,现在正在做很多扩展 SOAP 的工作,使它能使用其它的传输协议,例如 HTTPS 和 SMTP。
SOAP和其它组件关系图如下:















由 上图可知,调用Web Service的程序本身也与设计语言无关,与其运行的平台,只要Web Service中发布的接口符合W3C的标准,即可在世界任何地点,任何平台下对客户端服务。http://www.xmethods.com/ 这个网站上收集了全世界对Web Service有兴趣的开发者撰写的各种服务,每一个Web Service也都使用不同的技术来实现的,利用这些服务,开发者可以容易的使用别人已经完成的各种Web Service,真正实现了简化代码工作量的问题。
本人接触Soap不过半年的时间,利用Soap做的项目只有广东数字电视SMS系统、及与其配 套的数字电视视频加密主模块。深刻发现接触得Web Service这项技术越深越发现自己的浅薄之处,并且深信Web Service是未来软件行业的必然趋势,它必将像Internet一样以不可阻挡的势头成为主流开发技术。
在开发过程中(开发工具Delphi6+Oracle8i+Apache Soap Toolkit),当然不可避免的遇到一些困难,也走了一些弯路,所以在这里将自己的一些心得写下来,存在错漏之处,请各位多多提出批评、指教。
一、 Soap程序执行的效率问题。
前 面已经说过,客户端获得服务器的服务表格是通常有两种办法,一种是MS采用的动态绑定方式,另一种是Inprise采用的接口方式(静态绑定)方式。当然 通常情况下,两者之间的效率差别并不明显,但当服务器上提供的是一个中、大型规模的WSDL时,就会有明显的速度差异,所以,推荐能用接口注册(静态绑 定)的Web Service尽量用。
另一个因素是因为SOAP是一个通用的通信协议,因此没有某一个通信实体(HTTP、FTP等)进行最佳 化,所以尽量减少网络的Round-Trip及压缩传递的数据量是增强SOAP程序效率的最有效方法。我们知道基于HTTP、FTP等协议间的数据传送, 必须将二进制的数据流通过BASE64或MIME加码、解码,而经过这些运算后,会增加30%左右的数据量,如果不经过压缩处理,你的程序会变得奇慢无 比。解决办法,使用系统或工具中已有的压缩类进行ZIP或RAR压缩运算,ZIP或RAR对文本型数据压缩比是非常高的,通常情况是1:30,再进行 BASE64加码运算。等传送到服务器端时,反向操作一遍,即先进行BASE64解码运算,再ZIP或RAR解压运算获得原值。
现今的商业系统通常都要与数据库打交道,优化数据库查询语句、设置VCL组件的属性来获得程序执行效率也是一种非常有效的方法,下面是关于设置VCL组件的一些参考:
BDE / IDAPI ADO DBExpress
参 考 设定Tquery等组件的RequestLive属性为False,设定UniDirection为True 设定CursorLocation为clUseClient,设定CursorType为ctOpenForwardOnly。如果需要处理大量的数据, 那么可以设定CursorLocation为clUseServer,并且尽量减少CacheSize的设定值。 使用TSQLDataSet的只读和单向游标。
最后一点可以提高SOAP系统效率的办法是:尽量以一个封包封装尽量多的远程服务调用。这样做的好 处是:因为SOAP封包是以XML格式封装的,XML本身也占有一定数据空间,真正需要的数据有时候只有几十个字节,所以尽量封装尽量多的远程服务是为了 增加数据的使用率并且减少网络的Round_Trip,就像DCOM的QueryInterface接口一样,可以在一个远程调用的网络 Round_Trip中取得多个COM对象的接口。

二、 非标准型数据的传递问题。
根据W3C关于SOAP 1.2的说明文档,SOAP是可以封装复杂数据的,比如Struct、Record,甚至是图像、声音等二进制流数据。对于二进制流数据,可将其转换为 BASE64编码的文本,等数据到达目的地后再进行BASE64解码。这里就体现出上一个问题所提出的数据需要压缩处理的好处了,因为一个几百K的图像经 过BASE64处理后会变成硕大无比J。
对于处理结构型数据,需要进行SOAP封包类型的转换,现拿Delphi6举例说明:在Delphi6中 对应于封装和解装SOAP封包称作Marshaling和Unmarshaling,即将非SOAP允许的数据结构转换为SOAP允许的数据类型,这个过 程称为Marshaling。当数据传递到目的地后再从SOAP格式的数据恢复成复杂数据类型,应用程序才能够使用,这个过程是前一个过程的反向操作,称 作Unmarshaling。
在Delphi中对数据进行Marshaling及Unmarshaling操作极为方便,只需要从Delphi的 辅助类Tremotable和TremotableXS继承下来即可具有传递复杂类型数据的功能。需要补充一点的是,开发人员在使用这种自定义数据类型前 必须对其进行注册,Delphi6中提供两种方法:分别是RegisterXSClass和RegisterXSInfo。前一个方法是注册从 Tremotable继承下来的类,后一个不需要是从Tremotable继承下来的类。

三、 用Delphi开发Soap客户端程序的接口问题
通常做法是设置TclientDataSet组件的[RemoteServer]-[URL]及ProviderName属性来获取远程服务,这样做效率不高,可直接使用服务器统一的主接口IappServer的各种方法来获取数据,例如:
IAppServer = interface(IDispatch) [‘{1AEFCC20-7A24-11D2-98B0-C69BEB4B5B6D}‘]
function AS_GetRecords(const ProviderName: WideString; Count: Integer; out RecsOut: Integer;Options: Integer; const CommandText: WideString; var Params: OleVariant; var OwnerData: OleVariant): OleVariant; safecall;
上面这段代码是IappServer中的As_GetRecords方法的定义, 只要将其中的常量参数指定为某一个接口的TdataSetProvider即可调用该服务。

Soap目前的不足之处:
每一个技术不可能是十全十美的,就像程序中总会有BUG存在一样。SOAP也是如此:
l SOAP目前实现在HTTP / HTTPS通信协议之上,不过HTTP的这种请求/响应式模型并不一定适合所有场合,因此SOAP仍然需要定义其他的通信协议。
l SOAP需要XML解析器来处理封装的信息,但是每一种SOAP实现使用的XML解析器可能不同,这会造成一些使用DOM模式的XML解析器无法处理大量 的SOAP封包。此外这种解析器也可能使用大量的资源而造成系统沉重的负荷,降低SOAP/Web Service的延展性和执行效率。
l 目前SOAP的标准没有定义如何传递远程对象,因此所有的信息都必须转换为数值来传递,这会对一些应用造成降低效率的影响,以及在开发分布式Web应用系统中会产生一些问题。

显 而易见,SOAP和Web Service带来了新的应用、系统架构和契机,对于软件开发人员来说也是新的挑战,如何快速学习SOAP/Web Service并且根据企业的需求和现存的系统架构来集成SOAP/Web Service技术将是重要的工作。而对于非软件开发人员来说,学习了解SOAP/Web Service也是非常必要的,它不仅可以帮助你提高自身的水平,还能帮助你跟上新科技的脚步,为你的工作更加成功起着作用。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics