API设计模式漫谈 - 架构部署
在之前的文章里,我谈到了后续继续编写关于API系统进行软件架构时的一些基本思路和组件的选型。在这次的章节里面,我主要着重于谈谈API系统的基本架构和部署。
部署
当我们装备需要搭建一个API系统的时候,首先要考虑的是整体系统部署的架构。部署的方案往往会对系统的结构有决定性的影响。当我们需要动手开始搭建一个API系统之前,我们需要问自己一个问题:从宏观上看,这个系统我们希望如何进行部署?
很多 API 系统是这样部署的(简称方案一):
(在这里面,load balancer 和 nginx proxy (web server) 可能是同一个集群。暂且从逻辑上把他们划分开来。)
如上图所描述,这是一种很典型的做法,把所有的 API 放在一套系统里部署,简单,高效,容易上手。然而,随着时间的推移,系统功能的功能会越来越复杂,导致整体系统会逐渐不堪重负。比如说我们做一个内容发布平台的 API 系统(类似于微信公众号接口),起初我们可能只需要考虑功能相关的 API,渐渐地你要加入统计相关的 API,然后我们又需要用户行为相关的API,它们各自访问不同的数据源,行为方式也大不相同(部分内容相关的API可以做缓存,但是像统计和用户行为相关需要保证实时性的API不能做缓存)等等,当这些逻辑结构各异的 API 被揉进一个系统里时,这个系统会越来越难以维护。
所以,这样的部署方案会演进成下面的部署方案(简称方案二):
我们把API系统按照对应的接口功能做了拆分,load balancer / nginx proxy 之后是一个个 API application。它们有自己的 load balancer / nginx proxy,可以按照每个 API application 本身的规模进行调整、部署或下架。比如说内容相关的API,其并发访问量(折合成运算量)是用户相关API的5倍,那么,部署的时候我们可以把资源按照 5:1 的比例部署;再比如在高峰期整个系统负载过大,可以把统计API服务停止,在 proxy 侧直接返回503,把节省的资源配置到其他地方。
除此之外,方案一和方案二的软件架构还有一个很重要的不同。方案二中,两个 API application 间的访问可以通过 RPC(也可以使用 HTTP 协议)完成,而方案一中,可能唯一的途径就是直接就是直接访问对方的数据库,简单粗暴且不能做到很好的数据划分与抽象隔离。而方案二是一种分治的思想,把大的问题变成一条公共路径上若干相似的小问题的解决,这样可使得整体系统架构具有更健壮的合理性、扩展性和可维护性。
这里谈到的部署方案刻意忽略了一些细节,比如说日志如何收集和管理,服务本身的监控和信息的收集(APM)等都没有提及。它们是部署方案中的关键环节,但毕竟本文不是专门讲部署的实施方案的,故而忽略。