研发的那些事3--接口之本
从前,有个程序,
只有一个模块,自己搞定所有事情,简单又快乐地生活着。后来,干的事多了,需要划分职责,
加了新模块,不过他们需要彼此沟通协调工作……好在是进程内的,如C#,Java之类的写几个Interface就搞定协作规范了。不过,再后来变成了两个程序
这下麻烦更大了,因为你说话时,对方可能睡着了zzZZ。甚至,你可能需要同老外交流,更甚至,对方可能来自遥远的半人马座。很明显,接口不是简单的”interface”。
接口的本质是一个协议——双方交互的规范,是双方为完成某件事情而事先做的一系列约定。约定分为三个层面:展现、业务和通信。业务层是核心,承上启下,需要考虑如何直观自然的表达业务。通信层是双方的沟通方式。展现层则重在考虑沟通双方的使用方式。如下图:
业务层(这是核心)
一、协议的形式
- 命令式:通过一连串的指令进行交互,指令序列规定了具体执行的步骤,即先1,再2,而3。 如:TCP的三次握手:SYN,ACK,SYN,ACK。
- 文档式:通过文档形式进行交互,文档只说明要什么即目的,不规定任何执行细节。如:REST形式的接口。
二、协议的内容
- 命令式:请求命令有哪些,具体内容如何。对应的响应命令有哪些,内容又是怎样的,正确结果如何表达,错误又如何表达。
- 文档式:如何表达请求,如何表达响应,包括正常情况与错误情况。
通信层
一、通信方式
完成交互,还需通过一种通信方式为载体,传递具体协议的信息。通常通信环境有以下三种:
- 进程内 :如一个进程内的两个模块。通常将命令直接映射成一个个API,采用普通的API调用,协议设计直接简化成API设计。
- 进程间 :两个进程间交互,如果有要求较高的性能,一般采用管道方式。如果需要多进程交互,可采用消息队列方式,解耦发起方和处理方,并简化互相间的连接管理。对于文档风格的协议,在简单的生产和消费的情况下,也可采用直接文件传递的方式,一方读,另一方写。
- 机器间:进程分布在多个机器上,可以考虑:
- 文件:在一对一的生产-消费模式下,最“愚蠢”文件方式有时反而是最简单的高效。特别是异构系统间的一对一通信,可使用此方式,一次传递批量命令。
- 数据库:多个异构系统间的通信,也能通过中央数据库进行。但是,频繁的修改和读取同样数据会带来性能瓶颈和死锁。
- 基于消息:通过一个消息系统传送命令、结果和文档。能从空间和时间上解耦发起者和处理者,两者可以互相不知晓对方的存在,发送和处理消息可以异步进行。可以实现点对点或发布/订阅方式。
- RPC:直接模仿本地调用,将一个方法调用转换成一个数据块,使用一种基于TCP/IP的传输协议进程点对点传输。
二、数据格式
确定通信方式后还需要考虑,传输时的具体数据格式。
- API方式:方法的签名及参数
- 文件方式:文件格式(如XML,TXT,领域专有的文件格式),通常还可定义一个描述格式的元文件,供对方根据它自动生成解析程序。如XML,需要考虑其具体Element,Attribute,通常用XSD定义。
- 数据库:数据库Schema。
- 消息:在MOM系统中使用的消息头和消息体的具体内容。
- RPC:自定义传输通道时需要考虑,传输数据包的格式。可采用:
- 应用层叠加:在已有TCP应用协议上再增加一层专有业务数据格式。简单,无需考虑TCP传输层的编码与解码。如传统WebService是 SOAP over HTTP的,在HTTP中传输SOAP格式的数据(如果需要也可)。
- 开发新应用层:直接在TCP层上增加业务专有的应用协议。需要考虑传输层的编码与解码,涉及数据分包、校验等。如Remoting。
展现层
无论业务与通信如何设计,使用者最终需通过一个API,完成交互。这个API即我们通常说的“接口”。存在两种方式:
- 业务无关API:直接暴露下层协议细节,通过一个一般化的API完成工作。好处是对提供者而言所需工作小,可轻易跨平台,当然消费者需要了解协议细节自行完成解析。一般用作文档风格的协议的提供方式,如RESTful接口,可直接通过本地HTTP API使用。
- 业务专有API:即Wrapper。通过包装器,封装掉所有协议细节,在API上直接表达业务,简化使用。缺点是需要提供每个目标客户端平台的API实现。
使用范围也会影响接口的设计。如果是公司内产品的交互,无论下层如何设计,通常会考虑提供包装器,供相关团队使用,因为客户总是需要写类似代码的,不如由一个人(团队)干了造福大家。如果是公司间产品的交互,在Java和.net上,大Web服务还是不错的选择。一方面,虽然重,但因为有工具可以自动生成接口代码,所以也轻了点。另一方面,大Web服务容易达成共识,因为WSDL是标准元数据格式,沟通方便。至于互联网上,各式Open API都是类REST的,因为Web是天然面向文档的,暴露的又都是资源,如此最自然,提供者所作的工作最少。至于消费者,天知道他们用什么语言平台来访问,只能请他们自己解析了:)
SOA中的接口
单看技术层次,SOA的核心是服务,服务有三个基本要素:契约、实现和绑定。契约是服务所提供功能的一个规范,重在表达业务概念;实现是服务的具体在语言和平台的落地,包含提供者的实现和使用者的API;绑定则是服务之间的具体通信协议。分离了使用、业务表达和通信。
最后再看看经典的ISO模型