随着智能设备普及和移动互联网发展,移动端应用逐渐成为用户的新入口,重要性越来越突出。但企业一般是先有 PC 端应用,再推 APP,APP 1.0 版的功能大多从现有 PC 应用平移过来,没有针对移动自身特点考虑 APP 的架构。随着 APP 越来越复杂,功能和非功能要求越来越高,架构的先天不足逐渐成为大型 APP 升级的瓶颈。
本文作者结合大型移动应用的落地实践,从服务端架构设计角度,阐述如何进行升级优化,为后续 APP 做大做强奠定架构基础,供大家参考。
本文主要内容包括:
- V1 架构
- 问题分析
- V2 架构
- 智能升降级
- 总结
V1 架构
APP 可以分为手机端和服务端,手机端负责 UI,相对简单,服务端负责提供数据和业务逻辑,相对更为关键。APP 1.0 版的服务端架构比较简单,一般在原有 PC 端 web 应用的基础上增加无线接口,供 APP 调用,如图一所示。
图一 APP 1.0 架构
服务端系统一方面以 web 应用的方式提供给 PC 端浏览器访问,另一方面为支持移动,在 web 应用基础上增加一些 REST 接口直接供 APP 访问。相应地,无线接口和 web 应用作为同一工程开发,作为同一个应用部署,这种设计思路是很直接和自然的,可以快速把 PC 端功能复制到 APP。
问题分析
上述设计是在现有 web 应用上打补丁,体现的是 PC 思维无线化,把 APP 简单作为 PC 端应用的翻版,并把两者物理上捆绑在一起,带来一系列的问题:
1、紧密耦合
无线接口和 web 应用紧耦合,web 端的修改会影响无线接口,web 端的发布导致无线接口被动连带发布,web 端的 bug 影响无线接口的可用性,反过来也一样,无线接口的任何变化会影响 web 应用。
2、重复开发
无线接口除了给 APP 提供业务数据,还需要考虑一系列非功能性因素,如通讯协议和数据格式封装、安全控制、日志记录,性能监控等,这些对每个无线接口都适用。如果 APP 和后端系统直连,意味着每个后端系统都需要单独支持这些通用功能,导致重复开发。一旦这些通用需求有变化(如对数据传输进行加密增强),所有后端系统都要强制同步修改和上线,给项目管理带来很大挑战。
3、稳定性
APP 和多个后端系统直连,只要一个系统出问题,就会影响 APP 的可用性,缺乏故障隔离机制,导致 APP 非常脆弱。
这些问题本质上是因为没有把 web 应用和 APP 做清晰隔离,导致相互影响,一损俱损。
那么如何实现有效隔离呢?首先两者共享核心的业务逻辑,所以核心业务逻辑要独立出来,以一致的方式供 APP 和 web 调用;同时,无线接口服务于 APP,和 web 前端没有任何关系,需要进一步对它们进行剥离,单独维护和部署,经过拆分后架构如图二所示。
图二 系统拆分示意
V2 架构
除了 APP 和 web 应用拆分,架构改造还必须考虑 APP 自身的特点。APP 一方面需要从服务端各个系统获取数据,这个是个性的,面向业务;另一方面所有调用需要非功能性的通用处理,这个是共性的,并且和业务无关。架构上需要做到统分结合,共性统一处理,个性分散处理。
最后,结合 APP/web 拆分需求和 APP 自身特点,新的 APP 架构方案如图三所示。
图三 APP 2.0 架构
1、对等隔离
APP 实际上和 PC 端浏览器是对等的,PC 端应用有服务端,APP 也需要自己独立的服务端,两个服务端都需要针对自身的特点,独立开发,独立部署,同时实现逻辑和物理层面的解耦,从架构层面彻底摆脱 PC 思维无线化。
2、统一服务
核心逻辑从 web 应用剥离出来,进行服务化改造,服务实现时不区分 PC 和无线,APP 和 web 应用都依赖于这些服务,一套接口,多方调用。
3、统一网关入口
提供统一的无线网关,所有 APP 调用指向此网关,网关包括通用层、接口路由层、适配层。
通用层
通讯协议适配、数据封装、安全、监控、日志这些系统级功能,每个接口调用都需要同样逻辑,这些功能统一由网关前置处理,避免重复开发。具体实现时,每个通用处理逻辑封装成拦截器,遵循统一的过滤接口,并且做到可配置,网关依次调用这些拦截器,这样可以支持通用逻辑的灵活扩展。
拦截器接口定义如下:
Object filter(Object input) throws Exception
接口路由
经过通用逻辑预处理后,无线接口请求将进一步分发给后端处理(各个 Adapter)。URL 和 Adapter 在配置文件里做映射,分发逻辑根据请求中的 URL 信息,找到对应的 Adapter,然后把请求交给 Adapter 处理。
配置例子如下:
www.website.com/search SearchAdapter www.website.com/detail DetailAdapter
服务适配
外部无线接口和内部 SOA 接口的输入输出格式以及通信协议很可能不一样,比如前者经常是 HTTP+JSON 格式,后者可能是 Hessian+ 二进制格式,Adapter 首先用于无线接口和内部 SOA 接口的适配,除此之外,Adapter 还可能对多个 SOA 服务做聚合,对 APP 提供粗粒度的数据,以减少远程网络调用次数。实现上一般每个业务系统有一个 Adapter,负责本系统无线接口的调用适配。
Adapter 接口定义如下:
Object adapter(Object input) throws Exception
Adapter 物理上是 jar 包,由各个业务线研发团队提供,作为相应 SOA 服务的前置,最终所有 Adapter 集中部署在网关,网关本身支持水平扩展。
智能升降级
网关支持集中管控的同时,也带来单点问题。假设后台某个服务接口,由于某种原因,性能有严重问题,对应 Adapter 处理很慢,那么网关所在服务器的线程很快被耗尽,导致单个接口拖垮整个系统。这种问题,单纯通过加机器,水平扩展网关数量是解决不了的,实践中,我们引入智能升降级机制快速隔离单个接口的影响,如图四所示:
图四 智能升降级
针对特定一个接口,如果在一定时间间隔内(比如 5 秒钟),它的超时失败率到了一定比例 (比如 2%),网关会对该接口做降级处理,随机抛弃部分流量,比如只允许 50% 流量通过。下一个 5 秒再评估,如果失败率还没有改善,允许通过的流量降到 25%,以此类推。
如果成功率好转,网关对该接口做升级处理,提升通过的流量比例,为了快速恢复,一般提升到原流量 4 倍,然后在下一个时间段再评估是否触发升降级。
整个过程全自动智能处理 (为防止误判,可支持人工干预),这样单个接口出问题,不会影响整个网关的处理能力。
总结
APP 服务端架构通过一系列的拆分和整合,既优化了公司整体应用架构,又为 APP 做大做强奠定良好基础,其带来的好处是全方面的:
- 实现 PC 端应用和移动端应用分离,使两者彻底解耦,各自独立发展,APP 从寄生藤变成并蒂莲。
- 底层核心的 SOA 服务基于统一业务规则提供逻辑和数据,接口不区分 PC、无线或其他渠道(如 Open API),避免重复开发,避免业务逻辑被污染。所有前端一母同胞,本是同根生。
- 根据无线本身的特点,支持系统层面的集中处理和业务层面的分散处理。通用逻辑支持插件化扩展,可以根据需要逐步补充;Adapter 实现内外部接口的无缝转换,可以针对无线场景,做逻辑增强(如服务聚合)。前面师傅领进门,后面修行靠各妈。
- 移动研发团队和各业务线研发团队各司其职,每个团队专注于自己擅长部分,移动团队负责 APP 客户端和网关通用逻辑处理,各业务线研发团队负责底层 SOA 服务及前端 Adapter 适配。上帝的归上帝,凯撒的归凯撒。
如果用一个字描述 APP 架构,V1 是“爪”,年幼依托各家;V2 是“丫”,长大独立成家。
新架构,大型 APP 应用的成年礼,你“Y”准备好了吗?
作者介绍
王庆友,前 1 号店首席架构师,先后就职于 ebay、腾讯、1 号店等公司,精通电商业务,擅长复杂系统业务建模和架构分析,同时在构建大规模的分布式系统方 面有丰富实践,尤其在大型系统的 SOA 改造方面有很深入的理论和实践,目前在寻找合作机会,微信号 Brucetwins,个人公众号 software-arch,欢迎一起聊架构。
感谢郭蕾对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们。
评论