一家中型互联网公司的架构演进之路

2022-11-03 00:00:00 功能 微服 架构 业务 自如

在云原生架构出现之前,大家谈论多的是微服务架构。有的企业可能只有一种架构,有的企业经历过多种架构的演变。架构的选择与企业当前所处的阶段

有很大关系,好的架构都是为了解决当下企业面临的业务问题而诞生的。


引用王小川老师在中国计算机大会(CNCC)分享的一句话:“技术与业务的关系就像汽车,汽车有三大组件—车轮、发动机、方向盘,分别代表了3种技术与业务的关系,分别是技术支持、技术驱动、技术颠覆。”95%的企业是技术支持型企业,一般都是先追求业务的快速迭代试错,架构一般会滞后于业务的发展,在架构跟不上业务的迭代速度,或有巨大的历史技术债务出现时,技术架构才会进行新一轮的迭代。同时,没有任何一个架构是“银弹”,凡是能够解决当下企业面临的问题的架构就是好架构。


本章首先介绍企业级架构的演变过程,包括大部分企业都会经历的单体架构、分布式架构、微服务架构,以及近几年比较火爆的中台架构;然后结合自如的业务特性介绍自如技术架构的历史变迁,还原一个中型互联网公司的架构演进之路。相信很多读者在读完本章后,能够找到自己企业的影子。


2.1 技术架构的演进

什么是架构?架构有哪些特点?架构有哪些分类?一万个读者可能有一万个答案。

本节将从架构的定义出发,介绍几类常见的架构形态及其演变路径,从单体到分布式、从分布式到微服务、从微服务到中台。并不是新的架构就是好的,符合企业当下业务形态的架构才是好架构。那么,如何选择符合自己业务的架构呢?让我们从了解每个架构的特点开始。

2.1.1 架构的定义与分类

1.架构的定义

架构(Architecture)这个词源自建筑行业,以下引用百度百科的描述。

软件架构(Software Architecture)是一系列相关的抽象模式,用于指导大型软件系统各个方面的设计。软件架构是一个系统的草图。

通俗地来讲,技术架构就是对软件系统各个维度进行不同模块化的抽象,通过抽象使原本复杂的工程变得易于理解和分工实现。就像泰勒提出的科学管理,通过标准化的作业流程和分工,原本混沌复杂的软件工程被拆分出前端、后端、质量、运维等多个岗位。以后端为例,根据不同的岗位职责,按照康威定律又被拆分出不同的组织,比如订单组、用户组、交易组等,进而使整体的生产力大大提升。因此,架构的本质是抽象分类,进而指导软件系统的实现。

2.好的架构特征

通常好的架构要能够支持高并发、高可用、高扩展。这些都是架构设计中应该关注的特性。除此之外,好的架构还应该关注如下特性。

可用性和可靠性。由于软件系统对于用户的商业经营和管理来说极为重要,因此软件系统必须非常可靠。可用性和可靠性虽然是两个不同的属性,但本质都是为了提升业务连续性,使企业的业务尽可能不中断。

高性能。高性能体现了架构在同样的物理配置下的业务支撑能力,更高的吞吐量、更低的响应时间意味着对用户更快速地响应。

易维护性。软件系统的维护包括两方面,一是排除现有的错误,二是将新的软件需求反映给现有系统。一个易于维护的系统可以有效降低技术支持的费用。

可扩展性。市场和用户总是在不断变化的,为了适应业务的高速迭代,尤其是一些2B企业的个性化需求,架构要求能够在小的改动成本下满足更多的需求。这要求架构可以根据客户群的不同和市场需求的变化进行调整。

安全性。随着《个人信息保护法》和《数据安全法》的出*台,信息安全已经成为架构设计中重要的因素,安全合规不容小觑。

3.架构的分类

我们常听到各种关于架构的名词,比如业务架构、功能架构、应用架构、技术架构、物理架构等,很多读者可能分不清,这里我们简单梳理一下这几个架构的区别。

(1)业务架构

