如何更好的构建服务层

日期: 2008-04-15 作者:Biffle French 来源:TechTarget中国 英文

创建”服务层”,该服务层提供容易的访问一系列的服务。那些服务全部将象Web服务一样可以被访问。 另外,通过入口访问服务的用户将只被要求验证一次,并且任何背景验证将被自动处理。   商业驱动和项目目标:   为了发挥作用,商业上需要充分利用现有的遗产系统。

他们已经投入了相当多的资金和长时期的开发和升级,才使得这些系统今天的样子。同时, 商业需要以当系统最初被建造时从未被预期过的方式,通过集成何重构这些已经存在的能力,来提高他们在技术能力。 改变的环境创造恒定的压力使得能去更好和更有效地做生意 — 经常的通过更少的人员来实现。   今天生意采取的通常的方法之一……

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

创建"服务层",该服务层提供容易的访问一系列的服务。那些服务全部将象Web服务一样可以被访问。 另外,通过入口访问服务的用户将只被要求验证一次,并且任何背景验证将被自动处理。

  商业驱动和项目目标:

  为了发挥作用,商业上需要充分利用现有的遗产系统。 他们已经投入了相当多的资金和长时期的开发和升级,才使得这些系统今天的样子。同时, 商业需要以当系统最初被建造时从未被预期过的方式,通过集成何重构这些已经存在的能力,来提高他们在技术能力。 改变的环境创造恒定的压力使得能去更好和更有效地做生意 -- 经常的通过更少的人员来实现。

  今天生意采取的通常的方法之一是将增加或者改进自我服务的能力。 自我服务是一个非常有效的省钱方式,因为它能可以减少调用核心成员。 但是,在调用核心设置的过程中有用的系统经常不足够自我服务,因为用户被需要培训从而可以知道怎样执行他们需要执行的任务。 很多遗产UIs是绿色的屏幕并且在"用户友好"的用户界面的科学上是居于领先的。

  我们的客户是一家大公司,它想把要面向服务的架构的承诺作为一种解决一个商业问题的方式来测试。 他们想要改进他们的在线的自我服务能力。 最初瞄准的用户是是在执行一个具体的工作过程中的专家的内部工人, 并且这些工人依赖一套各种各样的时代的遗产系统执行他们的任务。

  在许多情况下,用户必须登陆到一个系统,找到一个信息的项目, 然后登陆到另一个系统(使用一个不同的用户名/ 密码)并且使用那数据项作为另一查找的关键字。 这种方法的缺点很明显: 它是慢的,很难学习,它明显地在自我服务的领域不许诺任何事情。

  这项工程的目标是创建"服务层",该服务层提供容易的访问一系列的服务。 那些服务全部将象Web服务一样可以被访问。 另外,通过入口访问服务的用户将只被要求验证一次,并且任何背景验证将被自动处理。 因此从入口看来是简单的,无缝的和统一的, 即使在后台是复杂的,异类的和显然不统一。

  SOA架构型类型

  IBM SOA 架构型类型在后台的现有存在的系统和在前端的他们的最终用户之间增加了一个"服务层"。 这种方法的关键使能者是Web服务技术。

  "服务层"客户看到的是一个被设计好并且开发来满足商业需求的一良好定义的Web服务集。 供出售的那些服务基于(但是不不要地一定相同于)那些现有系统提供的。 服务层以最有用的方式来利用现有系统的能力。 然后,它重新装配,重新结合,组,是连续并且隐藏支持它的遗产服务的细节。

  让人不愉快的东西仍然在那里 - 并且它将总是会在那里 - 但是它被整齐的收起来并从视线中消失。

  以这种方式使用Web服务考虑到逐渐和控制的构建起来一个商业联盟的服务的集合,该服务集合具有机器可处理的服务描述。 那些服务描述以WSDL 文档的形式存放。 一份可以在服务层里得到的服务的目录可以被在一个注册处管理。

  当全部那些部分都在合适的地方的时,就可以开始看见一座面向服务的架构。

  Web 服务的PanDOORA

  服务层的细节任由实现来设置。 不过,象任何架构的选择一样,有更好的同时也就有一些也不是这么好的。 那些PanDOORA 架构模板推荐一种提供对一些相对结构化更小的但是更加简单来理解的设计的方法。

  最小的服务层只有3 个元素:

  ·知道如何对/从那些现有系统发送/接收消息的后端控制器。
  ·因为服务消费者可访问到的前端Web服务。
  ·在两种发送和引用类型之间转换的一个调解层。

  在3 种元素最简单的实现里实际上全部能被在单个的servlet的"doPost"方法来编码实现。 令人遗憾的是,以这种方法来实现它会伴随着产生一种不被希望的附带的耦合性,这种在元素之间的耦合保证了在全部代码中出现的波动的改变。

  任何最佳实践途径提供在"前端"和"后端"之间去耦合。 这使得那些实现者可以容易的使用它来替换或者修改一个部分而没有必要对这个部分进行重新编码。 因此如果优先的遗产系统经历了改变发送消息的细节的升级, 而前端(以及那些消费者)不需要知道这些或者处理这些。

  除在前端和后端去耦合之外, 那些调解元素也应该被从他们两个中分离,以便它可以按照要求被改变或者替换。 实际上,一些调解元素的责任可能由一个象ESB那样的单独的工具提供。 例如,服务提供商的实际版本和位置可能在ESB内被作为一个运行时决定确定。那样的话,改变一张桌子可以导致另一个选择。 在一个基于消息的寻路的例子里,初始请求的细节可以导致一种不同的类型的反应- 也许流通或者语言的选择。为无限的价值增加的最大灵活性和机会要求那个层被完全分开。

  PanDOORA是一个架构的模板。 它不提供代码,而是给设计提出指导。通过为一层服务层提供一个模板,Web服务的PanDOORA能够帮助设计者。 这个层有6 种元素。 在具体的实施里,每种元素通常都是一种单个的java类,虽然这不是一个限制,只是推荐的实践。

  Requestor Adaptor知道怎样访问基础的系统。

  Requester代理从Requestor Adaptor分离出商业服务。

  商业服务包含全部业务逻辑。 把业务逻辑放在商业服务外边一般是一个很不好的实践

  Provider Adaptor是一个真实的Web服务。实际上,这可能是SAAJ 类型的Servlet,或者被自动产生的JAX-RPC SEI 扩展的一个Java Bean。

  提供者代理人从商业服务分离Provider Adaptor。

  客户代理寄存于客户并且知道怎样访问Provider Adaptor 的Web服务。 取决于具体情况,客户代理可能被Provider Adaptor的实现提供,或者它可能被从提供的WSDL 产生。

  各种各样"协议"是描述价值对象的Java接口包含被从一个层传输到下一层的参数,这导致更进一步的耦合。 我们接下来讨论实现协议的选择。

  因此逻辑流程是入口调用一种导致一个Web服务引用的客户代理的方法。Provider Adapter在服务层处理Web服务引用, 它建造一份协议并且使用它来在Provider Agent上确定一种方法的参数。Provider Agent使用一份协议(也许相同的一个,我们将看见)来确定关于商业服务一种方法的参数。商业服务建立一份发送给Requestor Agent的一份协议,Requestor Agent轮流地跟随Requestor Adapto的相同的方式。 那些Requestor Adaptor访问那些实际的遗产系统,返回那些基于链的反应和最终地穿过那些网络达到那些远端的客户。

  那些PanDOORA 模板描述一种非常灵活的方法,该方法允许可以使完全和使正式化的分离那些具有3 个基本元素的耦合。 任何这3 个可以被替换或者更新而不用知道其他两,除非有一个需要提供另外的能力或者处理新参数。

  服务层实现考虑:

  真正的实现需要考虑下列因素:

  线程模型

  当后端系统正被访问时候,在管理Web服务调用的servlet内的线程不能被引用。 那样做将锁住属于一台应用服务器的有价值的并且有限的资源。如果因为任何的原因后台系统不能响应, 或者即使响应的时间刚好在"正常"范围内,整个服务器或者群的表现性能将会明显的受到影响。 一单独线应该用来访问后台系统。

  协议方法

  有至少两个在层之间的协议怎样构建至少有两个选择。 一个选择是每个层能有它自己的ContractInterface 和ContractImpl。 那种方法的结果是在层之间的用参数表示的是明确和良定义的。 这方法的优势是程序错误一般将不被编译和协议也容易理解。这种方法的不利条件是, 它要求代码创造不同类型的协议并且在每一层从请求协议到提供协议复制参数- 一会儿从上往下和一会儿又倒过来。 那可能非常乏味。 它也导致昂贵的维护,使得参数化表示十分复杂,并且可能经常改变。

  另一种选择是使用一个一般的有效载荷对象, (例如HashMap)和把恰好相同的对象往下传并且倒退这个堆栈。 在每个层的对象收到有效载荷并且按需要选择性地读或者写它。 这方法的优势是从不会要求层的改变,从而不需要修改参数 – 就是刚刚把他们递给下层的那些参数。因为有效载荷是一般的,不利条件是可能没有编译时间来检查用参数表示的在请求者和提供者之间是否适合。 如果你想要一些不在那里的东西,或者如果它在那里并且它是错误的类型,你只能通过测试找到它的缺点。 错误直到运行的时候才会明显表现出来的。 有些时候看起来似乎是可以工作的,直到代码产品化了才能发现错误。

  验证

  安全是服务层实现的一个非常大的题目,并且对于一篇象这样的短的文章来说这个题目的范围太宽了。 因此我将讨论它的最明显的方面 - 用户验证。

  如果服务层将具有大的价值,它需要提供一个类似的验证方式。 一个典型的目标将是使得授权认证决定不管怎么都能客观化,从而服务层能自动地通过鉴于通用的验证模式的来管理。

  令人遗憾,我们通常看见的是一种更难的情况。

  遗产系统是人们在长时间里面建造的, 他们谁都不知道彼此,没具有共同目标,没理解企业级架构和对他们而言安全是一个最后一分钟的附加物。 因此,后台系统实现的那些各种各样的验证计划都是最后折衷的,因此很难把他们浇注成一个无缝的整体,而这就是服务层的目标。

  我们发现的遗产验证方式的包括标准大型机的RACF或者ACF,单个系统的用户名/ 密码仓库和甚至使用“信任IP”的方式。 信任IP是说如果你的IP 地址在他们的表格里,你就可以在他们那儿登陆访问。

  获得授权访问企业级系统的方式可以被分为两种类型: 及物的和具体用户。 在那些及物的方法里,那些入口自己就是那些企业系统的一个被授权的合法用户,而这个企业级系统会暗中的把他的授权事务委托给他的全权代表来完成。 一个典型的实现是创建一个具有全部的访问权限的用户并且把入口鉴别为那种用户。然后有入口来完成防止未被授权的进入的责任。 显而易见, 这是一种很弱的方法,并且只在折中的开销很低的和那些具体用户验证的费用高, 或者如果一种具体用户的方法完全不可行的时候可以被考虑。

  一种具体用户的方法可以被用几种不同的方式实现,这取决于系统要求什么样的目标。 我们试试的两个技术是重放映技术和第二张表技术。这两个方法都不是非常满足。

  在重放映技术这种中,入口偷去了验证服务器(在这个例子里面是Netegrity SiteMinder)产生的会话标志。 在服务层的请求中,它把这个标志作为参数传递,并且最终地过滤到在企业级系统的请求下重放它的那个Requester Adaptor。 这工作, 只有当标志衰减的足够长并且目标被首先产生标志的相同的系统部件保护着。

  在第二张表技术里,一张当地可达到的加密的表包含了被要求在目标系统证实的用户名/ 密码结合体。 我没开玩笑。 用户名, 象从被偷的会话标志里获得的,被用作一个主键来访问一张表,这张表是用来产生访问企业级系统的使用要求的证书的。

  知识渊博的读者对一种安全和有效的方法的感到失望,和但是的确存在一个这样的方法,如WS 安全描述的。 防止广泛的接受这种方法的唯一的令人讨厌的细节是这普遍是在目标系统里没有实现。但是随着时间的过去,我们确实相信WS 安全将被很多企业级系统实现,形势将逐渐改进。它永远都不会是完美的,不过,并且如果服务层被建造,我在上面描述的安全问题仍然是被要求的。

  附件

  紧挨着"安全",附件(Web 服务请求或者响应增加的二进制文件)是Web服务的最成问题的方面。 有4 种方法,并且他们工作得都不是非常好。 如果你想要穿过Web服务发送一个二进制文件(例如一幅图像),你必须做出选择。

  微软公司有一种方法, 这种方法被他们称为有声称的一些类型标准的味道的WS 依赖。只要你不是试着为在Java 和微软公司之间的联系使用它,那么它就会听起来象这样。 它只是微软公司"标准"。 WSE 实现它,但是微软公司正反对它并且计划不久移到一种新方法。

  Java有一种方式叫具有附件的SOAP (SwA),而Sun 提供一个叫SAAJ的API(Java的SOAP与附件API)。 但是微软公司不支持SwA, 即使它是WS -I 批准的方式。

  XML提供一个是把二进制数据作为文本发送的二进制编码技术的"base64"。 它为每人工作, 因为它是XML标准,但是它对大文件却是一个问题,因为文件的大小以50%或者更高的因子增长。 那就会更坏了,因为XML 语法分析程序必须费力地读完全部非文本的正文来寻找下一个标志。 与只把它作为一个MIME类型插入中HTTP 和把它作为一个已知大小的块来处理相比要贵的多。

  并且最后,仅仅发送象储存在一个FTP服务中心上的文件的URL并且在范围之外允许自我服务是可能的。但那是一个授权恶梦,因为全部的被授权的用户能上载文件,即使真正的授权要求可能更严格。

  对我们的实现来说,我们选择的SAAJ,并且决定不要与微软公司允许互操作。 那为我们工作,但是它当然将不为每人工作。

  开发

  当我们开始我们的发展时, 我们获悉当客户想调查Rational Software Architect作为一个工具箱的时候,一些客户端开发者更熟悉Axis并且以那种方法做他们的全部发展。

  那造成一次我们直到我们努力集成的时候才知道的严重冲突。 问题是许多类有相同的名字,但是Axis与IBM 那些类配合的不是很好。 因此如果一个物体装载SOAPAttachment(例如), 然后类装载单位需要知道是哪一个,因为有不同的选择。 为了保证他们得到他们想要的,Axis开发者设置特性来装载org.apache.axis.SOAPAttachment。那为我们的队制造了一个问题,因为自然,我们对那一无所知并且以为如果我们需要SOAPAttachment,我们将得到com.ibm.ws.webservicesengine.SOAPAttachment,。 不那假定再是真实的,当我们努力想出集成为什么如此严重毁坏我们的代码时,的确有一些困难的时刻。

  结论

  最后我们设法克服了这些问题,我们表明一个服务层的确能被做出以运行, 虽然只在后端存在困难。

  关于性能仍然是存在的一个问题。 显而易见,带有那么多层,并且具有处于主角位置的Web服务,服务层将不会很快的。 幸好,一位以前的客户曾经说道,"摩尔定律是我们的朋友"。

  因此我们现在能有灵活性,稍后可以有更好的性能。 我们现在不能有高的性能而稍后有灵活性。

  这个思想是指引我们达到今天我们所达到的地方。

相关推荐