论软件系统分层架构

软件架构风格是描述一类特定应用领域中系统组织方式的惯用模式,反映了领域中诸多系统所共有的结构特征和语义特征,并指导如何将各个模块和子系统有效组织成一个完整的系统。分层架构是一种常见的软件架构风格,能够有效简化设计,使得设计的系统结构清晰,便于提高复用能力和产品维护能力。由于大量企业应用系统都由界面呈现、业务逻辑、数据存储三类功能构成,因此广泛采用分层架构风格进行系统设计。

请围绕“企业应用系统的分层架构风格”论题,依次从以下三个方面进行论述。

  1. 概要叙述你参与管理和开发的企业应用系统建设项目以及你在其中所承担的主要工作。
  2. 请结合项目实际情况,指出应用系统都有哪些层次以及每个层次的主要功能。
  3. 请结合项目实际情况,指出设计每个层次时需要注意的问题及相应的解决方案。

试题出自试卷《2013年下半年系统架构设计师考试论文真题》

摘要

2018年9月,我所在的部门因公司业务发展需要,承担了公司的实时消息平台的研发工作。该平台提供了即时通讯、消息推送、社交圈等功能,满足C2C(用户对用户)、C2B(用户对商家)、B2C(商家对用户)的沟通需求,同时为公司内其它业务子系统间消息流转提供支持。我在该项目中担任系统架构设计师的职务,主要负责设计平台的系统架构和技术选型。本文以实时消息平台为例,讨论了软件分层架构的选择和应用。在该项目中,我结合实际业务需要,从开发和维护难度、稳定性、可靠性和可扩展性等方面综合衡量,为平台选择了接入层、逻辑层、数据访问层的三层分层架构。平台的研发耗时4个月,目前,系统已稳定运行了近2年。实践证明,这种架构设计有效的降低了系统的维护和开发成本,增强了系统的稳定性和可靠性,提高了系统的可扩展能力。

正文

随着移动互联网技术的迅猛发展,我所在的公司的在各业务子系统的开发过程中发现,用户、商户、客服之间进行沟通的需求越来越大,各业务子系统间进行消息流转的需求愈加频繁,且使用起来十分繁琐不便。为此,公司于2018年9月开始研发设计通用的实时消息平台(以下简称为“系统“)。该系统致力于为公司内各业务产品线提供基础通用的消息服务,降低公司内各业务子系统间进行信息交互的复杂度,满足C2C(用户对用户)、C2B(用户对商家)、B2C(商家对用户)的沟通需求。该系统为C端用户提供了私聊、群聊、密聊、聊天室、漂流瓶等多形式多场景的即时通讯功能,同时,该系统还支持公司内各业务子系统间进行消息流转,如B端商家通过该系统可以定向地为用户实时推送各种业务消息,如订单消息、活动促销消息等。本项目组全体成员共10人,我在里面担任系统架构设计师职务,主要负责项目计划制定,需求分析,整体架构设计与技术选型。本文结合作者的实践,以消息平台系统为例,对比分析两层架构和三层架构,讨论三层架构中接入层、逻辑层和数据层的设计过程和实施方法。

在传统的C/S两层体系结构中,客户端用户界面和业务逻辑耦合在一起,用户界面层直接调用数据库访问实现。两层体系结构只适用于那些比较简单的企业应用系统中,但难以适应新的需求、不易维护、安全性差。三层结构则由表示层/接入层、业务逻辑层、数据访问层构成,表示层/接入层为用户提供交互操作界面,业务层负责关键业务的处理和数据传递,数据访问层实现数据访问。优势是当数据库或用户界面发生改变是不需要重新开发,只做简单的调整即可。基于三层结构来架构的应用系统具有稳定性、安全性和处理能力较高等特性,同时拥有可扩展性强、开发周期短等优点。

作为一个通用的实时消息平台,系统首先必须具备高可用性和高可靠性,其支持业务子系统对接的特点又决定了其必须具有良好的扩展能力。我通过技术调研和讨论分析,决定将系统划分为接入层,逻辑层,数据层。