业务架构一般是指业务的关键流程、组织形式、信息流。以电商为例,业务架构包括选品、采购、仓储、物流、供应商、订单等一系列的业务版块。业务架构体现的主要是业务模式和流程,核心是定义业务痛点,厘清功能需求和非功能性需求。

(2)功能架构

功能架构一般是指产品具备的细分功能。例如,电商系统的功能架构可细分为用户管理、登录注册、商品管理、仓库管理、订单*管理、购物车管理、支付管理等核心模块。功能架构图体现的是一个产品的核心功能模块。

(3)应用架构

应用架构一般是指根据业务场景设计出应用的层次结构,制定好应用间的调用、交互方式,确保它们能够融合在一起并满足业务需要。比如,电商系统的应用架构可能有用户中心、权限中心、登录系统、商品中心、搜索引擎、推荐体系、订单系统、交易系统等。应用架构体现的是用什么样的微服务去支持功能的实现。

(4)技术架构

技术架构一般是指实现应用架构的关键技术栈,如Spring Cloud、ZooKeeper、RocketMQ、Redis、MySQL、Elasticsearch等中间件,以及各种核心流程的时序图、状态图等信息。

(5)物理架构

物理架构一般是指从物理视角来看IDC中的物理拓扑关系,如防火墙、Nginx、网络、应用服务器、数据库间的调用和数据流转关系。物理架构关注的是如何通过硬件配置硬件和网络来配合软件系统达到可靠性、高可用性、性能、安全性等方面的要求。

除了以上大家耳熟能详的架构分类,还有很多与架构相关的名词,如下所示。

框架(Framework):通常指的是为了实现某个业界标准或完成特定基本任务的软件组件规范,往往是基于一组类库或工具,在特定领域里根据一定的规则组合而成。

组件(Component):一组可以复用的业务功能的集合,包含一些对象及其行为。组件可以直接用作业务系统的组成部分,颗粒度一般小于模块,也是一种功能的聚合形式,比如日志组件、权限组件等。

模块(Module):基于业务数据或一组相关功能按照特定维度的逻辑划分,也可以看作各种功能按照某种分类的聚合。例如,电商系统可以从业务上划分为用户模块、商品模块、订单模块、支付模块、物流模块等。模块使一个复杂的软件变得更加容易管理和维护。

服务(Service):一组对外提供业务处理能力的功能,服务需要使用明确的接口方式(比如Web Service、RESTful等)。服务描述里应该包括约束和策略(比如参数、返回值、通信协议、数据格式等)。

平台(Platform):一般来说,是一个领域或方向上的生态系统,是很多解决方案的集大成者,提供了很多服务、接口、规范、标准、功能、工具等。

2.1.2 单体架构

在Web应用发展早期,大部分工程都是将所有的服务和功能模块打包到一个单一的应用中,如以War包的形式运行在Tomcat进程中,直接与数据库和文件系统交互。

在业务发展早期,业务功能往往比较单一,为了快速支持业务,一般一台服务器、一个应用、一个数据库,就足够支撑起一个单一的业务功能。比如电商业务,登录、下单、商品、库存都在一个单一的应用中进行管理和维护。单体架构在业务发展早期非常轻便,易于搭建开发环境,易于测试和部署。

随着业务的不断增长,用户的访问越来越多,单一应用对磁盘、CPU、内存、数据库的访问要求也越来越高。一台服务器一个应用的配置开始捉襟见肘,更改任何一个小的功能模块,整个应用都要重新进行编译和部署。同时,当有多个需求并行时,发布效率会非常低下,整体的功能耦合性非常大,一个小功能的变动可能会引起整个应用不可用。多种功能的强耦合迫使单体架构走向分布式架构。

2.1.3 分布式架构

随着业务压力增大,并发访问会成为单体架构的瓶颈,简单的解决方案就是把单体服务横向扩展为多体架构,即将1台服务器分散扩容为N台,分而治之,也就是从单体架构变为分布式架构。但是,扩容为分布式架构也有一个问题,即如何保证用户的请求均匀分散到这N台服务器?倘若用户的流量仍然集中访问其中的某台服务器,这样的分布式架构在本质上与单体架构没有任何区别。要解决这个问题就必须增加一个新模块—负载均衡,此时的架构变成了如图2-1所示。

