SOA服务是否需要加以区别保持差异性?

SOA服务是否需要加以区别保持差异性?

不久前我看过一部电影<<幸福终点站(The Terminal)>>, Tom Hanks所饰演的主角被迫生活在一个机场,因为他是一个无国籍的人,他的国籍不被承认是因为就在他去美国的路上他的祖国解体了,他的国家不再存在了.当然,我想这只是一个编剧为了抓住观众的心而想出的新情节,以为它只是一个喜剧而以.然而事实上,这部电影是以Merhan Karimi Nasseri的真实生活故事为背景的,因为法国的移民问题还有他不愿回到他的祖国伊朗的原因,他在巴黎的戴高乐机场生活了将近二十年.本质上说这件事和面向服务没有任何关系,但是这件事使我想起一个问题,那就是有人近期在一个研讨会上提到的关于SOA的问题:服务需要保持差异性吗?

在SOA的所有核心原则之中,大概最基础的就是服务提供者和消费者之间的松散耦合关系.SOA的核心灵活性和重用优越性依赖于服务提供者和消费者在用于描述交互的服务合同条款框架内各自独立运作的能力,并且,对于一个特定的SOA来说,至关重要的是不能为其能力和行为加入非必要的要求或限制,因为无论是服务提供者和消费者都可能随时间而改变。

无差异性原则对于松散耦合的需求来说是十分必要的。毕竟,一个服务要通过消息传递为软件提供接口。不存在一种与对象实例类似的服务实例的表示方式;相反地,服务只是简单的停在那里,和他的每个访问者通信。更具体的讲,既然SOA包括了独立实体之间通过服务耦合进行的互操作,我们只需要在服务之间传递消息和数据就可以了。这些松耦合的、异构的、复合的应用程序要求所有的服务必须是无差异性的,以保证他们不会将自己的系统或进程地信息暴露给外部从而增加了系统的耦合度,那会导致可重用性和可用性的下降。

将不同服务组和在一起的原因是要实现商务流程,而这些流程必定是有差异性的,毕竟,一个进程的不同实例可能处在不同的状态。于是如何利用无差异的服务实现有差异的事务逻辑就变成了十分重要的挑战。如果实现方式不对将会失掉由无差异的服务带来的松耦合的好处。

在SOA中维护差异性信息

Wikipedia 是这样定义“差异性”的:这样的差异性保留了过去的信息,如一个用户记录或购买事务,并且差异性反映了系统从起始到当前时间的所有变化过程。在这个“差异性”定义的基础上,出现了许多关于另一个概念“计算”的定义:从一个状态到另一个状态的转变以及他们之间转换发生的条件。对于一个进程来说,差异是十分重要的,因为如果没有差异性,我们的系统将没有任何历史可供积累。实际上,我们开发的大部分系统,要么是记忆差异,要么对差异进行操作。进一步来说,各个公司都需要之前的状态来从某种错误的更新状态中恢复。最要紧的是没有前一步的状态记录,我们做到任何的可靠交易,因为无法在发生问题的时候进行回退。

因此,既然差异性对于一个信息系统如此之重要,那么为什么不把差异性的表示和维护功能包含在SOA中呢?回答这个问题的关键,在于充分了解差异性信息在一个松耦合的系统中是需要被共享还是独立在各个服务中。

松散的耦合是否意味着不需要差异性?

松散耦合使得SOA具有很高的效率。这就是说,SOA增加了灵活性,并使得一些互不干扰地各自运行的服务能够尽可能多被重用,所以,就不会在服务用户的行为和能力上强加一些不必要的需求和限制。在这种情况下,特定服务活动的差异性概念就应该在服务内部保持而不应该暴露给使用服务的客户,这将变得很有意义,因为这样当差异性万一需要发生变化的时候,就不需要让所有的服务用户来操作这种变化。更具体的来说,因为SOA包括了组成服务的实体之间的合作,所以就仅仅需要把消息和数据从一个服务传递到下一个服务,这样带来的缺点则是所有的服务将需要保存各自的状态。

然而,即使在SOA的环境之中,为了获得那些跨组织或者跨公司的长期运行的进程信息,仍然应该在每个独立的服务实现之外保持差异性的值。而且,一些进程需要保留多个服务的现场,为了这些进程的性质的要求,同时也为了安全、管理等目的,一些差异性的表现也是必需的。

用没有差异的服务保持有差异的系统

