海珠区二手家具:SOA--服务

来源:百度文库 编辑:偶看新闻 时间:2024/05/08 06:48:00

服务:某人为别人执行的事务(职能)。

SOA中的服务SOA中的服务体现了业务功能。SOA聚焦于业务流程,这些流程在不同的系统上分不同的步骤。服务的目标就是体现业务功能的“自然“步骤。这就是说,就服务起作用的领域而言,服务应该代表了一项自足的功能,对应着一项真实世界的业务活动。业务人员应该能理解服务干了什么。下面是一个技术驱动的业务接口的例子:

customerOP(action, // "create", "read", "change", "delete"

id, // customer id or null

name, // new customer name or null

address, // new customer address or null

account) // new customer bank account or null 

这是一个业务接口,它允许你创建一个新客户,读取或修改,或者删除数据。然后,这个接口是技术驱动的,也许直接映射自相应的数据库接口。

作为对比,一个业务驱动的接口可能看起来像这样: 

createCustomer(name, // new customer name

address, // customer address

account) // customer bank account

readCustomer(id) // customer id

changeCustomerAccount(id, // customer id

account) // new customer bank account

changeCustomerAddress(id, // customer id

address, // new customer address

check, // true: verify address

modify) // true: fix address if possible

deleteCustomer(id) // customer id

技术角度的服务(接口和契约)

技术上,一项服务是一个处理(多个)消息的接口,它返回信息,以及/或者改变相关实体的状态。也可以说,所有能够当做接口使用,体现了自足的业务功能的东西都是一个服务。

然而,仅仅知道接口还不足以使用服务。接口仅仅是一种“签名”,它描述了输入参数,输出参数,以及可能的异常等等。但是,作为服务的消费者,我们必须知道服务的完整行为和语义。也就是说,服务必须是“定义良好”的。

另外,对于某些特定的消费者,我们可能还得知道服务质量(Qos)以及服务等级协议(SLA)等。我们可以把这些信息放在“契约”中,它是对特定供应者和特定消费者之间的服务的完整规格说明。一份契约,理想中,定义了消费者使用中应知道的一切。 

服务特性

n 自足

所有SOA定义都同意,服务自足(独立的,自主的,自给自足的)是其设计目标。总会存在某种形式的依赖。例如,服务至少公用一些基本的数据类型。但是,要避免对一些复杂类型的依赖。目标是最小化依赖,这样,SOA才使用于所有者各异的分布式系统

n 粗粒度

在供应者和消费者之间调用一个服务传输所有必须的数据,比起使用多个服务调用处理同等数量的数据,通常来说,前者更好。当然,有时候,也得结合性能一起考虑。

n 可发现/可见

有一个地方能发现服务。

n 无状态

幂等性

如果调用某个服务修改一些东西,但是没有收到答复,那么就比较麻烦了。如果再次发出服务调用而不会照成问题,那么服务就是幂等的。实现幂等的普通方法很简单,每次发送请求发送一个唯一的ID,如果没有应答,那么每次重试都用相同的ID

作为一个优化,也可以发送一个标志,这样就能知道是否是重试。这样就不用判断ID是否已经存在了。

n 重用

避免冗余是一个普遍目标。重用性应该结合性能一起考虑。总的来说,重用性也许是个目标,丹不是一个法则。

n 可组合

服务可以使用/调用其他服务。也就是说,更广义上的业务功能可以被分解为小的步骤。所有的步骤也是服务,所以服务的分类中也包括一类“组合服务”。

n 技术性

n 服务质量和服务等级协议使能

n 前提和后置条件

n 供应商分散

n 可操作 

服务分类

服务的分类有很多,只说一下常见的一种:

l 基本服务:提供一个基本的业务功能,并且,将该功能进一步拆分成多个功能已经毫无意义。它们应该具有ACID特性:原子性、一致性、隔离性、持久性

l 组合服务:代表了基本服务组合而成的服务

l 流程服务:代表了长期的工作流或者业务流程。通常有一个状态。 

基本服务也可以分为两类,分别是基本数据服务和基本逻辑服务;前者通常都是输入数据或者读取数据的一些操作,比如:创建一个新客户、改变客户的地址、返回客户的地址等等。这些服务都是一些最低限度的业务功能。与基础数据服务相比,后者代表了基本业务规则,这些服务通常输入一些数据,然后返回相应的结果。比如:定义产品目录和价格列表、定义改变客户合同的规则、返回某年不是闰年的答案等等。

通常来说,这些服务也是对提供这些功能的后端的系统的包装。所以两者的界限也就没那么明确。 

组合服务的运行层次比基本服务高,然而,它们仍然是短期执行的,并且从概念上来看是无状态的。用工作流的术语来说,一个组合服务体现了一个“微流”,即在业务流程内部短期运转的活动流。

组合服务虽然是“组合”的,但是,它仍然应该有ACID性。在组合服务内的多个基本服务要么全部成功,要么都失败。在面对这一点时,大家首先想到的是在多个基础服务之间提供一个事物上下文环境,通过执行两阶段提交(2PC),来加入事物安全性。这样的想法对于异质的,多个“系统”组成的大型系统来说,基本是不可能的,代价也太高。现在,有一种称为“补偿”的松耦合的方法