图2-1 负载均衡架构图

负载均衡一般分为硬负载和软负载,常见的负载均衡算法有轮询、加权、地址散列、少链接等。有了负载均衡后,不会因为某一个服务的宕机而导致整体服务不可用,架构的可用性大大加强。除了应用的分布式,根据业务量的大小,数据库也会进行水平或垂直拆分,通过分布式架构赋予整体架构高负载的能力。

分布式架构2.0阶段不仅是在部署上实现分布式,应用的边界也更加清晰,从单一架构的大单一职责,拆分出一些大的应用,逐步形成多种服务之间的分布式调用。还是以电商为例,这里可能会拆分出用户服务、订单服务、商品服务、库存服务四大应用,应用之间通过接口进行交互,调用形式可能是REST或者RPC。

1.分布式架构的优点

低耦合:有了功能模块的拆分,使用接口进行通信,降低了对数据库的依赖,模块耦合性降低。

职责清晰:把应用拆成若干个子应用后,一般也是由不同团队进行维护的,这样一来,不同团队与应用的职责也就更加清晰了。

部署方便:每个应用的发布互相独立、互不干扰,发布和部署更加灵活方便。

稳定性更高:不会因为某一个应用或功能模块出现问题导致整体服务不可用,整个系统的稳定性更高。

2.分布式架构的缺点

系统间的依赖和链路增多,会增加接口开发的工作量,同时增大服务之间的维护成本,但整体上利大于弊。

2.1.4 微服务架构

分布式架构实现了应用从单进程到多进程的转变,做了粗粒度的服务拆分,微服务架构是在分布式架构的基础上对应用架构进行更细粒度的拆分。在微服务架构出现以前,SOA也曾风靡一时,本书将SOA和微服务合并到一起来讨论。还是以电商为例,用户服务可能会拆分成用户中心、权限、登录等服务,如图2-2所示。

图2-2 微服务架构图

随着Spring Cloud的普及,微服务架构逐步成为大中型企业的主流架构。我们来看下微服务架构有哪些优点。

耦合性进一步降低:模块更独立,功能拆分更加细化,使代码间的耦合以及数据库、中间件的耦合进一步降低。

自治性更强:一个微服务就是一个独立的实体,它可以独立部署、升级,微服务与微服务之间通过REST等标准接口进行通信,微服务只与其上下游有关,各个微服务之间更加独立。

技术独立:各个微服务之间可以用不同的技术栈,服务端应用可以用Java、Go、Python等多种语言实现,数据库可以是MySQL、MongoDB、HBase等不同的类型。

高可用:随着微服务增多、链路增长,异常也会被分散,一个微服务异常可以通过线程池隔离,利用熔断等技术避免故障扩散和雪崩,大大增加了整个系统的高可用性。

在微服务架构成为主流架构的同时,很多缺点也被暴露出来。

复杂度高:微服务采用RPC或REST等方式进行交互,需要考虑网络抖动、消息丢失、幂等、分布式事务等问题,代码的逻辑处理更加复杂。

粒度难定义:微服务拆成几个合适?什么样的功能模块需要独立成一个微服务?服务拆分的粒度是不好准确定义的,倘若拆得过粗,不利于服务间解耦;如果拆得过细,则会导致应用爆炸,增加系统的复杂性。

运维复杂度高:微服务的调用关系终会形成一个大网,故障的定位和排查依托于更加完善的监控报警系统等配套工具。

性能变慢:微服务一般有一个很长的调用链路,链路过长导致整体接口的性能变慢,响应时间(Response Time,RT)会变长。

2.1.5 中台架构

随着阿里巴巴“大中台、小前台”概念的提出,一线大厂纷纷建立自己的中台体系,公认比较成熟有效的是数据中台、业务中台、技术中台。中台的本质是进一步提升应用系统的复用性,当组织规模扩大,更多业务场景纷纷涌现时,各部门之间会形成一个个“系统烟囱”。在“系统烟囱”中,重复冗余的功能不断被造出来。

