从小餐厅 到 理解 互联网架构

很多人在学习 Java 后端的时候,都会遇到这样一张技术栈地图:

Spring Boot → Nginx → Gateway → Nacos → Redis → MQ → MySQL → Elasticsearch → 分布式事务 → 微服务 → 监控 → 链路追踪......

问题是,为什么会有这么多东西?

如果只是一个个去学习,很容易变成:

  • Nginx 是负载均衡;
  • Redis 是缓存;
  • MQ 是消息队列;
  • Nacos 是注册中心;
  • Gateway 是网关;
  • Elasticsearch 是搜索引擎......

每个知识点似乎都懂,但把它们放在一起,却不知道它们为什么同时存在。

其实,互联网架构并不是一堆技术名词的堆砌。

它更像是一部由问题推动的系统演进史

  • 今天我们有 Redis,是因为数据库扛不住了。
  • 今天我们有 MQ,是因为请求洪峰把系统打爆了。
  • 今天我们有微服务,是因为单体系统越来越难以维护。
  • 今天我们有 Nacos,是因为微服务越来越多以后,服务之间不知道彼此在哪里。
  • 今天我们有链路追踪,是因为系统越来越复杂以后,出了问题不知道到底是哪一环出了问题。
    所以,理解互联网架构最重要的不是记住:

"这个组件有什么功能?"

而是建立一个更底层的问题意识:

"系统遇到了什么问题,所以才需要这个组件?"


一、互联网架构到底在解决什么问题?

在学习 Spring Boot 的时候,我们接触到的通常是一个单体应用。

如果把它比作一家小餐厅,那么整个系统可以理解成:

复制代码
顾客
 ↓
服务员 Controller
 ↓
厨师 Service
 ↓
仓库管理员 / Mapper
 ↓
数据库 MySQL
  1. 一家小餐厅只有几个人的时候,这套结构非常简单,也非常好管理。
  2. 但是,当这家餐厅突然火了起来,事情就开始变得复杂。
  3. 一天来了几千个顾客。

于是出现了第一个问题:

一家店坐不下了怎么办?

开分店。

分店越来越多以后,又出现:

顾客应该去哪一家?

于是需要统一调度。

客人突然同时涌入,又出现:

厨房做不过来了怎么办?

于是需要排队和缓冲。

订单越来越多,又出现:

一个仓库放不下所有东西怎么办?

于是需要拆分仓库。

最后店铺遍布全国:

哪家店坏了?哪个环节出了问题?

于是需要监控、日志和链路追踪。

这就是互联网架构演进的本质。

我们可以把所有问题归纳成三个最核心的目标:

问题 餐厅里的表现 互联网系统里的表现
高并发 突然来了几万名顾客 大量请求同时访问系统
高可用 一家店着火,不能让全国都关门 某台服务器故障不能导致整个系统不可用
海量数据 仓库装不下所有食材 数据量越来越大,单库性能达到瓶颈

所以可以得到一个非常重要的结论:

互联网架构,本质上就是系统面对规模增长之后,不断解决新的问题。


二、从一家小餐厅开始

最开始,我们甚至不需要复杂的互联网架构。

假设只有一家餐厅:

复制代码
                    餐厅
              ┌─────────────┐
              │   顾客      │
              └──────┬──────┘
                     ↓
              ┌─────────────┐
              │   服务员    │
              │ Controller  │
              └──────┬──────┘
                     ↓
              ┌─────────────┐
              │    厨师     │
              │   Service   │
              └──────┬──────┘
                     ↓
              ┌─────────────┐
              │    仓库     │
              │    MySQL    │
              └─────────────┘

这就是我们学习 Spring Boot 时最容易理解的三层架构。

顾客 → 服务员 → 厨师 → 仓库。

简单、清晰,而且完全够用。

但是问题来了:

如果顾客突然从 100 人变成 10 万人呢?


三、第 1 步:人多了,开分店------集群 + 负载均衡

一家店只能容纳 100 人。

现在突然来了 10000 人。

最直接的办法是什么?

开分店。

于是:

复制代码
                 顾客
                   ↓
                总服务台
                   ↓
        ┌──────────┼──────────┐
        ↓          ↓          ↓
      分店A       分店B       分店C

在互联网系统里,就是:

复制代码
                 用户
                   ↓
                 Nginx
                   ↓
        ┌──────────┼──────────┐
        ↓          ↓          ↓
     Server1    Server2    Server3

这就是集群 + 负载均衡

Nginx 可以根据负载均衡策略,把请求分发给不同服务器。

