浅谈互联网架构演变

IT知识
267
0
0
2024-03-03
标签   架构设计

前言

可以将某个项目或产品的架构体系按照如下方式分层:

  • 业务层面:项目业务体系
  • 技术层面:
  • 数据架构:数据持久层策略
  • 应用架构:应用层的实现方式
  • 部署架构:部署方式,自动化持续集成等策略

针对每一层也随着时间的变化而变化。

业务架构

单体模式

早期的互联网产品多为单体系统,特点是以业务为导向,往往形成业务团队各自为战,在新业务线出现时需求大量增长。

这里补充部分业务模式的概念:

  • B2B:企业与企业之间的供销模式
  • B2C:企业面向消费者的交易模式
  • C2C:消费者与消费者之间的交易模式
  • O2O:线上与线下业务混合模式

随着公司的业务发展,业务层面会不断向 B2B、B2C 等扩张。

这就引出了单体架构的局限性:

  • 功能冗余:B2B、B2C 会有相同的业务重叠,导致多个单体系统功能近似或冗余
  • 数据不互通:多个跨域业务下,对于同一用户群体的数据不能互相沟通

功能冗余会带来成本的浪费(开发运维成本),数据的不互通带来业务壁垒,跨域业务间数据难以打通。

中台战略

为了解决单体架构带来的问题,阿里在 2015 年提出了中台战略,这是一种企业架构,而不是单纯的技术层面。

这里再细化一下单体系统相较中台战略的局限性:

  • 技术和业务架构上:
  • 单体系统功能重复,而抽调出中台可以大幅减少冗余代码的开发
  • 业务集成度高,开发和运维成本高,而中台模式下,基础业务也下沉到技术部门,甚至通过技术反推业务发展
  • 对于多变的需求,中台战略可以将业务细化分层,上层业务针对产品快速迭代,下层业务持续沉淀,为上层业务封装底层接口
  • 组织架构上:
  • 单体架构下,往往是每个项目就是一个团队,团队随项目扩张不断增大或重组复用,利用率低
  • 中台模式下,可以将上层业务和下层业务的团队分离,并将各个中台单独立项,提高利用率

除此之外,中台战略在业务扩展方面具备先天性优势:

image-20231226002455240

去中台化

虽然中台战略看起来已经足够优秀,但目前又呈现出了去中台化的趋势。

在大市场不断跟风的情况下,中台战略暴露出来的问题也越来越多:

  • 中台战略需要过硬的技术支撑,大部分的公司没有完善的中台构建方案
  • 公司业务差距太大,中台复用度不高,中台带来的生产价值远远小于中台的开发和运维成本
  • 高度依赖中台的业务体系之间,耦合度严重提高

甚至中台战略的鼻祖——阿里的中台战略发展也没有达到预期,在反垄断的大背景下,减少大而集中的部门,拆分不同业务线独立发展,降低耦合。

数据架构

单体模式

早期的单体项目业务简单,一般只需要单体数据库(多为 MySQL),但随着业务体量不断增大,这一时期往往引发追逐商业大型数据库(Oracle)。

单体数据库架构多见于早期的 JavaWeb 和 SSH 项目:

  • 通过 JDBC 直连,简单直接
  • 数据库用 MySQL,或大型商业 DB
  • 单库上的机器 IO 及 cpu 性能很快达到上限

主从读写

淘宝以前就是 MySQL,后来更换为了 Oracle,直到 2007 年又从 Oracle 回迁为了 MySQL,这个历程中实现了主从库的部署与读写分离。

这一架构的特点如下:

  • 应用层连接多个数据库,数据库之间形成主从关系,主库为写,从库上读,分离读写压力
  • 数据库集群策略,一主多从或双主单写,提升数据层的容灾和高可用能力

但是这一架构也避免不了带来新的问题:

  • 数据不一致:主库到从库之间数据要进行同步,不同的数据同步策略会产生对应的问题
  • 单库瓶颈:业务越来越多,表数量越来越多,甚至可能会出现单个库几百张表的现象
  • 数据局限:依然无法解决单表大数据的问题

分库分表

为了解决单库的数据局限性问题,又引入了分库分表的解决方案:

  • 水平分库:将一个库的数据拆分到多个库中
  • 水平分表:将一张表的数据拆分到多个表中
  • 垂直分表:将一张表的多个字段拆分到多个表中、

对于垂直分库,一般是分布式架构下,按照业务将数据库进行拆分,保存不同的表和数据。

对于分库分表也会不可避免地带来新的问题:

  • 分库:不同的数据库,所以无法使用数据库事务,而分布式事务的效果并不理想,多采用幂等和最终一致性方案
  • 分表:拆了再聚合是一对矛盾,例如按下单时间维度的分表,需要按用户排序统计变得异常困难