没有差异性的web表现出同样的问题,这些web必须保存一些跨越多个web的session,而每个web都不会独自保存状态。基本上有两种方法可以在web上保存差异:一种是在浏览器中存储一个拥有多个交互信息的cookie,另一种是在服务器上以某种方式跟踪差异,可以用网络的普通协议来交换保存的session信息的方式来实现这种跟踪。

使用Cookie保存差异只有在web上才适用,因为它们本身就是HTTP的结构,而HTTP是Web最基础的协议,每个浏览器都支持它。但是,当涉及到服务的时候,需要考虑系统到系统的通信,因为不可能所有的用户都是浏览器,或者更一般来说,都支持某种特定的协议。这就使得只有消息能够在SOA环境下保存差异性。

本质上,跨多服务的保存差异性是有可能的,这种保存可以通过对每个服务消息打上某种持久的标记来实现。而这种标记将代表一种跨越多服务交互活动的持久状态,表现良好的服务会把这种标记以混合的方式不加删改地传递到其他的服务,这种传递会通过管理这些服务的协议来进行。通过这种方式,个体服务仍然是没有差异性的,但是消息能够保存那些特殊服务的组件所需要的差异性。

这种基于消息的差异性保存方法回避了问题的本质,那就是到底要怎样来管理服务组件代表的进程。传统的BPM(业务处理管理)工具利用了代表所有运行进程的运行时组件引擎,而这些引擎保存了差异性。这种方法的优点是它提供了对运行进程的可见性并保存了相关服务的差异性。

然而,这种方法有一些严重的问题:第一,一个核心进程的运行环境仅仅能给服务可见的服务和服务组件提供差异性的保存。一旦服务的请求超出了系统的边界,进程工具将不再能够控制进程。第二,进程的活力性依赖于进程工具的活力性——如果工具崩溃并丢失了信息状态,那么就没有方法来恢复进程实例。但是也许这还不是最严重的事情,因为核心进程的运行环境降低了松散耦合的性质会导致所有的服务提供者和用户都必须通过进程服从核心工具的控制。

此外,这里已经完成的是把BPM和面向服务的BPM分开,这种面向服务的BPM建立在差异管理的基础之上。一种理解这种区别的方法是在练习时尝试“去掉服务器”。当一个核心BPM工具停止时,正在运行的进程将会出现什么情况?因为核心工具控制了所有的进程逻辑,包括差异性逻辑,因此停止工具其实就意味着所有进程的终止,这经常是不可恢复的。

解决这些问题就必须要用面向服务的方式保存进程的差异性。也就是说,通过约定的服务提供差异管理,这些服务的目的就是为进程实例保存差异性。本质上,这种方法把消息当作事件来处理,差异保存服务能够对这些事件审计,记录日志,并在以后根据这些记录分析决定给定的差异。这种方法认为差异性是运行系统潜在的缺点而不是运行进程环境应该保存的一些必需信息。这种事件驱动的、面向服务的方法跟踪所有相关的事件,并且有一个单独的服务集合来分析事件流并执行专门的过程,这些活动是基于进程的需求,政策以及服务的协议等。

现在,当进程管理的服务集合停止以后会发生什么呢?因为服务提供者和用户交互的消息包含了持久地标识,这些标识代表了进程的差异性,所以进程的信息将不会丢失。相反,发送到进程管理服务的消息被放进一个队列,等待服务恢复再处理。一旦服务被恢复,则可以继续执行它没有处理完的进程逻辑,因为队列中的消息能够提供它需要的关于当前进程差异的所有信息。

从一个设计师的角度来看,在面向服务的设计中考虑差异性是十分有必要的。服务除非它是差异性管理服务且在特别要求这样做时一般自己不保留差异信息。就算这样做时,它们也管理那些暴露给差异性管理服务的进程。在任何情况下不会有一个服务管理自己的差异性信息,因为一个服务消费者通常自己知道一个服务的内部状态便于确定是否给服务发送消息。如果那样的话会破化SOA中松散关系和封装原则。

有效率的公司设计师已经认识到,就如所有有关SOA的文章中所阐述的,好的设计随协议而改变。也就是说,虽然差异性无关是一个独立的服务通过松散连接获得灵活性的必要条件,状态无关也是商业程序为获得商业目的而需要的条件,所以这种手段是一种平衡来用于它们在采用面向服务设计方法的共同需要。