例如:

复制代码
请求1 → Server1
请求2 → Server2
请求3 → Server3
请求4 → Server1
...

这样原来一台服务器承担的压力,就被分摊到了多台服务器上。

解决的问题

单台机器性能不够怎么办?

答案:

横向扩展。

也就是:

复制代码
一台机器不够
     ↓
复制更多机器
     ↓
组成集群
     ↓
负载均衡

这也是互联网架构中非常重要的思想:

Scale Out(横向扩展)


四、第 2 步:厨房太慢,提前备菜------Redis

虽然我们已经有很多家分店,但新的问题又出现了。

假设餐厅最热门的一道菜是:

鱼香肉丝。

每天有 10000 个顾客点这道菜。

如果每一次都:

复制代码
顾客
 ↓
服务员
 ↓
厨师
 ↓
仓库
 ↓
找食材
 ↓
现做

效率非常低。

于是餐厅想出了一个办法:

热门菜提前做好,放到保温柜里。

顾客来了:

复制代码
顾客
 ↓
保温柜
 ↓
有 → 直接拿

只有保温柜没有的时候,才:

复制代码
保温柜没有
 ↓
去仓库取食材
 ↓
现做
 ↓
放回保温柜

互联网系统中的这个"保温柜",就是:

Redis

典型缓存流程:

复制代码
             请求
               ↓
             Redis
           ↙       ↘
        命中         未命中
         ↓             ↓
      直接返回       MySQL
                       ↓
                  写入 Redis
                       ↓
                     返回

Redis 的核心思想其实非常简单:

把访问频率高的数据放进速度更快的内存中。

所以 Redis 并不是为了"替代 MySQL"。

两者承担的角色不同:

复制代码
Redis
 ↓
速度快
 ↓
缓存热点数据

MySQL
 ↓
可靠持久化
 ↓
保存核心业务数据

于是我们得到第二个重要思想:

用空间和内存换时间。


五、第 3 步:客人太多,厨房爆炸------MQ 削峰填谷

现在餐厅又遇到一个非常严重的问题。

平时每秒只有 100 个订单。

厨房刚好可以处理。

但是晚上 8 点突然发生促销:

复制代码
1 秒钟
 ↓
10000 个订单

可是厨房:

复制代码
1 秒钟
 ↓
只能处理 100 个订单

怎么办?

如果让 10000 个订单直接冲进厨房:

复制代码
10000 请求
    ↓
  厨房
    ↓
 💥

系统可能直接被打爆。

于是餐厅设置了一个:

接单箱。

顾客先把订单放进接单箱。

厨房按照自己的处理能力:

复制代码
订单
 ↓
接单箱
 ↓
厨房
 ↓
一个一个处理

互联网系统里的这个"接单箱",就是:

消息队列 MQ。

例如 Kafka、RocketMQ、RabbitMQ。

整个过程:

复制代码
用户
 ↓
订单服务
 ↓
MQ
 ↓
消费者
 ↓
业务处理

MQ 的三个核心价值:

1. 异步

不需要所有事情都立即做完。

2. 削峰

把瞬间的流量洪峰变成平稳的处理流量。

复制代码
请求流量
   /\
  /  \
 /    \       → 洪峰

处理能力
────────────── → 平稳

3. 解耦

订单服务不需要知道:

"到底有多少个其他服务需要处理这个订单?"

只需要:

复制代码
订单服务
 ↓
发送消息
 ↓
MQ

其他服务自己消费:

复制代码
MQ
 ├── 积分服务
 ├── 优惠券服务
 ├── 通知服务
 └── 数据统计服务

因此:

MQ 不只是一个"异步工具",它实际上是在帮助系统隔离流量和业务之间的耦合。


六、第 4 步:一家店什么都做太乱------微服务

随着餐厅越来越大,又出现一个新的问题。

最开始:

复制代码
一家餐厅
 ├── 用户
 ├── 订单
 ├── 支付
 ├── 商品
 ├── 库存
 └── 营销

所有东西都在一个系统里。

这就是单体架构

一开始没问题。

但当代码越来越多:

复制代码
订单代码
用户代码
支付代码
商品代码
库存代码
营销代码
...

所有代码耦合在一起。

于是:

改支付功能,可能影响订单。
改订单功能,可能影响库存。
一个模块出现问题,整个系统都可能受到影响。

于是餐厅开始拆分。

复制代码
                总部
                 │
      ┌──────────┼──────────┐
      ↓          ↓          ↓
    川菜馆      粤菜馆      甜品店
      ↓          ↓          ↓
    独立经营    独立经营    独立经营

