服务端高并发分布式结构演进之路 概述在进行技术学习过程中由于大部分读者没有经历过一些中大型系统的实际经验导致无法从全局理解一些概念。因此本文以一个“电子商务”应用为例介绍从一百个到千万级并发情况下服务端的架构演进过程。同时列举出每个演进阶段会遇到的相关技术让大家对架构的演进有一个整体的认知方便大家在后续深入学习时有一定的整体视野。架构演进关于后端架构的演进最初往往是从一个单机架构来去进行的单机架构单机架构就是只有一台服务器这个服务器负责所有的工作初期我们需要利用我们精干的技术团队快速将业务系统投入市场进行检验并且可以迅速响应变化要求。但好在前期用户访问量很少没有对我们的性能、安全等提出很高的要求而且系统架构简单无需专业的运维团队所以选择单机架构是合适的。下图假设是一个电商网站最少要包含 --- 应用服务HTTP和存储服务器MySQL用户在浏览器中输入 www.XXX.com 首先经过 DNS 服务将域名解析成 IP 地址 10.102.41.1随后浏览器访问该 IP 对应的应用服务。对于单机程序能不能将数据库服务器去掉光一个应用服务器又负责业务又负责数据存储在单机架构中通常所有服务包括应用服务和数据库服务都运行在同一台服务器上。这意味着应用逻辑、数据存储以及用户请求的处理都在同一台机器上完成。这种架构的特点是简单、部署成本低适合用户量较少、业务逻辑相对简单的初期项目。绝大部分的公司的产品可都是单机架构哦因为硬件发展太快了性能好如果业务进一步增长用户量和数据量都水涨船高一台主机难以应付的额时候就需要引入更多的主机更多的硬件资源这时候也就自然而然的过渡到了分布式系统了一台主机的硬件主要指的是CPU内存硬盘网络......资源是有上限的服务器每次收到一个请求都是需要消耗这些资源来处理请求。同一时刻请求多了此时就可能导致某一个硬件资源不够用了进而导致服务器处理请求的时间变长甚至处理出错我们该如何处理呢开源 --- 简单粗暴增加更多的硬件资源。一台主机扩展到极限了只能引入多台主机了不是说买一个新的机器买来就可以解决问题了也是需要软件上做出对应的调整和适配的一旦引入多台主机了咱们的系统就可以称为是“分布式系统”了--- 引入分布式是万不得已的节流 --- 软件上优化各凭本事需要通过性能测试找到是哪一个环节出现了性能瓶颈再去对症下药解决是相对比较困难的。相关软件Web 服务器软件Tomcat、Netty、Nginx、Apache 等数据库软件MySQL、Oracle、PostgreSQL、SQL Server 等 我们目前的训练大多针对该阶段的业务系统包括本科毕业设计的系统实现。应用服务集群架构我们的系统受到了用户的欢迎并且出现了爆款单台应用服务器已经无法满足需求了。我们的单机应用服务器首先遇到了瓶颈摆在我们技术团队面前的有两种方案大家针对方案的优劣展开了热烈的讨论垂直扩展 / 纵向扩展Scale Up通过购买性能更优、价格更高的应用服务器来应对更多的流量。这种方案的优势在于完全不需要对系统软件做任何的调整但劣势也很明显硬件性能和价格的增长关系是非线性的意味着选择性能 2 倍的硬件可能需要花费超过 4 倍的价格其次硬件性能提升是有明显上限的。应用服务器里面可能会包含很多的业务逻辑可能会吃 CPU 和内存数据库服务器需要更到的硬盘空间更快的数据访问速度可以配置更大硬盘的服务器甚至还可以上 SSD 硬盘这样就可以最大层度解决硬件不足的问题也即是上面提到的问题。水平扩展 / 横向扩展Scale Out通过调整软件架构增加应用层硬件将用户流量分担到不同的应用层服务器上来提升系统的承载能力。这种方案的优势在于成本相对较低并且提升的上限空间也很大。但劣势是带给系统更多的复杂性需要技术团队有更丰富的经验。经过团队的学习、调研和讨论最终选择了水平扩展的方案来解决该问题但这需要引入一个新的组件 ——负载均衡为了解决用户流量向哪台应用服务器分发的问题需要一个专门的系统组件做流量分发。实际中负载均衡不仅仅指的是工作在应用层的甚至可能是其他的网络层之中。同时流量调度算法也有很多种这里简单介绍几种较为常见的Round-Robin 轮询算法即非常公平地将请求依次分给不同的应用服务器。Weight-Round-Robin 加权轮询算法为不同的服务器比如性能不同赋予不同的权重weight能者多劳。一致性哈希散列算法通过计算用户的特征值比如 IP 地址得到哈希值根据哈希结果做分发优点是确保来自相同用户的请求总是被分给指定的服务器。也就是我们平时遇到的专项客服经理服务。应用服务器可能会吃 CPU 和内存如果把 CPU 或者内存吃没了此时应用服务器就顶不住了这时候引入更多的应用服务器就可以有效解决该问题用户的请求就可以先去访问负载均衡器然后由负载均衡器对这个请求进行分发负载均衡器对于请求量的承担能力要远超过应用服务器的。负载均衡器是领导分配工作。应用服务器是组员执行任务。那是否可能会出现请求量大到负载均衡器也扛不住了呢这是有可能的我们可以引入更多的负载均衡器~~~引入多个机房相关软件负载均衡软件Nginx、HAProxy、LVS、F5 等可是就一个存储服务器所有的应用服务器都要访问数据库就会有很大的压力而且相比之下数据库对于压力是更加敏感的增加应用服务器确实能够处理更高的请求量但是随之存储服务器要承担的请求量也就更多了我们一样的可以使用开源和节流来解决问题读写分离/主从分离架构读写分离/主从分离架构是一种用于缓解数据库压力的解决方案。在之前的架构中用户请求通过负载均衡分发到不同的应用服务器后虽然可以并行处理但所有请求最终都会从数据库读写数据导致数据库成为系统承载能力的瓶颈。数据库服务的特殊性在于数据一致性要求很高例如银行账户金额如果数据分散到多台服务器数据一致性将无法保障。为了解决这个问题采用主从分离架构保留一个主数据库用于处理所有写入请求其他从数据库用于读取请求。从库的数据全部来自主库通过数据同步保持与主库一致。由于大部分系统中读请求远多于写请求将读请求分散到从库可以有效减轻数据库压力。虽然主库到从库的数据同步存在一定的时间成本但可以通过数据库中间件如 MyCat、TDDL、Amoeba、Cobar 等来实现读写请求的分离处理从而优化整个系统的性能。本来的服务器即是写又是读现在分成两个了一个主(master)用来写数据和做同步一个从(slave) 用来读数据因为读的频率是比较高的我们就可以设计一个主服务器然后多个从服务器也就是一主多从然后这些从服务器通过负载均衡的方式让应用服务器进行访问引入缓存 --- 冷热分离架构数据库有一个天然的问题响应速度是很慢的因为在磁盘上存放我们可以将数据进行冷热区分热点数据放到缓存中缓存的访问速度往往比数据库要快很多随着访问量的增加业务中出现了读取频率远高于其他数据的热点数据以及相对的冷数据。为了提升热点数据的读取响应时间引入了缓存机制包括本地缓存如 Memcached和分布式缓存如 Redis缓存热门商品信息或热门商品的 HTML 页面等。通过缓存可以拦截绝大多数请求从而大大降低数据库的压力。同时需要解决缓存一致性、缓存穿透/击穿、缓存雪崩以及热点数据集中失效等问题。引入缓存是可以提高效率但是修改就不是一件容易事修改了就需要进行主从数据库的数据同步还要考虑主的改对了从的缓存有没有对等等一系列问题这些问题等我们后续Redis的学习会进一步展开我们引入分布式系统不光要去应对更多的请求量(并发量)同时也要能应对更大的数据量是否会出现一台服务器已经存不下数据了呢当然会存在的一台主句存不下我们就需要多台主机来解决 --- 进行分库分表垂直分布本来一个数据库服务器这个数据库服务器上有多个数据库指的是逻辑上的数据集合create database 库名 创建的东西现在就可以引入多个数据库服务器每一个数据库服务器存储一个或一部分数据库--- 分库如果某一个表特别大大到一台主机都存不下也可以针对表进行拆分--- 分表为了进一步应对业务数据量的增大可以采用垂直分库的方式将数据按照业务逻辑进行拆分。例如评论数据可以根据商品 ID 进行 hash 路由到对应的表中存储支付记录可以根据小时创建表并进一步根据用户 ID 或记录编号拆分为小表。通过将数据分散到多个小表中可以实现数据库的水平扩展从而提高性能。这种架构显著增加了数据库运维的难度对 DBA 的要求较高。此时的数据库已经可以称为分布式数据库但其内部组件是通过不同的工具实现的例如分库分表管理和请求分发由 Mycat 实现SQL 解析由单机数据库实现读写分离可能由网关和消息队列实现查询结果汇总可能由数据库接口层实现等。这种架构是 MPP大规模并行处理架构的一种实现。相关软件包括 Memcached、Redis 等缓存软件以及 Greenplum、TiDB、Postgresql XC、HAWQ 等分布式数据库软件商业产品如南大通用的 GBase、睿帆科技的雪球 DB、华为的 LibrA 等。业务拆分 --- 微服务架构之前的应用服务器一个服务器程序里面做了很多的业务。这就可能会导致这一个服务器的代码变得越来越复杂为了方便于代码的维护就可以把这样的一个复杂的服务器拆分成更多的功能更单一但是更小的服务器这就是微服务--- 服务器的种类和数量就增加了随着人员增加和业务发展业务被拆分给不同的开发团队进行维护每个团队独立实现自己的微服务。团队之间通过隔离数据直接访问利用 Gateway、消息总线等技术实现相互调用和关联。同时可以将用户管理、安全管理、数据采集等通用业务提取为公共服务。引入微服务解决了人的问题付出的代价1. 系统性能下降拆出来更多的服务多个功能之间要更依赖网络通信网络通通信的速度可能还比访问硬盘还慢想要保证性能不下降太多只能引入更多的机器更多的硬件资源 --- 充钱2. 系统复杂程度提高可用性收到影响服务器更多了问题出现的概率就会更大了这就需要一系列的手段来保证系统的可用性更丰富的报警系统以及配套的运维人员尾声在架构上形成了多个子系统集群例如用户子系统集群、商品子系统集群、交易子系统集群等每个集群都包含应用集群、缓存和存储集群。公共服务包括安全中心、监控预警中心等。电商系统的架构演变是一个逐步优化的过程。以上所述的架构演变顺序只是针对某个侧面的单独改进。在实际场景中可能同时面临多个问题或者瓶颈可能出现在其他方面。例如在政府类场景中业务可能很丰富但并发量不大此时高并发不是重点而解决复杂需求的方案更为关键。对于单次实施且性能指标明确的系统架构设计应满足系统性能指标要求并预留扩展接口以备不时之需。对于持续发展的系统如电商平台应设计到满足下一阶段用户量和性能指标要求的程度并根据业务增长不断迭代升级架构以支持更高的并发和更丰富的业务。“大数据”是一个统称涵盖了海量数据采集、清洗转换、存储、分析和服务等场景的解决方案。每个场景都有多种技术可供选择例如数据采集有 Flume、Sqoop、Kettle 等数据存储有分布式文件系统 HDFS、FastDFSNoSQL 数据库 HBase、MongoDB 等数据分析有 Spark 技术栈、机器学习算法等。大数据架构根据业务需求整合各种组件提供分布式存储、计算、多维分析、数据仓库和机器学习算法等能力。而服务端架构更多关注应用组织层面底层能力通常由大数据架构提供。在正式引入架构演进之前为避免读者对架构中的概念完全不了解导致低效沟通优先对其中一些比较重要的概念做前置介绍基本概念应用Application/ 系统System一个应用就是一个/组服务器程序也可以叫做系统为了完成一整套服务的一个程序或者一组相互配合的程序群。生活例子类比为了完成一项任务而搭建的由一个人或者一群相互配合的人组成的团队。模块Module/ 组件Component一个应用里面有很多的功能每个独立的功能就可以称为是一个 模块/组件当应用较复杂时为了分离职责将其中具有清晰职责的、内聚性强的部分抽象出概念便于理解。生活例子类比军队中为了进行某据点的攻克将人员分为突击小组、爆破小组、掩护小组、通信小组等。分布式Distributed物理上的多个主机分布式就算是要引入多个服务器来协同配合完成一系列的工作全部放在一起就是分布式系统系统中的多个模块被部署于不同服务器之上即可以将该系统称为分布式系统。如 Web 服务器与数据库分别工作在不同的服务器上或者多台 Web 服务器被分别部署在不同服务器上。生活例子类比为了更好地满足现实需要一个在同一个办公场地的工作小组被分散到多个城市的不同工作场地中进行远程配合工作完成目标。跨主机之间的模块之间的通信基本要借助网络支撑完成。集群Cluster逻辑上的多个主机被部署于多台服务器上的、为了实现特定目标的一个/组特定的组件整个整体被称为集群。比如多个 MySQL 工作在不同服务器上共同提供数据库服务目标可以被称为一组数据库集群。生活例子类比为了解决军队攻克防守坚固的大城市的作战目标指挥部将大批炮兵部队集中起来形成一个炮兵打击集群。分布式 vs 集群通常不用太严格区分两者的细微概念细究的话分布式强调的是物理形态即工作在不同服务器上并且通过网络通信配合完成任务而集群更在意逻辑形态即是否为了完成特定服务目标。主Master/ 从Slave是分布式系统中的一种比较典型的结构多个服务器节点其中一个是主另外的是从从节点的数据要从主节点这里同步过来集群中通常有一个程序需要承担更多的职责被称为主其他承担附属职责的被称为从。比如 MySQL 集群中只有一台服务器上的数据库允许进行数据的写入增/删/改其他数据库的数据修改全部要从这台数据库同步而来则把那台数据库称为主库其他数据库称为从库。中间件Middleware和业务无关的服务 --- 功能更通用的服务数据库缓存消息队列...一类提供不同应用程序用于相互通信的软件即处于不同技术、工具和数据库之间的桥梁。生活例子类比一家饭店开始时会每天去市场挑选买菜但随着饭店业务量变大成立一个采购部由采购部专职于采买业务称为厨房和菜市场之间的桥梁。评价指标Metric可用性Availability系统整体可用的时间/总的时间考察单位时间段内系统可以正常提供服务的概率/期望。例如年化系统可用性 系统正常提供服务时长 / 一年总时长。这里暗含着一个指标即如何评价系统提供是否正常我们就不深入了。平时我们常说的 4 个 9 即系统可以提供 99.99% 的可用性5 个 9 是 99.999% 的可用性以此类推。我们平时只是用高可用High Availability, HA这个非量化目标简要表达我们系统的追求。响应时长Response Time, RT指用户完成输入到系统给出用户反应的时长。例如点外卖业务的响应时长 拿到外卖的时刻 - 完成点单的时刻。通常我们需要衡量的是最长响应时长、平均响应时长和中位数响应时长。这个指标原则上是越小越好但很多情况下由于实现的限制需要根据实际情况具体判断。吞吐Throughputvs 并发Concurrent吞吐考察单位时间段内系统可以成功处理的请求的数量。并发指系统同一时刻支持的请求最高量。例如一条两车道高速公路一分钟可以通过 20 辆车则并发是 2一分钟的吞吐量是 20。实践中并发量往往无法直接获取很多时候都是用极短的时间段比如 1 秒的吞吐量做代替。我们平时用高并发High Concurrent这个非量化目标简要表达系统的追求。分布式系统小结单机架构采用应用与数据库同机部署的简单架构模式。这种架构适用于初期业务量较小、访问量低的场景具有部署和维护简单的优点。例如个人博客、小型企业官网等系统常采用此架构。但随着业务发展这种架构容易导致资源竞争性能瓶颈明显。应用与数据库分离将应用服务器和数据库服务器分别部署在不同主机上实现资源隔离。这种分离可以解决CPU、内存和IO资源的竞争问题提高系统整体性能。例如电商网站将商品展示应用和用户数据库分离部署后可以有效避免数据库查询影响前端响应速度。负载均衡通过负载均衡器如Nginx、HAProxy等将请求均匀分发到多台应用服务器提升系统吞吐量。常见的负载均衡策略包括轮询、加权轮询、最少连接等。例如在秒杀活动中负载均衡可以将大量并发请求分摊到多个服务器节点处理。读写分离架构采用主从数据库结构主库负责写入操作确保数据一致性多个从库负责读取请求分担查询压力主库通过binlog复制等数据同步机制保持从库数据一致性 这种架构特别适合读多写少的业务场景如新闻网站、社交平台等。缓存优化引入Redis、Memcached等缓存机制实现冷热数据分离显著提升系统响应能力符合二八原则。热点数据如商品详情、用户信息等可缓存在内存中降低数据库访问压力。例如电商平台将热门商品信息缓存后查询响应时间可从数百毫秒降至毫秒级。数据分片通过分库分表策略如水平分片、垂直分片扩展数据库容量有效缓解存储压力。分片策略可以根据业务特点选择如按用户ID哈希分片、按时间范围分片等。大型社交平台通常采用分片策略来处理海量用户数据。微服务化将单体应用拆分为多个功能单一、轻量化的服务集群每个服务独立开发、部署和扩展。例如电商系统可拆分为用户服务、商品服务、订单服务等。这种架构通过服务注册中心如Nacos和服务网关如Spring Cloud Gateway实现服务治理大幅提升系统可维护性和扩展性。