高速缓存

数据库往往是系统的瓶颈,即便通过垂直分表可以将冷热数据进行分离,但从本质上仍然无法提升 IO 瓶颈。

因此,又提出根据数据的冷热划分,热点数据如类目、商品基础信息放在告诉缓存中,再其他数据延迟加载方案:

  • redis:性能可靠,纯内存,自带分片,集群,哨兵,支持持久化,几乎成为当前的标准方案
  • memcache:性能可靠,纯内存,客户端需要自己实现,无持久化
  • ehcache:非分布式,简单,易维护,可用性一般

引入缓存,在实际生产中也会遇到问题:

  • 缓存击穿:单一 Key 失效,遇到大量请求压垮数据库
  • 缓存雪崩:大量 Key 失效,遇到大量请求压垮数据库
  • 缓存穿透:不存在的 Key,遇到大量请求压垮数据库
  • 数据不一致问题:数据库更新,缓存也要更新保持一致性

数据多样化

数据库和缓存只是一种基本的存储手段,除了这些,其他各种形式的存储结构和存储需求也相继涌现:

  • NoSQL:非关系型数据库,如:Redis,MongoDB,Neo4j
  • 分布式文件存储:存储不同文件,如:Hdfs,Fastdfs,CephFs,MinIO
  • 搜索引擎:解决海量数据搜索问题,如:Lucene,Elasticsearch

针对这些需求,带来的架构层面的挑战也是巨大的:

  • 数据可靠:面对高并发等场景,要保证数据服务的高可用
  • 数据运维:多数据服务下,对应系统的容灾措施也相应复杂,维护成本水涨船高
  • 数据安全:要求能够针对不同数据的访问权限进行隔离

应用架构

单机调优

互联网早期项目模式多为 MVC 模式:

  • Model: 模型代表一个存取数据的对象或 JAVA POJO。它也可以带有逻辑,在数据变化时更新控制器。
  • View: 视图代表模型包含的数据的可视化。
  • Controller:控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。它使视图与模型分离开。

这一时期的项目单机特点是:

  • 每个项目独立为一个 MVC 结构,部署在应用服务器上(tomcat、jboss、websphere,weblogic)
  • 需求迭代快,项目体量越来越大,一个 war 包动辄几百兆
  • 技术方案不成熟,有大量历史问题遗留(屎山)

由于各种各样的单机性能瓶颈问题,这一时期的项目往往都推崇 JVM 单节点调优。

动静分离

为了解决单机瓶颈,又提出应用服务集群的动静分离的方案:

  • 静态响应:tomcat 对静态文件响应一般,提取静态文件,直接由nginx响应
  • 动态代理:后端 api 通过代理转发给 tomcat 应用机器(集群)

在这一时期的项目特点是:

  • 项目结构大幅调整,由原来的一体化 MVC 转换为后端api + 前端形式
  • 前后端的分工变得更明确,互相并行开发,独立部署

这一时期大量的 Apache + tomcat 已初具前后端分离架构的雏形,直到后来被 nginx 几乎一统江山

SOA

单纯的动静分离只解决了自己服务的项目结构,跨项目接口调用时,必须经过 rest 请求,不利于服务之间的交互。

因此又提出了面向服务的架构——SOA:

  • SOA 是一种建设企业T生态系统的架构指导思想,SOA的关注点是服务
  • 服务是最基本的业务功能单元,通过将业务系统服务化,可以将不同模块解耦
  • 各种异构系统间可以轻松实现服务调用、消息交换和资源共享

image-20201210141921958

对于 SOA 的落地目前有两种主要表现形式:

  • 分布式服务化:采用 SOA 去中心化的落地方式,典型的落地的技术栈:Dubbo + Zookeeper,服务之间依靠 RPC 框架互相调用
  • 集中式管理:偏重于以 ESB 作为基础支撑技术,以整合集成为核心,将各个新旧系统的业务能力逐渐在 ESB 容器上聚合集成

这一阶段的项目特点鲜明,技术难度大:

  • 界限把控:服务的粒度、拆分和公共服务提炼需要架构师的全局把控,设计不好容易引发混乱
  • 部署升级:服务数量增多,人工部署变的不现实,必须借助自动化运维
  • 服务可用性:抽调的微服务因需要被多个上层业务共享,对系统整体的容灾能力要求提高
  • 熔断和限流:做好服务熔断和限流,提防服务单点瓶颈造成整个系统瘫痪

微服务

