图解系统设计: 五分钟从单体架构到微服务(上)

为了在情人节前让你的在线花店火速上线,你和团队选择了最熟悉、最快的单体架构。

项目进展神速,网站如期上线,成功抓住了第一波渴望浪漫的顾客。

然而,甜蜜的烦恼接踵而至...

随着用户暴增,尤其是在七夕、双十一这样的大促节点,网站频繁卡顿、下单失败,甚至整个应用都挂了,客服电话被打爆。

你的团队意识到,那个曾让你们引以为傲的"速度",如今正成为业务发展的巨大瓶颈。

1. 什么是单体架构?

你的在线花店的所有功能------用户管理、商品展示、购物车、订单处理------都被精心打包在一个应用里。

这就像一个肯德基全家桶。

所有美食(功能)都在一个桶里,你不用费心去想该单点些什么。

一手交钱(开发),一手拿桶(部署),直接开吃(上线),非常方便。

1.1 单体架构的优点

  • 开发简单:所有代码都在一个项目里,IDE打开就是所有的源码,没有复杂的分布式环境要操心。

  • 测试直接:想做个端到端测试?启动应用,跑就完事了,不用模拟一堆外部服务。

  • 部署方便:打个包(比如一个WAR或JAR文件),往服务器上一扔,简单直接,不用考虑依赖情况。

1.2 单体架构的缺点

  • 技术栈固化:想给订单模块换个最新的Java 21?对不起,整个应用都得跟着升级,风险极高。

  • 新人上手难:一个新人入职,面对几十万行代码的"史前巨兽",可能花一个月都理不清逻辑,改个bug心惊胆战。

  • 可靠性差:最致命的"一损俱损"。购物车模块的一个内存泄漏,就可能让整个花店网站全部瘫痪。

  • 扩展性受限:双十一"秒杀"活动流量巨大,你想只给商品模块加服务器?没门,你必须把整个应用再复制一份,造成巨大浪费。

2. 单体架构的"进化之路"

在线花店迎来了双十一大促,流量是平时的10倍!你和你的团队必须在不动大手术的前提下,让这个单体程序扛住史无前例的压力。

2.1 垂直扩容 (Vertical Scaling)

这是最简单粗暴的一招:给服务器加配置。

这就像你觉得家里的旧电脑打游戏卡,直接给它换上顶配的CPU、更大的内存和更快的SSD。

优点:立竿见影,操作简单。

  • 缺点:最顶级的服务器也扛不住无限的流量,而且你还是只有一个"篮子",鸡蛋都在里面,风险极高。

2.2 水平扩展 (Horizontal Scaling)

一台服务器扛不住,那就多来几台!

这好比一家门店忙不过来,那就索性在旁边再开几家一模一样的分店。

为了让顾客能自动去到最不拥挤的店,门口还需要一个聪明的"调度员"------负载均衡器(Load Balancer)。

负载均衡器(Load Balancer) 是一种网络设备或软件组件。

它的核心功能是将客户端请求均匀分配到多个后端服务器,避免单一服务器过载,从而提高系统的可用性、性能和扩展性。

它位于客户端与服务器集群之间,充当 "流量调度器" 的角色。

但这里有个核心前提:你的应用必须是 无状态(Stateless) 的。

「思考题」: 为什么水平扩展要求应用是无状态的?如果你的应用是有状态的(比如用户登录信息存在服务器内存里),水平扩展会遇到什么问题?

2.3 数据库优化

应用服务器通过"人海战术"撑住了,但所有压力最终都给到了数据库,它的连接数和磁盘I/O开始疯狂报警。

2.3.1. 读写分离

如果CEO(主库)实在太忙,就需要雇几个助理(读库)。

CEO只负责做决策、签合同(写数据),而助理们则负责对外沟通、查询信息(读数据)。

助理们会定期跟CEO同步最新的信息。

2.3.2 数据库分片 (Sharding)

当数据量大到单个主库都存不下时,就得考虑将数据库分片了。

数据库分片将数据表按行分割成多个分区(称为逻辑分片),每个分片存储唯一数据并分布在不同的数据库节点(称为物理分片)。

所有分片共同构成完整数据集,但彼此不共享数据或资源。因此,数据库分片也有局限性:

一个管理着全国人口的超大户籍档案室(单库),现在按身份证号的省份代码(分片键)拆分成了34个独立的省级档案室(分片库)。

查询某个省的人(特定分片查询)会变得飞快,但如果要查全国所有叫"张伟"的人(跨分片查询),那就非常麻烦了。

2.4 缓存和消息队列

  1. 缓存 (Caching)*

为服务加一个缓存,就像是把最常用的工具(热点数据,如首页商品)放在手边的工具箱(Redis缓存)里,不用每次都跑回几里地外的大仓库(数据库)去取。

推荐阅读 腾讯面试官: 如何使用 Redis? 五分钟学会

「2. 消息队列 (Message Queues)」

举个餐厅的点餐流程的例子来解释消息队列。

你在前台下单(应用接收请求)后,拿到一个叫号器就可以去旁边玩手机了。

后厨(后台服务)会按照订单顺序慢慢做,做好了你的叫号器就会响。

这完美地解决了高峰期所有顾客都堵在点餐口的尴尬。

推荐阅读 图解消息队列

  1. 总结

本文从在线花店场景出发,介绍单体架构如全家桶般的便捷与开发简单等优点,也指出其技术栈固化等缺点。

本文还解析垂直扩容等优化手段,虽能解一时之困,但技术债务等问题为微服务架构登场埋下伏笔,下期将揭秘拆分之道,记得关注。

「下期剧透:」

《图解系统设计: 五分钟从单体架构到微服务(下)》将解锁这些硬核内容:

  • 微服务架构(Microservice Architecture)

  • 优雅升级架构的绞杀者模式(Strangler Fig Pattern)

相关推荐
不知更鸟2 小时前
Django 项目设置流程
后端·python·django
黄昏恋慕黎明3 小时前
spring MVC了解
java·后端·spring·mvc
G探险者5 小时前
为什么 VARCHAR(1000) 存不了 1000 个汉字? —— 详解主流数据库“字段长度”的底层差异
数据库·后端·mysql
百锦再5 小时前
第18章 高级特征
android·java·开发语言·后端·python·rust·django
Tony Bai6 小时前
Go 在 Web3 的统治力:2025 年架构与生态综述
开发语言·后端·架构·golang·web3
程序猿20236 小时前
项目结构深度解析:理解Spring Boot项目的标准布局和约定
java·spring boot·后端
RainbowSea6 小时前
内网穿透配置和使用
java·后端
掘金码甲哥7 小时前
网关上的限流器
后端
q***06297 小时前
搭建Golang gRPC环境:protoc、protoc-gen-go 和 protoc-gen-go-grpc 工具安装教程
开发语言·后端·golang
GOTXX8 小时前
用Rust实现一个简易的rsync(远程文件同步)工具
开发语言·后端·rust