互联网系统也是一样:

复制代码
                Gateway
                   ↓
        ┌──────────┼──────────┐
        ↓          ↓          ↓
      订单服务    用户服务    支付服务

这就是:

微服务架构。

按照业务领域,把一个庞大的系统拆成多个相对独立的服务。

例如:

复制代码
订单服务
 ├── 创建订单
 ├── 查询订单
 └── 修改订单

用户服务
 ├── 用户注册
 ├── 用户登录
 └── 用户信息

支付服务
 ├── 创建支付
 ├── 支付回调
 └── 支付查询

微服务解决的核心问题之一就是:

复杂度。

它不是"为了高级而拆分",而是因为系统规模增长以后,单体系统的复杂度已经超过了人能够舒服管理的范围。


七、第 5 步:分店太多,不知道去哪------Nacos + Gateway

微服务拆出来以后,新的问题马上出现:

订单服务怎么找到用户服务?

假设用户服务现在有:

复制代码
User Service 1
192.168.1.10:8080

User Service 2
192.168.1.11:8080

User Service 3
192.168.1.12:8080

订单服务不可能把这些 IP 地址全部写死。

因为:

  • 服务可能扩容;
  • 服务可能缩容;
  • IP 可能变化;
  • 某个实例可能挂掉。
    于是需要一个"总部通讯录"。

这就是:

注册中心。

在 Spring Cloud Alibaba 体系中经常使用:

Nacos

服务启动的时候:

复制代码
User Service
     ↓
"我来了,这是我的地址"
     ↓
Nacos

订单服务需要调用用户服务:

复制代码
Order Service
     ↓
"User Service 在哪里?"
     ↓
Nacos
     ↓
返回可用实例
     ↓
RPC
     ↓
User Service

所以 Nacos 解决的是:

服务在哪里?

而 Gateway 解决的是:

用户的请求应该去哪里?

整个结构可以理解为:

复制代码
                   用户
                    ↓
                 Gateway
                    ↓
             ┌──────┴──────┐
             ↓             ↓
          订单服务       用户服务
             ↑             ↑
             └──── Nacos ──┘

Gateway 是用户进入微服务系统的统一入口。

它可以统一处理:

  • 路由
  • JWT 鉴权
  • 限流
  • 跨域
  • 请求日志
    而 Nacos 更像是微服务内部的"通讯录"。

八、第 6 步:仓库扛不住了------MySQL 主从、读写分离、分库分表

系统继续增长。

这次轮到数据库出现瓶颈。

最开始:

复制代码
所有请求
   ↓
 MySQL

但是数据越来越多,请求越来越多。

于是可以先做:

主从复制。

复制代码
              MySQL 主库
             /          \
            ↓            ↓
         从库1          从库2

主库主要负责写:

复制代码
INSERT
UPDATE
DELETE

从库负责读:

复制代码
SELECT

于是:

复制代码
写请求
 ↓
主库

读请求
 ↓
从库

这就是:

读写分离。

但是,如果数据规模继续增长呢?

一个数据库真的可能放不下所有数据。

于是继续拆:

复制代码
                 数据库
                    ↓
          ┌─────────┴─────────┐
          ↓                   ↓
       用户库                订单库
          ↓                   ↓
      用户表                订单表
                              ↓
                     订单表1 / 订单表2 / ...

这就是

分库分表。

它背后的思想依然是:

单个节点扛不住,就把压力分散到多个节点。

你会发现:

复制代码
服务器扛不住
 ↓
集群

数据库读太多
 ↓
读写分离

数据库数据太多
 ↓
分库分表

其实都是同一个思想:

分而治之。


九、第 7 步:系统越来越复杂------Elasticsearch

数据库解决了数据存储问题,但又出现了新的需求:

搜索。

例如电商网站搜索:

复制代码
"黑色 男士 运动鞋 42码"

用户希望:

  • 全文搜索;
  • 模糊搜索;
  • 分词;
  • 相关性排序;
  • 高亮;
  • 聚合分析。

这并不是传统 MySQL 最擅长的事情。

于是可以引入:

Elasticsearch。

整个系统形成:

复制代码
                 MySQL
                   │
              核心业务数据
                   │
                   ↓
            Elasticsearch
                   │
               搜索索引

这里需要建立一个重要认识:

Elasticsearch 通常不是为了替代 MySQL,而是补充 MySQL 的搜索能力。

MySQL 更关注:

数据可靠地存下来。