当分布式架构成为时代主流后,一种基于 SOA 的升级版——微服务架构也横空出世,它和分布式架构的主要区别如下:

  • 微服务架的拆分颗粒度更细、更小,中台化得以实现
  • 服务的治理强,容易构建成熟的容灾和高可用集群体系
  • 微服务的技术栈更全、更成体系,技术栈钱内部的技术组件也是基于微服务的思想来做的

image-20201210142042606

同时,这种架构也有需要平衡的地方:

  • 服务拆分:拆分粒度并非越小越好,太小会带来部署维护等一系列成本的上升
  • 接口约束:系统增多,各个服务接口的规范化日益重要,要求有统一的服务接口规范,推动企业消息总线的建设
  • 权限管理:服务之间的接口要做好鉴权,借助 oauth2 等手段,实现服务之间的权限认证

部署架构

单机部署

最早的单机项目部署方案大多为:

  • 采用 web 包部署与发布,db 等资源同台机器连接,例如早期采用 tomcat + war 的形式,后来则是 java -Jar,
  • 单机性能达到瓶颈后,只能通过提升机器配置的方式来提升性能,成本较高

这种单机部署架构在业务发展的初始阶段尚可支撑,但随着访问量的上升,这种部署架构无法达到业务的性能要求。

角色划分

如果项目再大一些,可以把数据库、缓存、消息等中间件剥离出去,单独机器来部署:

  • 多台机器:tomcat 与 mysql 各自独占机器资源
  • 针对性扩容:tomcat 应用机更注重 cpu 的运算和内存,mysql 更注重 IO 与磁盘性能,针对各自情况扩容

在这种方案下,可以将 dba 分离出来单独维护数据库服务器,但同时也带来了数据安全方面的问题。

应用集群

应用集群部署带来的最大优势就是——负载均衡,此时期常见技术栈为:

  • apache:早期负载均衡方案,性能一般
  • nginx:七层代理,性能强悍,配置简洁
  • haproxy:性能同样可靠,可做7层或4层代理。
  • lvs:四层代理,性能最强,linux 集成,但配置麻烦
  • f5:四层代理,硬件负载

image-20201221111636625

这一方案的特点是:

  • session 会话:集群环境下,用户登陆需要分布式 session 做支撑
  • 分布式协同:分布式环境下对资源的加锁要超出线程锁的范畴,上升为分布式锁
  • 调度问题:调度程序不能多台部署,容易跑重复,除非使用分布式调度,如 elastic-job
  • 机器状态管理:多台应用机的状态检测与替换需要做到及时性,一般 niginx 层做故障转移
  • 服务升级:滚动升级成为可能,灰度发布

对于更大的部署,往往采用多层代理

  • 动静态均有多个 nginx 负载,入口统一交给 lvs 负载
  • 但是 lvs 依然是单一节点,即使 keepalived 做到高可用,流量仍然需要在唯一入口进入

image-20201221110843244

异地访问

为了提升系统的物理容灾能力,解决机器部署的扩容问题,又产生了多机房部署策略:

  • 将相同的系统部署多份,分散到异地多个机房,或者电信、移动等多个网络中
  • 不同地点,不同网络接入的用户,有了不同的访问入口和选择

此时,对于异地访问也有对应的访问策略:

  • DNS 轮询:通过 DNS 的策略轮询调用,可以实现机房层面的扩容
  • CDN:就近原则,使用户获得就近的机房访问相关资源

多机房部署成本较高,一般只有规模较大,具有强硬的市场支撑的公司才会使用,同等条件下远不如上云来的实惠

云平台

近年来,针对中台化的建设及微服务数量的飙升,在快速部署和资源弹性伸缩的需求下,容器化与云平台开始大火。

image-20200402095344710

云平台部署下,常见的技术方案为:

  • 虚拟化:vm 方案,Openstack,Vmware,VirtualBox
  • 容器化:docker
  • 持续集成:Jenkins,CI/CD
  • 编排:swarm,k8s,k3s
  • 云化:私有云到企业云

云平台部署与传统部署方式最大的优势在于资源的灵活扩容和回收,针对活动期间弹性扩容,非活动期间回收闲置资源。

但同时云平台部署需要运维层面的高度支撑,门槛较高,其次,对应风险上,云瘫痪也会造成不可计量的损失,要对系统风险进行合理预估

总结

纵观今年互联网架构的演变,不难看出没有任何体系是一成不变的,架构体系往往随着业务需求不管革新。

因此,架构要服务于业务,而不能脱离业务存在,任何架构的设计都要贴合实际的业务场景。

技术上不断收敛,因为引入新技术必然会带来新问题,尽量追求原生,降低项目的开发和维护成本。

对于架构的扩展性要适度取舍,要考虑到互联网产品的周期,不能过分保留。