论webservice的设计、应用和发展


[摘要]
       当前,软件运行环境越来越复杂,分布式应用、跨平台交互、软件间的整合应用都给软件的设计带来挑战,如何应对这些挑战呢?web service为我们提供了一种解决方案。

      本人作为我们产品研发的负责人之一,担任了产品的系统分析和设计工作,并亲历了整个项目开发的过程。本文着重讲述在这个过程中我们是为什么要选择web service,如何设计web service,又是如何应用web service的。在这个过程中我们遇到了一些问题,我们是如何克服的,本文最后总结了产品研发的经验,以及本人对webservice发展趋势的看法。

[正文]
       我公司研发了一套企业应用产品,这套产品首先要整合我公司已有的一款版本控制产品,组成一套SCM企业配置管理软件,由于版本控制产品是用vc++和java写的,而新产品由于集中数据\业务分布处理以及部署成本等各方面的考虑,决定用asp.net 和c#编写为Browser/Server的架构,这样就碰到了跨语言的问题,新产品需要提供API给版本控制产品,考虑到跨语言不能直接进行对象访问,我们采用web service作为api,这样就将自己的产品整合起来了.
        我们产品同时还需要给客户的其他产品提供api作为外部录入数据,查询数据的接口.而客户已有产品可能是运行在非windows平台上的,也很可能是用其他语言编写的,这样我们最合适的方案就是采用webservice将相关编程接口开放.用户可以根据我们的开发文档,做好他们想要的任意产品的整合.实现平台无关语言无关的要求.
      在我们做了充分的需求分析后,决定按以下流程实施web service层的开发:
      1, 成立软件设计小组,负责软件的概要设计和详细设计,包括web service层的设计和应用层设计.
      2, 制定webservice开发计划日程.
      3, 有专门的小组负责webservice的开发.
      4, web service应用测试及系统集成测试.
      5, 发布webservice,总结工作,安排后期维护
      
      web service层的设计离不开低层的支持.整个系统是一个整体,web service可以说是低层业务逻辑API之上的一个应用层,而且webservice一旦开放接口的变动需要最小化,所以由设计小组统一设计软件,加强不同层之间的接口设计.尽量实现层之间的低偶合和接口的稳定.要求低层先设计接口,web service层做到低层接口的适配器,web service方法通过适配器调用底层的Business API,这样就更好的实现了层的独立性。

     由于数据的准备和业务逻辑的实现都是底层business api或者web service调用端提供,所以我们前期的webservice开发都是基于模拟数据的,这样就既要考虑本身并行开发的进度,在底层开发的同时开发web service应用层;又要考虑关键路径的进度,降低串行工作进程的可能,使底层开发的进度尽量不影响web service层的开发进度。

     由于以前的产品没有webservice开发的经验,我们只能边学边开发,成立了web service小组是为了更好的学习,更好更快的解决问题。为了使webservice更易用,我们写了很多wsdl对方法描述。使方法的调用者更清楚方法的作用和使用方法。并且我们尽量简化ws对外接口的复杂性,让参数简单,方法间的耦合最大程度的降低,尽量实现一个方法一块完整的功能。开发中,不断学习新思想,对ws的设计采用了一个入口,路由分发的策略,使调用者不需要在大量方法中查找哪一个才是最合适的方法。同时,对于ws传输大数据量也有新的尝试,我们采用了ws-attachments的规范,
使用直接 Internet 消息封装 (DIME) 发送和接收带有附件的 SOAP 消息的方法。不必将大数据量的文件转化成数据量更大的base64编码,解决了附件传输的问题。根据 Microsoft 和 IBM 向 Internet 工程任务组 (IETF) 提交的规范,DIME 用于以类似于 MIME 的方法封装 SOAP 消息及其相关附件。象 SOAP 一样,DIME 消息可以使用标准传输协议(如 HTTP、TCP 和 UDP)来发送。DIME 支持对数据进行流处理。

      对于webservice开发小组的单元测试,基本上是使用demo客户端模拟数据提交,后台模拟返还数据的方式测试的。这个测试主要是测试方案的可执行性,以及方案的安全性等。至于业务数据处理的正确与否需要在底层api开发测试的基础上,再做集成测试。

      我们的web service发布是分阶段的,规划是分三个阶段。首先是满足我们自己产品scm的内部不同产品间使用。这个阶段我们无须发布到外部网,仅在产品部署的内部网上使用即可。我们提供自动化的发布机制。

