系统架构是一个不断演化的过程。虽然有时少部分架构演化可能需要彻底推倒重写,但大多数情况下,架构演化是通过架构重构来实现的。相比全新的架构设计,架构重构对架构师提出了更高的要求,主要体现在以下几个方面:
业务已上线
在架构重构过程中,业务已经在线运行,这意味着重构需要在保证业务持续发展的同时完成架构调整,类似于“给飞行中的波音747换引擎”。相比之下,新架构设计在业务尚未上线时进行,即使出现问题对业务的影响也较小。
关联方众多
架构重构涉及多个业务关联方,各方资源投入、业务发展速度和对架构问题的敏感程度各不相同。如何减少对关联方的影响,或者协调各方共同行动,是一项挑战。新架构设计在上线前对关联方没有影响。
旧架构的约束
架构重构必须在旧架构基础上进行,这是一个约束,会限制架构师的技术选择。新架构设计中,架构师的技术选择范围更广。
数据转换
即使完全推倒重来设计新架构,新架构也会受到旧架构的约束和影响,因为业务在旧架构上产生的数据不能重来。新架构必须考虑如何将旧架构产生的数据转换过来。
综合能力要求
架构重构对架构师的综合能力要求很高。他们需要说服产品经理暂缓或暂停业务,与其他团队达成一致的架构重构计划和步骤,提出让技术团队认可的重构方案。因此,架构师需要在业务、团队和技术方面具备广泛的能力。
通常情况下,当系统架构无法满足业务发展时,会出现一系列问题。这些问题可能表现为系统响应缓慢、数据错误、部分用户访问失败等轻微情况,严重时可能导致系统宕机、数据库瘫痪、数据丢失,或者系统开发效率低下。
起初,技术团队可能会针对具体问题进行解决,一次又一次地应对。然而,如果问题持续存在,可能长达数月甚至一年之久,团队可能会开始怀疑系统架构是否存在问题。这时,就会开始讨论是否需要进行架构重构。一旦确定需要重构架构,架构师将领导架构重构的分析和实施。
当架构师开始进行架构重构分析时,往往会感到如同进入了一个迷雾森林,到处都是问题,每个问题都需要解决,让人感到无从下手。有些架构师会开始收集系统当前存在的问题,并汇总成一个长达100行的Excel表格。看到这样的表格,他们会感到困惑:这么多问题,要解决完需要花费很长时间啊!
然而,期望通过架构重构解决所有问题是不现实的。因此,架构师的首要任务是从这些问题中识别出真正需要通过架构重构来解决的问题,并集中精力快速解决这些问题。重要的是专注于解决核心问题,而不是试图通过架构重构解决所有问题。否则,团队可能会陷入人手不足、任务繁多、头绪混乱的境地,花费大量时间和精力,最终发现虽然做了很多工作,但每个问题依然存在。
特别是对于刚接手一个新系统的架构师或技术主管来说,控制住冲动,避免过度重构和优化是很重要的。要避免进行摊大饼式或运动式的重构和优化。
我们来看几个具体的重构案例。
1.平台系统重构:解决不合理的耦合
M 系统是一个后台管理系统,负责管理所有游戏相关的数据,重构的主要原因是因为系统耦合了 P 业务独有的数据和所有业务公用的数据,导致可扩展性比较差。其大概架构如下图所示。
图片
举一个简单的例子:数据库中的某张表,一部分字段是所有业务公用的“游戏数据”,一部分字段是 P 业务系统“独有的数据”,开发时如果要改这张表,代码和逻辑都很复杂,改起来效率很低。
针对 M 系统存在的问题,重构目标就是将游戏数据和业务数据拆分,解开两者的耦合,使得两个系统都能够独立快速发展。重构的方案如下图所示。
图片
重构后的效果非常明显,重构后的 M 系统和 P 业务后台系统每月上线版本数是重构前的 4 倍!
2. 游戏接入系统重构:解决全局单点的可用性问题
系统是游戏接入的核心系统,一旦发生故障,将导致大量游戏玩家无法登录游戏。然而,S系统并不具备多中心的能力,一旦主机房发生故障,整个S系统业务将不可用。其大概架构如下图所示,可以看出数据库主库是全局单点,一旦主库不可用,两个集群的写业务都将不可用。
图片
针对 S 系统存在的问题,重构目标就是实现双中心,使得任意一个机房都能够提供完整的服务,在某个机房故障时,另外一个机房能够全部接管所有业务。重构方案如下图所示。
图片
重构后系统的可用性从 3 个 9 提升到 4 个 9,重构前最夸张的一个月有 4 次较大的线上故障,重构后虽然也经历了机房交换机宕机、运营商线路故障、机柜断电等问题,但对业务都没有什么大的影响。
3.X 系统:解决大系统带来的开发效率问题
X系统是创新业务的主系统。在业务快速尝试和快速发展阶段,系统设计着重于方便操作和快速开发,没有投入太多精力和时间。许多功能都被“塞”到同一个系统中,导致现在已经难以进行改动。为了实现新功能或业务,需要花费大量时间来讨论和梳理各种业务逻辑,存在踩坑风险。X系统的架构如下图所示。
图片
X系统和M系统在可扩展性问题上看似相似,但根本原因不同。M系统的可扩展性问题源于数据耦合,而X系统则是因为将所有业务功能集中在一个系统中,导致可扩展性不足。此外,所有功能集中在一个系统中也可能导致某个功能出现问题时整站不可用的情况。举例来说,如果某个功能导致数据库负载过高,整站的业务都会受到影响而变慢。
针对 X 系统存在的问题,重构目标是将各个功能拆分到不同的子系统中,降低单个系统的复杂度。重构后的架构如下图所示(仅仅是示例,实际架构远比下图复杂)。
图片
重构后,各个系统之间通过接口交互,虽然增加了接口的工作量,但整体上各系统的发展和开发速度比原来快了很多。系统也相对更加简单,不会出现某个子系统有问题导致所有业务都有问题的情况。
回顾重构这三个系统的方案,现在看来似乎是理所当然的,但实际上在进行分析和决策时并不简单。以M系统为例,当时接手后遇到了许多问题:
- 数据经常出错。
- 单机系统宕机后所有后台操作不能进行。
- 性能较差,有的操作耗时较长。
- 界面丑陋,操作不人性化。
- 代码混乱,历史上经过多次转手。
- 业务数据和游戏数据耦合,开发效率低下。
从这些问题中识别出重构的目标并不容易;要解决所有问题又需要耗费大量人力和时间!因此,架构师需要透过问题表象看到问题本质,找出真正需要通过架构重构解决的核心问题,从而做到有的放矢。这对架构师的分析和判断能力要求非常高,不能一看到问题就想到架构重构,也不能只是针对问题进行系统优化。
当然,原来发现的那些非架构重构问题也不能放任不管。重构完成后,我们启动了多个优化项目来解决这些问题,但这些优化主要由团队内部完成,和其他团队关联较少,因此优化速度很快。如果没有重构而是直接进行优化,则每次优化都需要拉一大堆关联业务的团队来讨论方案,效率非常低下。