背景
在跨系统对接方法中,通过HTTP/RESTful API是常用的系统对接方法,但有些情况使用HTTP API并不是最好的方案。本文尝试探讨这个问题。
历史
很多年前,常用对接系统的方式是FTP。请求方把所谓 EDI 文件按照规格放到一个 FTP 服务器的某一个目录下面,而处理请求的一方会把文件取走作进一步处理,处理完毕后,按照规格会把适当的档案名字的结果文件放到一个指定目录下面,请求方通过FTP 来抓取处理结果。
这个对接方式现在还出现在一些老行业(如仓库、物流等领域),但在现代技术的眼光,这种方式毕竟有点过时。
其后新兴了 WebService,SOAP / RESTful 都是基于类似的方式:HTTP 请求/返回。HTTP优点是实时性很好,主要原因是HTTP协议直接对接应用服务器产生动态内容。自从有了HTTP对接方式之后,一些老方式开始不怎样被人接受了。
但是HTTP方式并不能很好接受一些需要长时间运算的请求(异步方式),返回时间过长会导致请求超时,而消息队列MQ的出现解决了这方面的问题。
技术分析
存储特性
本质上对接的意义是消息传递,传统意义中消息传递是【保存再传递】(Store-and-Forward)的意思。保存再传递的例子是:
- 写封信并寄出:写信就是把信息保存到一个载体(纸)上,并经过信差传递
- 电子邮件:消息存在一个服务器,再发送到另一台服务器
- FTP文件对接:消息被放在一个服务器的文件夹中,等候被获取
- 消息队列中的消息传递:生产者把消息存在服务器中,服务器经过路由配置转给消费者,等候消费者取走消息
保存的意义在于:当接收方出了什么问题,消息依然存在,不会因为接收方的不在线导致信息丢失。
例如信息是一句话,发送者把话说完,期望你在听的,结果你没在听,信息就丢失了。这个例子,异常处理责任在发送者身上,造成发送者的处理压力。
比如说水塘有缓冲作用,可以某程度上抵消上游和下游压力的差异。若消息没有被存储,而下游处理能力不足,会导致上游信息挤压,到最后上游系统崩溃。所以没有存储缓冲的对接架构在本质上是不稳定的。如WebService,若服务处理能力不足,导致调用请求积压,最终大部分请求超时,若消息很重要,客户端会进行重试,客户端线程因此被占用,到最后客户端只能一直等待和重试直到成功。
若换个带存储的对接方式(如FTP 或 MQ),情况就简单多了。发送者发送完消息,基本上责任已经完成了。只要消息是成功发送的,发送者基本不存在后续失败的责任。消费者若不在线也没关系,FTP或MQ成了消息水塘,只要存储空间足够,系统对接方面还是稳定安全的。
消息的方向性
系统是在某个信息的上游或下游,定义仅在信息的流向来决定,而不是用什么传输方式决定的。
消息有推拉之分:同样是HTTP接口,若是GET请求,就是向服务器请求信息。若是POST/PUT
就是向服务器推送信息。所以用HTTP方式,容易混淆消息流向的推拉关系:同一组客户端和服务端,有时候是推送信息(POST),有时候是拉信息(GET)。
但在消息队列的方式,不存在这种混淆:永远都是发送者主动推送消息,消费者被动接收信息,并没有消费者直接拉信息之说,就算消费者真的想拉信息,水塘是干的也拉不到任何消息。
对接策略
基于上面的特性分析,我会建议系统对接的方案如下:
- 只读的查询方法来获得信息,即信息拉动,用HTTP接口
- 需要传递消息/推送消息,目的是要改变接收方的状态(写的接口),用MQ
例如我们准备填制一张表单,表单中有个基本数据要在后台系统1准备,作为下拉选项,而信息是来自后台系统2。信息流是拉动数据到用户表单中,使用HTTP。
填制完了需要提交,一般会用POST发送到后台系统1 ,然后后台系统1也许需要把信息推送到其他下游系统(后台系统2)中进行进一步处理,用MQ。(这种情况不建议用HTTP发送)