SOA 实践知识

来源:互联网 发布:java编程思想配套视频 编辑:程序博客网 时间:2024/06/05 06:30

参考:http://www.ibm.com/developerworks/cn/education/webservices/ws-soacert1/section2.html

   http://www.ibm.com/developerworks/cn/webservices/ws-soa-design/

 

1、SOA 最佳实践

SOA 以业务建模和业务分析人员为中心。

面向服务的体系结构(Service-Oriented Architecture,SOA)提供了支持业务灵活性的 IT 灵活性远景。

SOA 原则非常强调将服务使用者和服务提供者分离开来,即对服务提供者的修改不应要求在服务使用者中进行相应的修改。

                  业务驱动的开发

 图片

   

2、XML、Web 服务和 SOA

XML 是最低级的通用语言。它是一种可扩展标记语言,不同的平台和语言都能理解它。很多 Web 服务标准中都使用了 XML。

Web 服务是能够进行重用的功能构建块。必须由提供者系统使用标准协议和语义对其进行发布、查找(发现)和调用。这是使用具有不同语法和相关结构的 XML 进行的,例如以下 XML:WSDL、UDDI、SOAP。

    1)Web 服务描述语言 WSDL 是一个 XML 实例文档,符合服务请求方和服务提供者之间的通信的 W3C 标准 XML 语法。它描述 Web 服务如何工作。

    2)统一描述、发现和集成 UDDI 定义如何查找 Web 服务(及其 WSDL 文件)。

    3)简单对象访问协议 SOAP 是用于在网络上交换基于 XML 的消息的协议。通常,使用 HTTP 作为传输协议,但也可以使用其他协议,如 SMTP 等。

          Web 服务标准的使用

    图片

 

3、SOA遵循原则

命名服务时应以最大化易用性为目标

我们在选择服务、操作、数据类型和参数的名称时有一个指导原则:希望最大化服务的易用性。我们希望帮助流程开发人员标识实现业务流程所需的服务和操作。因此,我们强烈建议使用服务使用者专业领域内有意义的名称,优先选用业务概念而不是技术概念

我们的建议就是:应使用名词对服务进行命名;而应使用动词对操作进行命名。

 ManageCustomerData {
    InsertCustomerRecord()
    UpdateCustomerRecord()
    // etc ...
 }

 

服务应具有精心选择的粒度

在本文的服务设计讨论中,我们考虑的是服务本身的粒度,即服务应该包含的操作数量

没有可用于确定服务粒度的简单启发式方法。我们将提供两个在设计服务时应该考虑的因素的示例加以说明:

    1)常作为测试和发布的单位。如果粒度过粗,而将大量操作分组到单个服务中,则可能将增加服务的使用者。因此,如果我们对服务的某些方面进行更改(可能仅为了其中一些使用者的利益),则必须重新发布整个服务,从而可能影响所有使用者。
    2)服务使用者所面临的一个挑战就是找到正确的操作。通常,使用者需要浏览服务列表,然后在标识了合适的服务后浏览服务操作列表。我们认为,服务粒度的两个极端——提供仅有几个方法的很多服务,或数十或数百个操作均集中在几个服务中——都将对易用性造成影响。


服务应是内聚而完整的

既然认识到了在确定服务粒度时需要考虑周全,那么在确定哪些操作应组成服务时有什么注意事项呢?我们认为有两个对象设计概念很有用:内聚性和完整性。我们可将这些概念应用于服务接口

我们希望创建功能内聚的接口,一组操作由于其功能相关而聚合到一起。我们发现,当评估内聚程度时,从服务使用者角度看待服务很有用。通过使用者的视角,我们会将重点放在服务的功能上。将此方法与使用以下内聚标准进行对比:

我们可以考虑基于功能实现的内聚性进行决策。是否应由于操作使用相同的算法分组到一起,或者由于均是使用相同主机上的 CICS 事务实现的而将其分组到一起?这些是实现细节,不应影响接口设计。
可以使用时间内聚性原则,即,将在短时间内一起使用的操作分组到一起,例如,RetrieveCustomerDetails、CheckCreditRating、CreateLoanFacility 和 TransferFunds 操作都可能在金融业务流程中依次出现。不过,时间内聚性并不意味着这些操作应该由同一个服务提供,CheckCreditRating 和 TransferFunds 就缺乏功能内聚性。


服务应对实现细节进行封装

另一个对象设计原则(封装)也适用于设计服务接口。我们封装服务实现的细节——所用的算法和资源——的动机在于增加服务使用者和提供者之间的分离,从而为将来扩展提供灵活性。

 

服务操作设计原则

参考:

我们应该优先对服务和操作使用业务领域的名称,使用动词作为操作名称。对于操作,我们将这个建议进一步深化:应当使用具体的业务含义而不是泛型操作对操作进行定义。例如,不要使用泛泛的 UpdateCustomerDetails 操作,而要创建 ChangeCustomerAddress、RecordCustomerMarriage 和 AddAlternativeCustomerContactNumber 之类的操作。此方法具有以下好处:

    1)操作与具体业务场景对应。此类场景可能不仅是简单的更新数据库中的记录。例如,更改地址或婚姻状况可以要求生成正式的文档,而将要求系统记录该文档的详细信息——或扫描版本。如果使用不太具体的操作(如 UpdateCustomerDetails),则较难实现此类业务场景。
    2)各个操作接口将非常简单,且易于理解,从而提高了易用性。
    3)每个操作的更新单元得到了清楚的定义(.在实现具有高并发性要求的系统时,我们可以基于操作的要求采用更细粒度的锁定策略,从而减少资源争用。
问题:如果设计的信息模型会变动时,工作量增大?定义太细,需要定义的方法太多?

 

操作应采用粗粒度参数

在讨论操作参数时,同样要面对粒度的问题。我们之所以建议使用粗粒度参数,有两个原因。首先,它们提供了创建灵活操作的机会,支持在不干扰现有使用者的情况下提供新版本的操作。其次,具有大量类型相似的参数的操作易于在从第三代语言代码进行调用时出现转换错误。相反,当数据放置在所使用的结构化类型的显式方法(如 setGivenName() 和 setInitials())中时,此方法出错的几率更小。

 

操作设计应考虑并发性

请注意,数据库锁定从第 1 行检索时一直保持到第 5 行的提交操作。这样以一定的延迟确保了正确的并发行为。我们强烈建议,不要在高度分离且可能异步的 SOA 基础结构中的连续调用间保持锁定。我们建议采用乐观锁定策略,将并发控制的责任委派给相应的应用程序逻辑。考虑到管理并发更新的相对复杂性,我们提出一个相关的建议:尽可能使用无状态语义。例如,与实现等效的“Retrieve record”-“Write record”两个操作(使用者会在检索和写入操作间使值递增)相比,可能实现具有良好并发行为的单个操作“Increment balance by X”更为容易。

0 0