以阿里巴巴为例,淘宝、天猫两个事业部都需要用户管理、商品管理、订单*管理等功能,许多业务功能是重复的,如果两个事业部都重复建设,必然会造成极大的资源浪费。阿里巴巴技术栈全景图如图2-3所示。

架构重要的功能之一就是避免重复开发、提升复用能力。在这种背景下,如何避免重复造轮子,如何利用同样的能力快速支撑相似的业务需求是架构需要考虑的问题,于是中台思想应运而生。

中台架构有哪些优点呢?我总结了以下几点。

降本增效:中台的关键就是降本增效,通过复用、抽象避免不必要的重复开发,提升开发效率。

支持业务更加快速迭代:通用的能力域可以快速支持新业务线落地,比如新的业务也需要登录、订单的能力,完全不用从0到1构建一套新的体系,直接用中台的能力即可。

图2-3 阿里巴巴技术栈全景图

打造数字化运营能力:数据中台使企业的数据化价值有更宏观的体现,通过分析核心数据,能够更加地对业务进行调整和优化。

提升组织能力:中台架构的落地一定伴随着组织的调整,中台会打破“部门孤岛”,加深团队间的合作。

然而,中台在企业中落地很难,经过几年的发展,真正落地中台架构的企业很少。现在又有很多企业在质疑中台,在拆中台。并不是中台架构不好,而是企业要根据自己的业务特性和当前所处阶段去选择是否要用中台。

2.2 自如的技术发展史

自如是提供租房产品和服务的O2O互联网品牌,成立于2011年10月,目前已为近50万业主、300万自如客提供服务,管理房源超过100万间。自如的主要客群是租房用户,由于租房这个动作并不像电商、社交一样高频,因此自如的互联网属性也很少有高并发、高流量的特征。

针对流量逐步从线下转到线上、业务线从1条到10条、访客从1万到20万的业务场景,我们应该选择什么样的架构呢?本节会为读者呈现一个典型的中型互联网公司的技术架构变迁过程。

2.2.1 业务背景介绍

自如是一家连接业主、房子、租客的C2B2C公司,业务逻辑如图2-4所示。

图2-4 业务逻辑

左侧的C是业主,作为市场的供给方,业主有房源,想要更快捷、更安全、更高收益地出租。业主的痛点是找不到合适的租客、拿不到高的租金,同时,业主也没有精力打理房屋托管租期内的事宜。右侧的C是租客,作为市场的需求方,广大租客的核心痛点是找不到合适的房源、享受不到优质的租房服务。

在以自如为首的品牌公寓出现之前,房屋租赁市场有3个错配。

首先是供需错配,因为信息差异,业主找不到放心的租客,租客找不到诚信的业主。其次是装修错配,业主房子的新旧程度、装修风格差异性极大,对于租客而言,房子品质的可选范围非常有限。后是服务错配,租客租到房子后,基本上都是“自扫门前雪”,厕所、客厅、厨房等公共区域脏乱差、噪声大等问题非常突出。

自如先把业主的房源收集上来,然后进行精致的装修,为租客打造全新体验的租住和服务产品。同时,自如通过开发App、小程序、线下管家使这一匹配模式更加高效。

2.2.2 自如的技术演进过程

经过10年的发展,自如的业务规模和业务领域都大大增加。在业务规模巨增的背后,是自如业务系统的飞速演进。自如的技术发展大概经历了如下几个阶段。

2015年之前,自如以资产应用为主,管理房源信息、合同信息、客户信息,为了快速迭代业务,主语言以PHP为主,代码仓库以SVN来管理。到目前为止,老应用还存在部分未下线的功能,但是历史代码已经达到了1GB。

2015年到2018年是架构服务化的阶段,这时自如业务蓬勃发展,长租、短租、优品、家装、服务等多条业务线崛起,各个业务线开始构建独立的专属服务,此时Java开始逐步替代PHP,成为新业务线使用的语言。各个服务间开始通过RPC进行通信。这个阶段自如从单体架构迈向了分布式架构,度过爆发性增长的3年。

