架构艺术之应用分层设计

图片来自pixabay.com的ROverhate会员

1. 为什么需要应用分层架构设计

高内聚、低耦合、职责单一,是一个应用的基本设计要求。但是起初设计很好的应用边界,随着业务的扩张,待开发的业务功能越来越多,不断拆分出新应用 ,经常出现的问题是,应用之间的相互依赖关系越来越模糊,相互调用,进而出现循环依赖和长链条依赖问题。

举一个简单的业务功能为例,用户下单支付,其需要调用支付中心进行支付、调用会员中心确认可用积分、调用营销中心发放优惠券、调用消息中心发送用户短信等步骤,这里涉及的应用有4个,

  • A 支付中心
  • B 会员中心
  • C 营销中心
  • D 消息中心

一个常见的技术实现是,在应用A中提供一个下单支付的接口,在A中先后调用执行应用B、C、D的接口,串联实现下单支付的功能。这不是理想的技术方案,最大的问题是,支付中心A承担了整个下单支付的流程,不仅需要负责处理各个接口的返回消息,还要处理在接口调用失败下的重试和异常告警,其功能职责不再单一。随着下单支付的业务功能越来越复杂,需要串联的业务流程步骤越多,今天加个促销积分,明天发不同优惠券,支付中心变得臃肿不堪,负责支付的开发工程师苦不堪言。

在调用关系上,到底是A调用B或C,还是从B调用到C,在没有沟通清楚的情况下,各种调用方法实现都有,很容易导致A->B->C->D的长链条调用,或A->B->A的循环调用,应用之间的调用变得复杂。管控的不好,业务架构的可扩展性无从谈起,开发团队之间经常扯皮,一个功能代码到底如何串联?在哪里实现?

这里其实涉及到的关键问题是,应用的逻辑架构和相互依赖关系,这正是应用分层架构设计所要解决的问题。

2. 一个通用的架构分层设计

下面将介绍一个通用的架构分层方案,

应用架构分层设计

如上图所示,这个架构分层设计的要点如下,

  1. 应用根据分层架构划分为四层,从上到下分别为,
    • API网关层:对外提供HTTP接口服务,实现统一的鉴权、流控和降级。
    • 业务聚合层:依赖业务中心服务,调用中心服务所提供的原子业务接口,串联起业务流程,实现基于业务场景的功能接口。其负责流程的异常处理和重试,跟进流程状态。
    • 业务中心服务层:实现单一、独立的原子业务功能,高内聚、低耦合。原子业务的含义是指业务不可拆分,有确定的输入和输出,在输入正常的情况下,必须确保业务的正常完成。
    • 业务数据服务层:提供业务数据的只读查询,不提供写操作。
  2. 应用调用关系必须从上往下调用,不允许同层调用,以免形成互相依赖和循环依赖。
  3. 应用必须按规范格式xxx-gateway/business/center/data命名,以便快速识别其工作的逻辑层次。
  4. 业务中心服务和数据服务应用将共享同一个DAO类库,其数据服务提供的是只读接口。
  5. 业务中心服务层不能相互调用,若有需要,允许通过消息中心进行异步通信调用。
  6. 业务数据服务层不是一定需要,若没有数据查询的需求,可以省略这一层的数据服务应用部署。