Elasticsearch 更关注:

数据快速地搜索出来。

这就是典型的:

不同组件解决不同问题。


十、最后一个问题:系统出问题了怎么办?

到这里,我们的系统已经变得非常复杂:

复制代码
用户
 ↓
Nginx
 ↓
Gateway
 ↓
订单服务
 ↓
用户服务
 ↓
Redis
 ↓
MySQL
 ↓
MQ
 ↓
支付服务
 ↓
...

这时候,如果用户突然告诉你:

"我的订单怎么一直加载?"

你打开代码可能会发现:

每个服务看起来都没问题。

那么到底哪里出了问题?

于是我们需要三个东西:

1. 日志

日志回答:

系统刚才发生了什么?

例如:

复制代码
Order Service
16:20:01 请求进入

User Service
16:20:02 查询用户

MySQL
16:20:10 SQL 执行完成

2. 监控

监控回答:

系统现在怎么样?

例如:

复制代码
CPU:90%
内存:85%
QPS:12000
响应时间:3.5s
错误率:8%

当指标超过阈值:

复制代码
监控
 ↓
告警
 ↓
开发人员

3. 链路追踪

链路追踪回答:

一次请求到底经过了哪些服务?每一步花了多长时间?

例如

复制代码
用户请求
   ↓ 10ms
Gateway
   ↓ 20ms
Order Service
   ↓ 50ms
User Service
   ↓ 3000ms
MySQL

于是你终于发现:

原来不是订单服务慢,而是用户服务查询数据库用了 3 秒。

这就是:

SkyWalking / Zipkin 等链路追踪系统的价值。


十一、于是,一张完整的互联网架构图出现了

经过前面的不断演进,我们最终得到的系统大致变成:

复制代码
                         用户
                    浏览器 / APP
                         │
                         ↓
                        CDN
                  图片 / 视频缓存
                         │
                         ↓
                        DNS
                     域名解析
                         │
                         ↓
                       Nginx
              负载均衡 / 限流 / 反向代理
                         │
                         ↓
                      Gateway
                 路由 / 鉴权 / 限流
                         │
                         ↓
                  ┌─────────────┐
                  │    Nacos    │
                  │ 服务注册发现 │
                  │  配置管理    │
                  └──────┬──────┘
                         │
             ┌───────────┼───────────┐
             ↓           ↓           ↓
          订单服务      用户服务      支付服务
             ↕           ↕           ↕
             └─────── RPC 调用 ──────┘
             │           │           │
       ┌─────┴─────┐     │     ┌─────┴─────┐
       ↓           ↓     ↓     ↓           ↓
      Redis       MQ   MySQL        Elasticsearch
       │           │     │               │
       ↓           ↓     ↓               ↓
      缓存       异步    持久化          搜索
                 削峰
                         ↓
               ┌─────────────────┐
               │   可观测性体系   │
               ├─────────────────┤
               │ 日志             │
               │ 监控告警         │
               │ 链路追踪         │
               └─────────────────┘
相关推荐
m0_640602444 小时前
2026 年餐饮收银系统前后端技术实现——核心架构与原理详解
后端·微服务·云原生·架构
江畔柳前堤4 小时前
AgentScope 设计与原理全解:从消息原语到分布式智能体工程底座
大数据·人工智能·分布式·目标检测·机器学习·语言模型·架构
两万五千个小时4 小时前
DeepSeek Harness 上下文压缩:长对话管理
人工智能·程序员·架构
一拳不是超人5 小时前
一个 AI 改出的 bug,另一个 AI 五天就打穿了 Snowflake:Copilot Autofix 事件给 coding agent 的警醒
架构·github
zhuyingxiao6 小时前
ChatGPT、Claude Code、Codex 能直接控制泵阀吗?AI Agent 液路监测的正确架构
人工智能·chatgpt·架构
童谣16 小时前
越华碳能:V3.0 多模态物联网碳核算微服务平台架构设计与落地实践
物联网·微服务·架构
拿本唠嗑AI研究6 小时前
现代前端架构爬虫指南:从静态页面到 React/Vue 单页应用
前端·爬虫·架构
ZJU_统一阿萨姆6 小时前
【推理优化进阶】Hopper_Blackwell 微架构:从指令、流水线到真实性能上限
开发语言·人工智能·语言模型·架构·开源
独孤九剑打醒他6 小时前
【原创开源】双层Master‑Worker软硬协同调度架构:从根源解决分布式数据一致性难题
前端·嵌入式硬件·架构·前端框架·硬件工程