面向服务的软件工程复习
简答题
服务和制造
- 服务和制造的区别?相似和不同之处?什么是制造,什么是服务?
- 为什么需要面向服务的泛型?
服务和制造的区别
- 服务客户和服务提供者双向交互
- 制造模式中用户和产品提供者的交互是单向的
服务模式(Service Mode)和制造模式(Manufacturing Mode)的最大差异在于:服务模式的产物是服务(Service),而制造模式的产物是货物(Goods)。服务是无形的、挥发的,并可能以消费者参与的方式定制化生产;而货物是有型的、可存储的,消费者不直接参与货物的生产过程。
为什么需要面向服务的泛型
- 面向服务的快速发展导致单个组织无法独立提供全套服务,提供的有限服务也无法被广泛运用;已存在的服务并不能很好地被发现和调用,也导致大量冗余服务。
- 另一方面:原先的服务系统是复杂、脆弱、特殊的,从上层业务看,无法灵活应对实际业务的变更;从底层实现看,也无法及时应对底层技术的更新、或者新增的功能。
- 因此构建服务生态系统,运用面向服务的分析和设计原则,使得产生的服务具有良好的可发现性和可复用性,同时能灵活应对业务领域和技术领域的变更。
SOAP
- SOAP 包的主要构成,如何配合在一起完成消息交互
- 解决问题的时候如何去处理(两种主流的 SOAP 的利用方式)
- 协作完成任务的例子
SOAP 包结构
SOAP 包本质是⼀个 XML 文档,包含下列元素:
Envelope元素(SOAP 声明)
- 必需元素,根元素,标识此 XML ⽂档为⼀条 SOAP 消息
- 可以包含命名空间和声明额外的属性。如果出现额外属性,则必须使⽤命名空间修饰
Header 元素(应用相关的控制数据)
- 可选元素,有关 SOAP 消息的应用程序专用信息(比如认证、支付等)
Body 元素(消息容器)
- 必需元素,包含所有的调用和响应信息
Fault 元素(出错消息)
- 可选元素,提供有关在处理此消息所发生错误的信息
处理模型
- 用 XML 打包请求:
- 将接口名作为根节点
- 方法和参数作为节点
- 将请求发给服务器:
- 不创建自己的 TCP/IP 信息,利用 HTTP
- 将请求封装成 HTTP POST 请求格式发出
- 服务器收到请求,解码 XML,处理请求,以 XML 格式返回响应
- 与请求比较,方法的节点名字变为请求的方法名后缀 Response
- 客户程序自己调用了哪个方法,根据方法名后缀 Response 寻找调用方法的返回值
处理模式
交互模式
- 远程过程调用模式(RPC 模式)
- ⼀种同步请求/响应交互的方法
- 发出请求后会⼀直等待响应
- 面向文档模式
- ⼀种异步交互的⽅法
- 发送⼀个复杂的 XML 文档,然后等待通知,结果会在处理后发送回来
WSDL
- WSDL 的核心
- 每一个部件具体做什么
WSDL 的核心
WSDL(Web Services Description Language)是一种XML格式的语言,用于描述Web服务的接口、操作、消息、地址等信息。WSDL的核心是描述Web服务接口的抽象部分和具体部分。
具体部件的用途
WSDL(Web Services Description Language)2.0 以 description 元素为根节点
import、include:拼装不同部门/组织定义的文档,形成完整的 WSDL 语义
抽象部分:
Types:使用到的数据结构或者叫数据格式范式,独立于语言和平台
Interface:operation 的集合即服务能力的集合,描述服务能力
operation:input、output、infault、outfault
具体部分:
Binding:特定端口类型的具体协议和数据格式规范的绑定
Service:对服务整体的抽象,包含若干个 endpoint
endpoint:将绑定与当前地址关联
服务的泛型
- 面向对象和面向服务的异同
面向对象 VS 面向服务
特点 | 面向对象的计算 | 面向服务的计算 |
---|---|---|
方法论 | 通过定义紧耦合的类来进行应用开发;应用架构为基于继承关系的层次式架构;从构造函数——通过类或模型——到系统设计 | 通过定义松耦合的服务来进行应用开发,并将服务组装成可执行的应用;从系统模型到服务模块,从服务抽象定义到服务实现绑定;通过搜索获得可用的服务实现 |
抽象和协作层次 | 往往由一个团队来负责应用的开发,并负责整个生命周期;开发者必须了解应用领域的编程知识 | 开发任务由三个独立方承担:应用程序开发者,服务提供方和服务代理;其中,应用程序开发者需要了解应用逻辑,但不需要了解具体的服务是如何实现的;服务提供者需要编程能力,但不必了解使用服务的应用 |
代码共享和复用 | 代码复用通过类成员的继承和库函数加以实现。其中库函数在编译时引入,且往往是平台相关的 | 代码在服务层次复用。服务使用标准的结构,并发布在 internet 库中。服务是平台无关的,且能够被查找并远程调用。服务代理支持系统的服务共享 |
动态绑定和重新组合 | 在运行时将名称和方法进行关联。方法必须在应用部署前链接到可执行的代码 | 在运行时将服务调用和服务进行绑定。可以在应用部署后,再进行服务选定。这一特色使得应用可以在运行时重组 |
重组 | 多在设计时决定导入的组件 | 可以动态改变应用系统中服务的组合关系,以及服务定义与服务实现之间的绑定关系,即实现动态地添加、修改、删除各个服务节点 |
组件通讯和接口 | 与平台和语言有关,例如 c++ 程序难以直接和 java 程序通信 | 与平台和语言无关。组件间通过标准协议通信,如 XML,WSDL 和 SOAP |
系统维护 | 用户需要时常升级软件,且在执行升级时,应用必须停止 | 通过互联网升级系统,因为服务多运行在远程服务器上,用户通过互联网进行访问。维护对用户透明 |
可靠性 | 在设计时决定可靠性的方法 | 对于服务提供者,每个服务相对简单,更加可靠。对于应用程序存在多个满足同一需求的服务,可通过将故障服务的节点断开并重新绑定到备选服务节点上,获得不间断的应用系统 |
软件拥有 | 软件作为产品销售,为用户所拥有 | 软件存在并执行于独立的服务提供商的设备上,用户按照每次对服务使用付费,而不是按照软件产品付费 |
八大设计原则
- 八个设计原则互相之间的关系
标准化服务合约
- 标准化服务合约与服务松散耦合
- 消费者和服务之间存在对服务合约中技术接口的依赖
- 技术服务合约越详细,越内容丰富,消费者和服务之间的依赖关系越强
- 两个服务之间所达到的松散耦合程度直接与在服务合约中的依赖关系数量相关
- 标准化的合约将会有助于提高服务之间的一致性和耦合质量(quality of coupling)
- 消费者和服务之间存在对服务合约中技术接口的依赖
- 标准化服务合约与服务抽象
- 服务抽象原则要求简化合约
- 非核心信息都被隐藏
- 服务合约的设计决定了抽象的程度
- 在合约中的内容越仔细,服务中被抽象的信息就越少
- 服务抽象原则要求简化合约
- 标准化服务合约与服务可复用性
- 服务可复用性原则常常侧重于服务封装的逻辑是否足够一般和通用
- 可复用方案逻辑与数据交换之间的关系最终要由服务合约是如何设计的来决定
- 服务合约越是通用、灵活和可扩展,服务的长远复用潜力就越大
- 标准化服务合约与服务可发现性
- 服务合约越是得到一致的标注和结构化,对于那些需要使用它们的人来说就越是可以预测的
- 服务合约越是标准化,元信息(meta information) 的技术接口细节提供得越是充分,服务的可发现性就越高
- 标准化服务合约与服务可组合性
- 服务的可组合性需求常常与服务合约表达其能力的粒度有关
- 粗粒度的操作拥有更高的效率,但常常不适应于需要参与到更大规模组合中的服务
服务松散耦合
- 服务松散耦合与标准化服务合约
- 松散耦合鼓励调节技术合约内容的数量和复杂度,从而最小化消费者依赖需求、最大化服务所有者的自由度,在不影响现有消费者的情况下随着时间演化和改变服务
- 服务松散耦合与服务抽象
- 创建更低耦合的消费者关系,明确地要求应用良好定义的功能和技术抽象级别
- 服务松散耦合与服务可复用性
- 减少依赖关系可以使服务更容易被组合、演化甚至扩充以支持不断变化的业务需求和方向
- 服务松散耦合与服务自治
- 减少消极耦合类型的程度,会为运行时和设计时的更高自治级别提供支持
- 服务消费者具有越多的跨服务依赖,它所具有的自主权就越少(服务消费者可能同时担任复合服务中的服务协调者)
- 服务松散耦合与服务可发现性
- 服务松散耦合有助于元数据的调节
- 服务松散耦合与服务可组合性
- 在服务组合中,避免消极形式的耦合
- “合约-逻辑”耦合 如果服务合约是自动生成的,就很有可能在被其他服务使用时不符合标准。因此需要在它和其他组成成员之间进行转换
- “合约-技术”耦合 如果同一个组合中的不同部分同时使用开放与专用服务技术,就会需要在本地实现技术转化层
- “合约-实现”耦合 当一个服务合约与底层实现特性之间产生耦合时,就会最终把这些性质强加到作为一个整体的组合之上
- 在服务组合中,避免消极形式的耦合
服务抽象
- 服务抽象与标准化服务合约
- 服务抽象出来并对外界可用的信息就是服务合约,服务抽象原则的应用影响到服务合约
- 服务合约的设计标准也会影响到功能、技术和逻辑抽象的等级
- 服务抽象与服务松散耦合
- 抽象的程度对可能耦合的程度有直接的关系
- 少量的高度详细的技术接口约束会导致比大量含糊或开放的数据约束更多的紧密耦合需求
- 耦合的程度一般由被抽象的信息数量和信息本身的属性的组合来决定
- 最终由服务合约的粒度加以体现
- 服务抽象与其他原则
- 其他的服务设计原则,如服务可复用性、服务可组合性和服务可发现性等原则都鼓励创建更多的、关于服务的元信息
- 而服务的抽象原则要求在发布这些元信息前评估其必要程度
服务可复用性
- 服务可复用性与标准化服务合约
- 可复用的服务需要足够的灵活性来支持带有不同交互需求的消费者
- 导致降低合约验证约束(尤其是那些易变的)的设计标准
- 服务可复用性与服务抽象
- 合约的自描述性与简洁之间的平衡
- 元信息的抽象程度反映这一平衡
- 服务可复用性与服务松散耦合
- 一个服务的依赖需求越小,复用它就越简单
- 当追求服务逻辑的可复用性时,总是有一种减少服务合约约束的趋势
- 服务可复用性与其他原则
- 服务自治
- 自治是对可复用服务潜在高性能和并行使用的保证
- 服务无状态
- 通过最小化状态管理责任,提高一个服务的可用性,从而提高有效扩展的能力
- 服务可发现性
- 可复用服务必需可发现、可解释
- 服务可组合性
- 可组合是复用的一种形式,可复用潜能越大,服务被反复组装的机会就越大
- 服务自治
服务自治
- 服务自治与标准化服务合约
- 服务合约自治直接与服务合约紧密相连
- 规范化的考虑会影响到合约如何形成,以及如何与其他服务协调
- 在服务合约上有越大的控制权,服务合约能被更好地定制和标准化,越能够确保底层实现可以在遵循既定自治级别的前提下,被独立设计
- 服务自治与服务松散耦合
- 由于同样期望将服务之间的依赖最小化,服务自治在很大程度上支持服务松散耦合原则
- 积极耦合会直接导致设计时自治的增加;设计时自治的增加,又能更好地增强和优化服务的实现,从而支持运行时的自治
- 由于同样期望将服务之间的依赖最小化,服务自治在很大程度上支持服务松散耦合原则
- 服务自治与服务抽象
- 将一个服务的自治级别作为整个服务合约的一部分来发布
- 服务自治的信息是服务质量信息抽象的一个例子
- 服务自治与服务可复用性
- 自治的增加提高了一个服务的复用潜力
- 通过增强服务的可靠性和提高服务行为的可预测性,其逻辑可以更加容易地适应多个服务消费者的需求
- 更好地支持服务运行环境的演化,从而应对复用所带来的并发要求
- 服务自治与服务无状态性
- 实现高级别的服务自治可以直接支持服务无状态性程度的增加
- 服务自治与服务可组合性
- 服务组合的整体自治性取决于它的所有组成成员自身的自治性
- 服务有越好的可靠性和可预侧性就越能组成更高效的大型服务组合
服务无状态性
- 服务无状态性与服务可复用性
- 减少活动相关逻辑使一个服务变得更加无关(而无关服务具有更好的可复用性)
- 提高服务的可扩展性和可用性使得它们可以在更多的服务组合中被更多的服务消费者复用
- 服务无状态性与服务自治
- 状态信息的本质通常是特定于一个给定的活动或者业务流程的,通过在服务边界外改变状态管理机制和流程的职责,就可以降低服务逻辑依赖于更大的业务任务的可能性。这使得服务能够更加自给自足,并且能够被定位成技术环境的一个独立部分,因而直接增加其整体自治性
- 另一方面,由环境架构所提供的状态管理延迟选项可要求服务形成在其边界外的一个直接依赖。这种类型的外部实现耦合会影响到一个服务的整体自治
服务可发现性
- 服务可发现性与标准化服务合约
- 使服务更加容易可发现和可解释会影响服务合约的内容
- 服务可发现性会直接地影响功能表达设计标准的确定
- 服务可发现性与服务抽象
- 服务抽象的原则需要减少合约当中所发布的信息数量;服务可发现性则要求提供更多的信息;两者之间需要取得平衡
- 一旦实现了可发现性和抽象之间的适当的平衡,那么随后实现的服务的可发现性将基于那些已发布的(而不是被抽象的)元信息
- 服务可发现性与服务可复用性
- 强调服务可发现性的主要目的是支持服务可复用性
- 当表述可复用功能时,应当应用可发现性相关的设计标准,以保证能通过实际的技术合约把服务的目的和能力尽可能清楚地表述出来
- 服务可发现性与服务可组合性
- 潜在的组合成员应当容易定位和识别,以避免在无意间创建冗余的服务逻辑
- 当服务组合为了适应上层业务流程的变化或者为了增加整体的业务需求实现而发生演变时,需要查找从组合的原始版本创建以来,新加入的服务和功能
服务可组合性
- 服务可组合性与标准化服务合约
- 服务可组合性的应用强调服务间需要一致的合约标准
- 由服务可组合性原则引起的考虑可以用来帮助形成服务合约设计标准,以便支持特定于组合(尤其是复杂的组合)的需求。
- 服务可组合性与服务松散耦合
- 服务所具有的依赖关系会造成一些根本性的约束,直接制约服务能够达到的可组合性级别
- 服务可组合性与服务抽象
- 当抽象化被应用到隐藏复杂的组合的程度时,对这些组合有效和可靠地执行的要求被大大放大了。作为回报,组合所有者对如何发展组合配置获得了更大的控制权。
- 服务可组合性与服务可复用性
- 当一个成熟的服务库存建立起来的时候,服务组合就成为最常用的服务复用方式
- 可复用但不可组合(参与多个点对点活动)
- 可组合但不可复用(很高的“服务-消费者”耦合)
- 当一个成熟的服务库存建立起来的时候,服务组合就成为最常用的服务复用方式
- 服务可组合性与服务自治
- 这两个原则之间是“整体-部分”的关系
- 控制器服务在组合其他服务时需要牺牲其自治性(等价于对所有涉及的服务组合成员的自治性的综合度量结果)
- 服务自治性的提高有助于产生高效的组合成员
- 服务可组合性与服务无状态性
- 尽可能地减轻每个组合成员在状态管理方面的责任,可以更精细、更优化地执行整体的组合实例
- 为了能够在同一个服务库存中重复地装配出高效的服务组合,服务之间需要能够通过一致并且有效的方式共享状态数据
- 服务可组合性与服务可发现性
- 作为组合控制器的服务能力可以负责描述它所封装的整个组合逻辑,并达到服务抽象原则所允许的任意程度
综合题
Web Service
- 试结合相关协议和框架,描述一个 web service 从创建开始到被最终服务消费者调用的全过程对服务的建模、查询和调用的全过程。
服务的建模
XML(Namespace、XML Schema)、SOAP、WSDL
- XML 定义了 web 服务中的消息交换格式,使用 XML Schema 定义不同的数据结构,引入 Namespace 使得 XML、XML Schema 中的元素和属性全球唯一且全球共享;
- SOAP 提供了一种标准的方法,使得运行在不同平台、使用不同的技术和编程语言的应用程序可以相互进行通信,服务的发布、查找、调用,都通过 SOAP 传递的 XML 消息。
- WSDL 对服务能力、服务中使用的数据结构以及传输绑定给出定义和描述;提供了一种基于 XML 的标准接口定义语言/服务能力定义语言,用以在服务的提供者/调用者/服务注册之间,交换必要的有关的 web service 的信息
对于大多数服务,用以上三个协议和框架可以完成建模;对于一些更为复杂的服务,如复合服务或者是带有非功能性需求的服务,还需要用到其他协议和框架完成建模。
- BPEL 定义多个服务间如何交互和合作,从而将一组现有的服务根据业务流程构建起来,实现业务服务。
- WS-Policy 可以实现一些非功能性需求,如信息加密,权限验证等。
建模完成后,服务提供者,通过 UDDI 或者 WSIL 将服务发布出去。其中,UDDI 利用分页机制,让服务得到最大可能的复用和共享范围;WSIL 使用树形连接结构,适用于企业既定的业务。
服务的查询
- 消费者程序发送 SOAP 信息给服务注册,描述自己需要的服务;
- 服务注册查询注册表,通过 WSDL 服务合约找到一系列符合条件的服务;
- 服务注册将查询到的 WSDL 通过 SOAP 发送给消费者程序,让消费者程序从中选择可用的服务;
- 或者服务注册自动化筛选出当前最符合消费者程序要求的服务,通知消费者程序。
服务的调用
- 消费者程序根据 WSDL 中提供的服务位置进行调用;
- 其中,消费者和提供者基于 WSDL 中约定的接口进行消息的发送和接收;
- 另一方面,当前服务可能同时被多个消费者程序使用,创建了一系列服务实例,WS-Addressing 提供了相应的机制,确保服务消费者能在实例池中找到特定的实例并与之通信;
- 另一方面,由于创建的实例是有状态的,利用 WSRF 对状态数据进行存取,进行状态管理,提高资源利用率。
服务分析和服务设计
- 以电信企业为应⽤背景,举例描述服务分析和服务设计的过程。 并结合⾯向服务的设计原则(标准化服务合约、服务松散耦合、服 务抽象、服务可复⽤性、服务⾃治、服务⽆状态性、服务可发现性、 服务可组合性),讨论“schema集中化”“合约集中化”“逻辑集中化” 在设计过程中的应⽤
服务分析流程
面向服务分析的目标是讨论需要构建哪些服务,每个服务应该封装哪些逻辑。分析的核心是业务服务:
- 进行文档化的需求描述,定义流程自动化需求,作为服务候选建模的依据;由于电信企业发展比较完善,可以直接使用之前的需求文档分析
- 对现有的自动化系统进行分析、识别;分析企业正在使用的系统具有的功能
- 对服务候选建模,识别服务操作候选,并将其分组
在面向服务分析流程中,需要考虑服务可复用性、服务自治和服务的可发现性
- 可复用性:在服务建模中,需要:精化已有的服务能力候选,使其更加一般化和可复用;定义额外的服务能力候选,这些能力是在构成服务建模过程的基础的业务流程自动化所需之外的
- 自治:对已有自动化系统收集得到的消息,会影响服务系统所能达到的自治级别;比如根据信息决定保留遗留系统,那么达到共享自治,独立开发的可能达到逻辑自治或完全自治
- 可发现性:从服务生命周期开始,尤其是在产生服务操作候选时,需要以统一的方式,记录所有元数据;在服务建模过程中,业务和技术专家需要一起合作,建立服务候选
服务设计流程
服务设计过程,是从服务候选(逻辑)派生出具体的服务设计(物理),然后装配到实现业务流程的抽象组合中。
- 组合 SOA:选择编排、业务、应用服务层中的哪些进行实现,定义核心的 SOA 标准,选择 SOA 扩展(WS-*协议)
- 根据业务层级,分别设计以实体为核心的业务服务,应用服务,以任务为核心的业务服务
- 设计面向服务业务过程,组合服务构建出业务流程
schema 集中化
传统的做法是在订购服务、退订服务中使用不同的套餐数据结构,而按照标准化服务合约,所有使用的数据结构都应该被单独定义、管理,与具体的操作流程无关。
采用 schema 集中化的设计模式,将电信企业划分为多个分离的领域(部门),每个领域都可以被独立地进行标准化和治理,每个领域定义和管理自己的 schema,作为整个服务系统的基本数据结构;在不同的服务中,使用这些 schema,避免了频繁且不必要的数据转换;在必要的情况下,可以利用这些 schema 定义新的数据结构
合约集中化
为了保证服务松散耦合,避免消极耦合,采用合约集中化,将对服务的访问严格控制在合约内:
- 所有的合约应该被集中管理,拥有一致的设计原则和设计目标
- 在服务生态中,任何情况都不可以绕开合约去访问具体内容
服务抽象&服务可发现性:设计服务暴露的信息
服务抽象:技术信息、功能、程序逻辑、服务质量抽象
服务抽象出来并对外界可用的信息就是服务合约,服务合约的设计标准会影响到其他
逻辑集中化
为了实现服务可复用性,让消费者程序只调用指定的服务,要建立服务库存,在规范的服务库存中,每个服务代表了一个独特的功能域,这就要求服务边界之间没有重叠。
设置专家管理服务库存,应用开发人员不能直接往服务库存中增改需要的服务,只能请求当前服务库存管理人员进行审查,做出恰当的决策
同时,服务可发现性是实现服务可复用的前提,服务自治是可复用服务潜在高性能和并行使用的保证;无状态性能提高服务的可用性