流程服务,从业务观点来看,业务流程代表了“宏流”,它是可以被长期运行的活动。流程服务通常有一个状态,该状态在多个调用之间保持稳定。

典型的例子就是购物车的例子,需要保存购物车的内容。 

技术性“服务”

虽然,服务应该体现出业务功能,但是,一个系统中肯定会有那么些服务它们看起来和业务没多大关系。比如:查询部署信息、打印、监测运行时统计数据等等。我们可以称它们为“技术的”或“基础设施”服务。

服务和状态

SOA中宣称服务应该(理想情况)是无状态的。然而,永远都有状态被牵扯进来,即使是无状态服务也是。关键问题是,这个状态在哪儿?能持续多久?

通常来说,无状态服务时更好的选择,对它做负载均衡和实效援备也相当简单。有状态服务会更兼复杂一些。 

无状态服务

概念上,一个无状态服务时在不同服务调用之间不维持任何状态的服务;也就是说,服务调用结束之后,要销毁运行服务创建的局部变量和对象。重点在于,我们谈论的是服务本身的数据,在调用之后,如果执行调用的服务实例的所有数据都被销毁,那么服务就是无状态的,这和是不是同一个实例没有关系。

例如,我们调用两个增加金额的方法,向一个账户中增加一些钱,然后返回新的账户约,这个是无状态的服务。这种情况下,服务的实例中不需要保留任何数据。

在有些情况下,我们会在服务内部保持一个状态,然后在结束以后,销毁数据,那么也可以认为是无状态的。看下面的例子:

假设有一个在两个不同后端上修改地址的服务,对服务的一种松耦合实现是通过补充而非事务: 

string changeAddress (newAddress)

{

oldAddress = backend_1.getAddress( );

status = backend_1.changeAddress(newAddress);

if (status == failure) {

return "couldn't modify address in backend 1";

}

status = backend_2.changeAddress(newAddress);

if (status == failure) {

// compensation: restore old address to keep consistency

status = backend_1.changeAddress(oldAddress);

if (status == failure) {

fatalError(...);

}

return "couldn't modify address in backend 2";

}

return "OK";

}

这里我们维持着ige状态信息,OldAddress。这样如果后端2失败,这样就可以对后端1进行恢复。对整体而言,这个服务时无状态的,因为在调用结束的时,你可以销毁所有内部数据。 

有状态服务(性能是引入有转台服务非常重要的原因;安全,不必每次识别消费者,而是维持一个会话状态)

一个由状态服务是指,在多个服务调用之间,可以保持状态的服务。典型的例子就是购物车。

   

从技术上来看,实现一个购物车有3种可能的方法:

l 在服务中保持状态

l 在后端中保持状态

l 在前段/消费者保持状态 

    如果在一个有状态服务中保持状态,那么必须保证后续服务调用被路由到相同的服务实例。也就是说,用第一个服务建立了一个“会话”。通常,每个服务调用都会返回一个会话ID,消费者将这个ID与后续请求一个发送,这样ESB就能将请求路由到相应的服务实例。这是ESB的任务。 

    第二种方法,是保存在后端。与第一种方法类似,也需要一个会话ID来定位某一个会话。这是后端的任务。 

   第三种方法,是在前段保存,此时,服务向消费者不仅仅返回会话ID,而是返回完整的状态。当另一个商品添加到购物车时,消费者把整个状态发送给服务端。因为完整的状态保存在客户端,所有,服务可以是无状态的。 

状态在前段

状态在服务

状态在后端

在前段存储

所有状态

ID

ID

服务

无状态

有状态

无状态

在后端存储

/

/

所有状态

支持多通道

 

服务的生命周期

 

服务版本

新的流程或者新的需求总是会导致服务的修改,这就需要服务的版本划分,原则上,,关于服务的版本划分有两个不同的需求:

l 必须能够在同一个运行时环境中有服务的多个版本。例如,必须能有两个版本的服务来返回客户数据

l 必须能够有服务的多个修订同时处于开发之中。然而,这些不同的修订不一定要在同一个运行时环境中可用

总结

ü 可以将服务定义总结为:服务时某些自足的业务功能的实现

ü 依靠关注业务方面,服务隐藏了技术细节,使业务人员能够对它进行处理

ü 在技术上,服务时个接口,用于在供应者和消费者之间交换多个消息

ü 从消费者的角度来说,对服务的完整描述可以称为“定义良好的借口”或“契约”。

ü 常见的服务可以分为基本、组合和流程服务类别。

ü 基本服务永远都只应属于一个后端系统,只对该后端内的一致性负责

ü 组合服务于流程服务对多个后端间的一致性负责

ü 在多个后端间加强一致的方法是补偿,而不是事务安全或者两阶段提交(2PC

ü 在设计长时间运行的流程时,是把他们实现为有状态流程服务,还是在后端保持状态,提供基本服务来执行状态迁移,这一点需要仔细考虑。

ü 服务并不是解决分布式系统间任意通信问题的银弹。服务的主要目的是使分布式业务流程成为可能。如果有个特定客户流程,它维护着后端,或者它只和后端打交道,那么通过服务去访问后端并不是好主意。