UDDI服务发布

在前一节中,我们已经通过使用WSDL这个工具将Catalog Service这个Web服务进行了结构化地描述。为了使更多的潜在用户能够发现这个Web服务,同时也为了加强这个Web服务的互操作能力和灾难恢复时的连接保持能力,我们需要使用UDDI SDK将这个Web服务注册到UDDI注册中心中去。

假设我们之前已经注册了一个businessEntity,叫做www.sagitta.com,一个在线服务提供商,这个businessEntity 的键值是"434554F4-6E17-1342-EA41-36E642531DA1",那么我们要在这个businessEntity下注册一个 businessService,以用于描述前面的Catalog Service。同时需要成立的假设是我们也预先注册了一个Service Type(tModel),这个tModel描述了我们这个需要发布的Web服务的调用规范,具体内容是前面我定义的这个WSDL文档,在UDDI中,注 册的是描述的链接。

businessService注册的SOAP消息如下,其中使用了Microsoft的test.uddi.microsoft.com站点,因此authInfo中可以填入测试用的udditest。

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
<save_service generic="1.0" xmlns="urn:uddi-org:api">
<authInfo>udditest</authInfo>
<businessService businessKey="434554F4-6E17-1342-EA41-36E642531DA1" serviceKey="">
<name>categoryService</name>
<description xml:lang="en">Online Web Service for Catalog</description>
<bindingTemplates>
<bindingTemplate bindingKey="" serviceKey="">
<description xml:lang="en">categoryService's BindingTemplate3</description>
<accessPoint URLType="http">http://www.sagitta.com/catalog/</accessPoint>
<tModelInstanceDetails>
<tModelInstanceInfo tModelKey="uuid:E31A569A-AEFF-4468-BA4D-2BF22FE4ACEF">
<description xml:lang="en">Sagitta Web Service Type Description</description>
<instanceDetails>
<description xml:lang="en">Sagitta Web Service Type Description</description>
<overviewDoc>
<description xml:lang="en">Sagitta Web Service Overview</description>
<overviewURL>http://www.sagitta.com/wsdl/savecategory.wsdl</overviewURL>
</overviewDoc>
</instanceDetails>
</tModelInstanceInfo>
</tModelInstanceDetails>
</bindingTemplate>
</bindingTemplates>
</businessService>
</save_service>
</Body>
</Envelope>

通过上述的API调用,我们就已经把这个服务注册进了UDDI注册中心,其中bindingTemplate的accessPoint是服务的入口,而overviewDoc中的overviewURL是WSDL文档的访问位置。

潜在的使用者可以通过查询UDDI注册中心找到这个Web服务,通过overviewURL中保存的URL找到服务的描述,然后通过accessPoint所指定的访问地址来访问这个服务。

当发生紧急服务崩溃的时候,Web服务可能被迁移到另一台主机上,IP地址,甚至是访问的URL都可能有很大变化,此时原先的集成的连接将不再工作。但是由于UDDI注册的存在,我们可以通过自动化的程序手段来解决这个问题,使得类似的服务灾难恢复的过程非常迅速。

具体的流程一般是:

  • 当恢复的服务启动后,自动去更新UDDI注册中心上的数据,将访问入口修改到新的URL位置;
  • 连入的客户端系统当发现无法访问最终服务的时候,将会定期去查询UDDI注册中心,看看新的BindingTemplate数据和本地缓存的有没有差别,如果有的话,就下载到本地,重新建立服务绑定,完成服务连接的迁移。

    
然而在开发过程以及后期的应用中我们发现,我们的这种方案开发难度大,要自己解析转义一些东西。而且在每次客户部署或迁移后都需要重新配置发布ws,这个使用带来了很大的不便。解决办法就是hosting服务,我们这里做服务中心,那么不管客户如何迁移,只要我们不迁移,客户的应用就不必重新配置。

posted on 2006-10-16 10:06  Michael J  阅读(1351)  评论(0)    收藏  举报