接入层,是客户端接入消息平台的门户,主要负责统一鉴权、保持长连接,初步攻防,加解密,压缩解压缩等功能。为了防止DDOS等恶意网络攻击,我们采用了“WAF+DDos高防”安全策略来保护消息平台。接入层本身不含业务逻辑,它是无状态的,因此可以很方便得进行水平扩展,出于对成本与技术成熟度等方面的考虑,我们采用了基于Ngnix的负载均衡技术,以应对日益增长的数据吞吐量,提高平台的可用性。由于系统的核心业务是实现消息的实时传递,对连接的可靠性非常敏感,我们采用了“WebSocket技术 + 心跳机制”,保持客户端和消息平台的长连接。为防止恶意用户对消息平台进行洪泛攻击,在不影响正常业务功能的前提下,我们采用了令牌桶机制来限制客户端发送消息的频率,保障平台的稳定性和可用性。出于节省带宽流量方面的考虑,客户端与消息平台之间进行交互的消息都是经过加密、压缩过的,因此,接入层还需要对收到的客户端消息进行解压缩、解密,对推送给客户端的消息进行加密、压缩处理。

逻辑层,负责实现消息平台本身的核心业务逻辑处理,如私聊、群聊、密聊、聊天室、漂流瓶以及业务子系统的消息推送等业务场景。为增强系统的可用性和可扩展性,逻辑层也保持了无状态性,同样支持水平扩展。为解决无线环境下网络不稳定导致的“消息丢失”问题,系统收到消息后,先持久化到数据库,再进行相关的业务逻辑处理,以保证消息不会丢失。针对客户端“重复发送”消息的问题,我们采用了客户端和消息平台协同处理方案,具体为:客户端在发送的的消息体里带上唯一的消息标示码(如根据“用户Uid+当前时间戳毫秒”规则生成UUID),若逻辑层根据根据该标示码在数据层查询到该消息已存在,则直接返回消息重复错误给客户端。逻辑层还支持各个业务子系统接入到消息平台,具体实践中,我们通过引入kafka消息队列,将客户端发送的消息,根据业务方注册时绑定的主题,发送到相应的业务消息主题队列,以达到消息平台和业务模块的解藕。 另外,业务子系统也可通过逻辑层开放的RPC接口实时推送业务消息给客户端,实现了业务子系统和消息平台间的解耦。消息平台和业务子系统间进行双向消息传递均实现了解藕,新增业务子系统,消息平台无需改动代码,增强了系统的可扩展性,同时也降低了系统的维护成本。

数据层,涉及缓存,文件系统,数据库,搜索系统等模块。由于用户对数据的访问具有集中性,所以我们基于Redis实现了缓存机制,将用户访问频率较高的用户信息、群组信息等置于缓存,减少对数据库的访问压力。从我们系统的业务特性来看,数据库操作是“读多写少”,所以我们对数据库进行了一主多从读写分离。数据库访问采用了数据库连接池的技术,以固定的连接池大小为限,使用有限的数据库连接,提高对数据库操作的性能,保障数据库服务的高可用。开发实践中,我们采用了比较成熟的Gorm组件,用于实现数据和模型的绑定,该方法开发高效,敏捷,成本较低,而且兼容多种主流数据库,开发人员不必再去写大量繁琐的SQL语句,节省了开发成本。

结尾

2019年1月,该系统正式上线运行,至今已稳定运行了接近2年时间,满足了用户常用的即时通讯需求,同时为公司内各大业务子系统提供了稳定可靠的消息服务支撑。系统所采用的三层分层架构在降低开发与维护难度、加强平台可用性、提高系统稳定性、增强系统可靠性等方面都发挥了重要的作用,获得了领导和同事的好评。当然,这种架构也存在一些不足,如我们接入层采用的负载均衡算法是加权轮转算法,过于简单,常常出现资源分配不合理的现象,可将算法改进为加权最小连接数算法来解决。分层架构所具有的优点和面临的问题将是我今后在同类系统的架构决策方面需要重点考虑的因素。

彦祖老师 wechat