将“懒人”哲学运用于大规模的贸易SOA应用开发

将“懒人”哲学运用于大规模的商业SOA应用开发

 

在读大学的时候,老师就灌输了一个道理,计算机科学与技术很重要的一个重要层面就是解决日常工作的信息化和自动化。因此,尽量要将复杂的事情简单化,简单的事情模板化,可模板重复的事情自动化,可自动的事情规范化,最大程度的释放生产力,使人可以更加关注创新。用马云的哲学解释,就是尽可能的做一个聪明的懒人,懒出风格、懒出境界。

SOA企业架构的框架设计中,在企业ESB平台总线上面不乏存在有大量的接口服务,而这些服务的颗粒度、数量往往随着企业业务的精细化标准息息相关。对于SOA能力成熟度相对较低的企业,往往只有端到端横向的数据交互接口;而对于SOA能力成熟度相对较高的企业,不仅关注端到端横向大流程的衔接,能力流程纵向扭转也会存在大量接口,而且种类相对较多。这里面不乏存在着消息接口、文件接口、数据ETL接口、REST资源接口,以及我们最为熟悉的SOAP接口,而且数量随着SOA能力成熟度越是成熟,数量也越是剧增。那么是否应该每个业务需求都要按照接口开发流程重新执行一遍开发工作呢?无论自顶向下,亦或自底向上的开发方式都需要重复开发、重复部署呢?如果真是这样的话,那么很有可能出现开发生产力不能适应快速的需求变化,违背了SOA推行的“随需而变”初衷。

因此,回答SOA服务是否随需求需要重复开发、重复部署的答案肯定是否定的。尽管需求很多,场景复杂,服务数量不能确定,但是服务的类型肯定无外乎就那么几种,虽然其内部实现的业务逻辑肯定千差万别,但是其开发过程和部署发布方式,相同类型的服务肯定研发流程都是一样的。因此,一旦事情出现了规律,那么用老大的原话套用就要把他“模板化、参数化”。

本文以简化SOAP类型接口服务开发流程为例,介绍如何在SOA企业架构的框架设计中,在满足需求的前提下,减少开发工作量和提高开发质量。相比其他类型接口,SOAP类型接口服务最为常见,因此简化它的开发工作也最具有代表性。

首先,假设作为服务的消费方。那么如果ESB存在成百上千的接口服务需要调用获取相关信息或执行业务流程,那么是否每个外部接口,都需要根据其SOAP合约都一对一的开发一套客户端调用程序呢?如果这是在调用一个Hello World的服务做开发练习,或者消费服务数目不多的时候,那么确实应该按照传统的方式一个SOAP服务的服务端与一个客户端一一对应,但我们是大规模的商业SOA应用,服务数量众多,如果按照传统方式不但服务数量众多而且很多开发步骤都基本类似,那么作为“聪明的懒人”就有理由要动脑子想办法优化了。大概分析一下开发一个SOAP客户端的步骤:

1、  获取WSDL

2、  生成代码

3、  对象绑定与映射

4、  业务逻辑处理

那么会发现在借助于一些Web Service框架的情况下,只有第四步才是需要手工开发完成的,其余都可以自动生成。那么是否实现了“自动”就够了吗?难道有100个服务端,就要开发维护100套客户端吗?难道就没有更优雅的做法了吗?当然有!CXFDynamicClientJAX-WS Dispatch API均给出了答案。它们二者的出发点和思路都是一致的,即N:1的形式,再多的服务端,只有一个功能强大的客户端,类似Java的工厂模式。只不过DynamicClient运用了大量的反射机制,而JAX-WS Dispatch API直接操作XML消息,因此从性能上选择考虑JAX-WS Dispatch API的实现方式更好,不仅将服务客户端数量剧减至1个,并且直接操作XML消息,避免了Java对象和XML之间marshallingunmarshalling的反复绑定转换,实在是客户端中的战斗机啊!下图示意了二者之间的对比。

 将“懒人”哲学运用于大规模的贸易SOA应用开发

 

其次,假设作为服务的提供方或代理方。作为一个服务端的直接或间接提供者,其工作主要包括两部分内容:即业务逻辑的实现或者封装代理,以及服务的部署及发布。如果以AOP的哲学看待这个问题,那么“业务逻辑的实现或者封装代理”是一个服务提供者的核心工作,而“服务的部署及发布”是次要工作。那么是否可以以80-20的方式将重心放到核心工作,尽量简化次要工作,尤其是大规模的商业SOA应用中,不想因为本来就多需求开发工作再带来一些不必要的重复工作呢?答案当然是可以,“聪明的懒人”要用“懒人”的哲学想问题。大概分析一下开发一个SOAP服务端的步骤:

1.         获取WSDL

2.         生成代码

3.         对象绑定与映射

4.         业务逻辑处理

发现和客户端的开发步骤基本类似,唯一不同的是一个对请求的处理,一个对响应的处理。那么是否可以采取类似的方式优化呢?答案不是不可以,但最好不要!分析上面的架构设计,那个强大的客户端工厂在每次请求时,都可以动态生产客户端对象,并生产请求消息进行调用;但如果用一个服务端工厂来实现所有服务对象的处理,那么在服务部署后,服务端工厂的生命周期交由容器维护,一旦一个服务请求导致服务端工厂挂起或假死,那么所有服务均不可用。违背了SOA解耦分离的初衷,因此此方案在服务端实现高可用是不可取的。还是应该一个服务对应一个唯一的SEI和实现,只不过我们只关注其核心工作,次要工作可以通过简化或者动态实现。主要思路如下:

1、  根据接口规范定义SOA契约文件(WSDLXSD

2、  通过构建工具动态构建工程(如:maven archetype

3、  通过SEI实现插件完成代码实现或代理(如:maven plug-in

4、  自动打包(如:maven install

5、  部署(maven 还是maven…

通过上述思路实现,虽然服务数量和传统方式没有变化,但是过程更加关注与实现或封装,剩下的工作都按照AOP的哲学去解决吧。运用“懒人”哲学节省下来的时间可以花在其他创新方面。