互联网架构思维讲解
故事点,有个小公司做了一个小网站,用户极少,访问量低,这时候怎么简单,怎么来,这时候通常就是自己搞了一台服务器装了应用程序加一个数据库。
LAMP一套开源代码,如:Apache+Liunx+Java+Mysql,这就是单机架构。
接着,这家公司经过推广,业务慢慢增长,用户慢慢增加,这时候数据库和应用开始互相抢资源。这时候怎么办,很简单,那就加多台服务器,把应用和数据库分开,应用服务器,专门处理请求,数据库服务器专门存数据做io操作,可用性也提高了。
但是,这家公司又升级业务了,用户暴涨,单台应用处理器处理不过来,数据库也扛不住大量查询。
于是高并发来了,单台服务器,就算配置拉满,1秒最多也就处理100个请求,那如果来500个请求怎么办,500/100=5,那就再加4台服务器,装同样的代码,取名叫集群,流量怎么分配到每台服务器呢,于是有了一个中间层,它能将请求均匀地分配到每台服务器,这就是负载均衡,扛不住就加机器,这就是水平扩展,一台服务器挂了,屏蔽流量,其他来顶上,保证系统不崩溃,这就叫高可用。应用抗住了,但是大量请求穿透到数据库,数据库成了新的瓶颈,于是研究数据库原理,发现内存缓存区读取比从磁盘读取要快1000倍,能不能都去内存缓存区读呢,不行,它太小了,那怎么办,那我把内存缓存区弄出来,把热点数据都放进去,让用户直接去读取内存缓存区,这就是缓存,你设计了三层缓存,浏览器缓存,应用服务器本地缓存、分布式缓存(redis),用户每次请求先来浏览器缓存找,找不到就去本地缓存找,再到分布式缓存,最后才到数据库,这时候绝大多数请求,在缓存层就被拦住了,由于缓存放在内存中,查询速度从毫秒微变成秒级别,数据库压力暴跌,就算数据库挂了,缓存还能顶着,提高了可用性,数据库缓存区就存原始数据,三层缓存区是什么快、什么常用就存什么,不只是存数据库里的东西,还存页面、接口结果、静态资源计算结果。
缓存解决了热点读,但是写请求和非热点读还是会访问数据库,数据库有个特点,写比读慢得多,写会锁行锁表,并发一高就排队,那能不能拆开分工呢,于是你搞了一个主库和从库,主库负责写,从库负责读,通过数据同步,保证主从数据库一致,这就是读写分离,现实互联网中,读多写少,所以一般都是一主多从,(one master more slave) ,数据库读写互相阻塞的问题也解决了,系统跑了几年,数据量上来了,订单表,日志表越来越大,单库单表有点撑不住,于是,就开始拆分数据库,也叫拆库拆表,按业务拆分,拆分为用户库、订单库、商品库,互不干扰,也叫垂直分库,一张大表,拆成多张小表,比如按哈希拆成多张表,分成多表,分散压力,配合数据库中间件,对应用透明,也不用改大量代码,这就是分片分表,也叫水平分表,现在数据库从单点,变成了分布式。
存储和并发能力能无限扩展。
再后面,这家公司成功上市,业务遍布全国,有上海、北京、广州、深圳等这些地方,系统应用也遍布全国,有人访问快,有人访问慢,应用服务器直接暴露在公网,安全性极低,容易被攻击,于是你在全国铺设了很多节点,静态资源提前放到离用户最近的节点,就像小区楼下的快递站,用户不用每次都跑到中心机房区访问,而是通过域名解析,获取用户最近的节点ip去取数据,速度起飞,这就CDN;
另外,你还在用户和应用之间放了一个小玩意,公网请求先经过它,再转发给内网应用服务器,这就是反向代理,它隐藏真实应用服务器,防止被攻击,还能做流量清洗,权限校验,一举多得。
后来,随着互联网场景的复杂化,传统数据库遇到模糊查询,全文搜索,多维统计,力不从心,如电商搜商品、新闻热搜,用like查询慢死了,于是你看到两个小玩意,一个利用倒排索引,让搜索秒级响应,这就是搜索引擎,如,ElasticSearch。一个专门存非结构化半结构化的数据,支持高并发易扩展,这就是NoSql数据库,终于,系统只能简单增删改查,变成了支持复杂检索与分析。
再后面,生意越来越大,以两台应用集群的主机来说,这家公司从一个小电商,变成了集用户、商品、订单一体的大平台,所有的功能代码全集成在一个大应用里,这就是常说的巨石应用,麻烦也就来了,改一行用户相关的代码,要全量发布整个应用,多个开发改功能,冲突不断,想给订单服务加机器抗流量,只能整个应用一起扩容,浪费资源,怎么办,拆呗,按业务边界,把服务拆成单独的系统,比如用户相关的拆成用户系统,订单相关的拆成订单系统,商品相关的拆成商品系统,每个系统单独部署,单独发布,单独扩容,互不影响,这就是分布式架构,那拆了,怎么互相调用获取对方的数据,于是你引入跨服务调用,让跨服务调用像调本地代码一样简单,这就是RPC远程调用,但是服务越来越多,相互调用的链路也越来越复杂,快速找到目标去调用成了难题,于是,你找了一个总管,管理所有服务地址,新增的服务都需要来它这里注册,谁要调用谁,直接来总管这里寻找,这就是服务注册与发现中心(Nacos),还有一个问题,服务相互调用相互等待,一个服务卡住了,整条链路都会堵死,流量高的时候,容易雪崩,能不能让服务之间不相互等待,于是你发现了一个超大容量的智能收件箱,服务之间不用死死等着对方回复,把消息扔进去,谁要,谁到时自己来拿取就行了,这就是消息队列,服务之间彻底解耦,互不拖累,就算某个服务彻底挂了,消息也不会丢,等它恢复再慢慢处理,遇到流量突增,还能先把请求存起来,按系统能力慢慢消化,这就是消息队列的削峰填谷。
分布式架构用了几年,又有新的问题,拆是拆了,但是拆得不够细,比如拿用户系统来说,里面又装登录,又装用户信息,又装会员,又装地址,还是不够清爽,加上不同团队用的技术不一样,有的用Java,有的用go,捆在一个系统里,根本没办法搞,会员模块大促期间要扩容,结果只能把整个用户系统一起扩容,一起加机器,钱和资源白白浪费,继续拆,按照一个服务只干一件事的原则,把系统拆得更细小,登录做成单独服务,会员、支付做成单独服务,每个小服务只干一件事,他们能独立开发,独立扩容,想用什么技术栈,就用什么,互不干扰,这就是微服务架构,这可太灵活了,大促期间,订单和支付服务直接10倍机器抗流量,其他不忙的服务不用动,资源也不浪费,哪个服务出bug,就影响这个小功能,绝对不会拖垮整个网站,几十个团队各管各的服务,互不打扰,开发效率拉满,但是有利也有坑,服务多,调用像蜘蛛网一样,出问题,排查难度拉升,于是你加了一个全链路追踪,一眼就能定位慢服务,流量太大,怕倍冲垮,怕连锁崩盘,于是你加上限流熔断降级,自动保护系统,服务太多不好管,于是你做了服务治理、统一监控、日志权限,全部安排的明明白白。
这些配齐,就是大厂级别的微服务架构体系,抗住千万级亿级的流量不在话下,微服务好用,但是运维起来要命,服务越拆越细,从原来几个服务变成了几百个,部署运维直接噩梦,每个服务上线部署都要配置环境、调参数、装依赖,稍微不一样,就出现我的电脑能跑,服务器跑不起来的玄学bug,大促前要紧急扩容几百台机器,一台台配环境根本赶不上,大促结束还要一台台清理,效率极低,怎么办,你突然灵机一动,能不能把服务和它所需要的环境参数依赖打包进一个黑盒子,放到哪台服务器都能直接跑,这就是镜像安装,把每个服务的环境、配置、依赖全部打包成一个镜像,然后放到哪台服务器都能直接跑,实现一次打包到处运行,这就是docker容器,但是,几百上千个容器要怎么管理呢,于是你又找到了一个管家,它能安排容器自愈和扩缩容,这就是Kubernetes,也叫k8s,容量高了自动加容器,容量低了自动缩容器,容器挂了自动重启,全程不用人管,但是,到这里,你发现就算这样,你还是得自己买服务器,租机房,为了大促准备一堆机器,平时闲着,浪费钱,于是你直接把系统搬到云平台,云平台就像一个无限大的资源池,要多少CPU、内存、带宽随时申请随时用,用完释放,按需付费,底层机房可以当做透明,这个架构就升级了,就叫云原生。
系统架构演进对照表
| 架构 | 解决核心问题 | 备注 |
|---|---|---|
| 单机架构 | 业务从零搭建,快速落地最小可用系统 | 适用于初创项目、低并发场景 |
| 应用与数据分离 | 解决应用、数据库资源抢夺,提升系统稳定性 | 基础架构拆分第一步,实现计算与存储解耦 |
| 应用集群+负载均衡 | 应对高并发访问,解决单节点性能瓶颈与单点故障 | 常用方案:Nginx/HAProxy 四层/七层负载均衡 |
| 多级缓存 | 提升高频查询性能,大幅降低数据库访问压力 | 典型层级:本地缓存 → 分布式缓存 → 数据库 |
| 数据库读写分离 | 解决数据库读写阻塞,提升高并发下数据吞吐能力 | 主库写入、从库读取,配套主从同步机制 |
| 分库分表+分布式数据库 | 解决海量数据存储瓶颈,突破单库单表性能上限 | 常用方案:Sharding-JDBC、TiDB 等分布式数据库 |
| CDN+反向代理 | 提升静态资源访问速度,增强系统安全防护能力 | 反向代理可实现请求转发、限流、WAF 防护等 |
| 搜索引擎+NoSQL | 解决复杂全文检索、高并发非结构化数据查询场景 | 常用方案:Elasticsearch、MongoDB、Redis 等 |
| 业务拆分与分布式 | 解决业务膨胀、代码维护困难、系统耦合度高问题 | 按业务域拆分系统,实现分布式部署与调用 |
| 微服务架构 | 解决大型项目团队协作、独立开发部署、灰度发布需求 | 配套服务注册、配置中心、熔断降级、网关等组件 |
| 容器化与云平台 | 解决运维复杂度高、资源成本高、自动化部署效率低问题 | 核心方案:Docker 容器化、K8s 编排、云原生平台部署 |

浙公网安备 33010602011771号