到了2018年7月,基础平台成立,自如开始对已有的持续交付流程进行重构,引入大量开源技术栈,如Spring Cloud、Nacos、Pinpoint、Graylog、Apollo等,使各个业务线通用的能力得到下沉,同时建设了第二机房,使自如的架构次具备了同城灾备的能力。

2019年,自如开始搭建DevOps体系,所有应用运维往SRE(Site Reliability Engineer,站点可靠性工程师)方向转型,开始学习编码,准备为Kubernetes落地储备人才。自如建设了大量的平台功能,如网关、监控报警、配置中心、消息队列平台、权限平台、用户中心等,使技术中台已具雏形。

2020年,伴随着容器、Kubernetes的广泛传播,自如对持续交付流程做了颠覆性重构,完全改变了之前的发布部署方式,对环境、分支模型都进行了重新定义,成为整个自如的技术演进过程中一个新的里程碑。

2.2.3 当前技术架构

经过了10年的技术演进,当前自如的技术架构如图2-5所示。

自如前台有多条业务线,如业主、租住、家装、客服等,每条业务线有独自的产研团队进行信息系统的构建,下方有三大中台进行支撑。

业务中台:主要整合各条业务的通用业务能力,如卡券中心、评价中心、价格中心、消息中心等至少能给2条业务线复用的能力才会抽象成中台能力。自如业务中台的建设还不是很成熟,真正可以复用的核心能力还在不断完善中。

图2-5 自如技术架构图

数据中台:数据中台基本上是能有效赋能业务的通用能力域集合,核心的能力是自如的定价系统、用户档案、楼盘档案、业主档案、推荐系统,这些核心数据奠定了前台业务快速响应、多维度聚合数据的基础。

技术中台:相比于业务中台和数据中台,技术中台是自如目前能力域多、为成熟的中台。技术中台包括两部分:一部分侧重业务能力域,如用户登录、权限系统、敏感词系统、即时通信、推送服务、搜索服务;另一部分侧重基础架构,如配置中心、注册中心、监控报警、混沌工程、网关、熔断限流、业务开关、服务治理、流量染色。技术中台是自如业务研发使用高频的能力,是工程效能核心的部分。

2.3 自如技术架构遇到的问题

自如的技术架构经过10年发展,达到目前的架构状态,并非一蹴而就,而是跟随业务的增长不断迭代和演化的。在这个迭代过程中,我们总结了许多当时遇到的问题,相信与众多中小型互联网公司有不少相似之处。本节会通过一些数据来解析自如在云原生架构落地之前遇到的3个问题—稳定性问题、研发效率问题和流程体系问题。

2.3.1 稳定性问题

2019年之前,自如某业务线的系统在30天内出现了13次线上故障,基本达到2天一次的故障频率,面对如此高频的线上问题,开发工程师疲于奔命,根本无暇迭代新功能,一线业务人员对系统也怨声载道。如何保证系统稳定性、功能可用是当时开发团队为困扰的问题。

2018年年底,基础平台团队的成立是自如系统从“易变”走向“稳定”的转折点。基础平台重新盘点了线上故障类型,抓住核心短板,发现当时迫切的问题是中间件的

治理。

首先是版本问题,各中心使用的MQ、Elasticsearch、Redis版本都极其老旧。以Elasticsearch为例,当时新版本已经到了6.x,生产集群使用的还是2.x版本,导致许多陈旧、低效的语法仍在使用,一些中间件新的特性没有用于生产。

其次是集群耦合太大,数个中心共用一个MQ、一个Redis实例,经常发生业务部门A的队列拥堵导致业务部门B的业务不可用,一个中间件瘫痪,整个公司的业务停转。经排查发现,这个情形与2.1.2小节介绍到的单体架构相似,原因是历史研发人员为了方便,直接复制中间件配置代码,导致业务应用虽然做了解耦和独立,中间件的依赖却没有分开。

后是环境问题,代码分支、环境变量、开关配置经常出现测试环境与生产环境不一致等问题;人工参与过多,很多人为问题导致线上代码污染,进而引发故障。

经过2年的治理,因中间件、人为配置导致的故障率大大降低,我们重新盘点了一下2019年的故障情况,大体分布如图2-6所示。

图2-6 故障分布图

可以发现,占比高的3个问题变成了代码错误、产品设计缺陷、数据原因,其中代码错误占比45%。稳定性问题终于不再是系统故障的首要原因。

2.3.2 研发效率问题

经济学上讲生产力有三要素—劳动对象、劳动者、劳动资料。对应在研发过程中,劳动对象是需求、项目、任务;劳动者是产品、研发、测试、前端、运维;劳动资料是原型、代码、环境、组件库、IDE(Integrated Development Environment,集成开发环境)、硬件资源等,如图2-7所示。

图2-7 研发效率图

在2019年之前,自如研发的全生命周期是没有完全数字化的,一个项目的开发周期、测试周期、上线周期、人员投入等数据是不完整的,90%的项目没有管理,开发人员根据倒排时间进行排期上线。项目的线上质量指标也基本是原始状态,研发效率低下。

2.3.3 流程体系问题

研发效率低下,在很大程度上是劳动资料的问题,CI/CD是研发人员的必备工具。2019年,自如想重做CI/CD,对研发人员进行了一次摸底调研,发现研发人员对当前流程体系的满意度平均只有5.76分。

问卷中几个比较典型的用户反馈值得与大家分享。

1.对于“代码发布列表”你有哪些痛点?

□编译错误时无法自动发送编译错误提醒邮件。

□“合并”与“发布”的操作过于晦涩、比较难理解。

□发布时效锁定为2分钟有点固化。

□准生产环境经常不稳定,希望有所改善。

□希望可以进行多分支并行发布。

2.代码发布上线过程你遇到的问题有哪些?

□上线操作烦琐、流程复杂。

□发布报错后无法查看相关的报错信息。

□发布时没有优雅关闭,会有流量损失和启动过程中的流量冲击。

□代码发布过程可视化程度不够,没有任何提示。

□功能很全,但是人工操作过多。

3.在使用操作系统平台打包编译时你遇到过哪些问题?

□脚本编写复杂,无法自动化打包、编译。

□浏览器兼容性不足,除了Win10自带浏览器外,使用其他浏览器会报错。

□自动创建发布环境时需要配置的项目过多。

□不同环境的配置可能不一致,导致出问题后的排查与定位非常困难。

□发布权限与审批流程控制不合理。

□非发布窗口发布时,无法收到审批信息。

□类似的反馈还有代码发布历史的体验、发布审批流程的问题、版本信息管理、环境配置查看问题等。

同时,问卷也统计了研发人员对新平台的期待。

1.你觉得在项目上线流程中还需要添加哪些功能?

□建议增加代码检查功能,提升代码质量。

□建议精简审批流程。

□建议增加进度可视化、发布结果状态可检测功能。

□建议增加分组灰度发布功能。

□建议增加预发布环境进行上线前验证。

□建议增加测试环境服务器监控以及恢复机制。

□建议增加日志查询、进度查询、批量发布功能。

2.你对操作系统自动化平台的愿景是怎样的,希望它是一个怎样的自动化平台?

□希望是一个高度自动化的平台,人工介入越少越好。

□希望可以自己申请添加机器配置、查看负载情况。

□希望能够更智能、更灵活、更可视、更易用、更高效可靠。

□希望在发布上线前就做代码规范自动化检测,功能更简单易用。

□希望每个环境的项目信息、IP、项目域名能够完全正确匹配。

□希望发布配置更加智能化、简易化。

经过此次调研,我们下定了重建CI/CD流程体系的决心,通过重建体系解决发布部署的效率问题。

2.4 本章小结

本章介绍了技术架构的概念,对常见的技术架构定义及分类做了区分,梳理了自如技术架构的演变过程。技术架构是随着企业的发展阶段不断演变的,自如在启动云原生之路时遇到了稳定性、研发效率、流程体系问题,从第3章开始,将介绍自如是如何应对这些问题的。

相关文章