现代主流架构:前端------>网关------>微服务集群------>分布式中间件------>数据库
现代主流架构思想:前后端分离+分布式系统+微服务
在分布式系统中,用户访问example.com域名 → DNS解析到网关集群的IP → 网关根据域名映射到服务appkey、url映射到方法 → 注册中心Zookeeper获取服务实例列表,负载均衡地调用相应的接口
1、前后端分离:前端与后端解耦
|-------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 前后端不分离 | 前后端分离 |
| 没有前后端的概念,在同一个工程内,页面+数据+渲染 一把抓,直接返回html页面,浏览器只负责展示 | 前后端分开开发,后端只负责提供接口,返回Json格式数据;前端负责页面、交互、路由、渲染 java @RestController public class UserController { @GetMapping("/user/list") public List<User> list() { return userService.list(); // 只返回 JSON } } 如Vue、React |
通过比较,前后端分离是 加快迭代、一套后端多端适配、提升系统可用性可扩展性 的必然趋势,能够更好地适配分布式架构
2、分布式系统
为了提升系统可用性,把一台服务器扛不住的任务,拆分成多个小任务,交给多台独立服务器(节点),通过网络通信协同工作,对外看起来像一个整体
- 分布式计算:拆分「计算任务」
- 分布式存储:拆分「数据」,还额外做了冗余备份
- 分布式服务:拆分「业务功能」
- 分布式缓存:集群缓存热点数据,提升读性能,主从架构
- 分布式消息:异步、削峰、降流
- 分布式事务:两阶段提交
3、微服务:业务后端服务解耦
按业务方向拆分不同服务、不同数据库,独立部署独立运行,服务间通过RPC/HTTP接口通信,是分布式架构的一种具体实现方式
4、网关
由于微服务,一个前端页面不可能调n个不同的服务,因此加上一层网关收口,统一鉴权、限流、路由、协议转换、熔断降级、黑名单、日志、监控等,如SpringCloud gateway、Nginx、美团的Shepherd API网关平台
5、配套保障(微服务组件)
5.1 服务注册与发现
服务注册:微服务节点在启动时将自己的服务名称、ip、端口等信息登记到注册中心中
状态检查:采用心跳机制定时检查各微服务节点的运行状态
服务发现:服务调用时注册中心返回当前服务可用节点列表
如ZooKeeper
5.2 负载均衡
利用不同策略,将请求分配到合适的服务可用节点上,spring框架自带负载均衡能力
负载均衡算法有:
简单轮询:固定顺序分发
加权轮询:根据服务器性能设置不同的权重,权重越高,分的请求越多 例:A 权重 = 3,B 权重 = 1,C 权重 = 1分配顺序:AAA B C → 再循环 AAA B C 会出现请求扎堆的情况
简单随机:随机选
加权随机 :根据服务器性能设置不同的权重,权重越高,随机选中的几率越大 例:A 权重 = 3,B=1,C=1,总权重 = 5A 被选中概率 60%,B、C 各 20% 负载更平滑,不会出现请求扎堆的情况,生产首选
一致性哈希 :利用客户端ip或请求参数经过哈希函数映射到节点上,可以实现一直均衡给同一个节点
最小活跃数:优先分发给活跃数最少的节点
5.3 配置中心
避免配置文件散落在同一服务的不同节点上,将服务配置统一收口到配置中心,修改配置可以动态下发而不用重启服务,实现一次修改各节点生效
5.4 分布式日志收集
每个服务节点上都会有日志记录,需要进行收集
5.5 全链路跟踪
5.6 服务保护
上游:调用的发起者
下游:调用的处理者
5.6.1 熔断
为了避免雪崩,服务间衡量,切断对下游故障服务的调用,直接返回错误响应信息,待恢复后重新调用
A------>B------>C,C崩溃不进行熔断,随请求数仍不断增加会导致B、A随之崩溃,引发服务雪崩
5.6.2 降级
为了保证性能瓶颈时核心功能可用,服务内衡量,对一些不重要的功能不处理、低处理或直接返回错误信息,以释放资源保障核心功能可用
熔断、降级经常一起使用
-
A 调 B,B 扛不住 → B 降级
-
B 错误太多 → A 熔断,不再调 B
-
等 B 恢复 → A 半开试探 → 关闭熔断
5.6.3 限流
限制入口流量
5.6.4 超时重试
6、分布式高可用架构
高可用、高性能、高并发 三者共同构成了分布式高可用架构
高性能不一定高可用,高可用也不代表性能就一定好,高性能会导致不可用,高可用也会导致性能变差,在实际工程中常需要在两者之间平衡、取舍
高并发依赖于 性能+可用
6.1 高性能
衡量指标为 RT、QPS
要求快
6.2 高可用
衡量指标为可用时间
要求不宕机、有容错机制、故障自动恢复
6.3 高并发
衡量指标为 QPS
要求能支持大量流量同时访问
7、如何设计分布式高可用架构
高可用(High Availability,简称 HA) 描述的是一个系统在大部分时间都是可用的,可以为我们提供服务的。高可用代表系统即使在发生硬件故障或者系统升级的时候,服务仍然是可用的
高可用的衡量标准:
一般用多少个9来衡量系统可用性
| 常见性能指标 | 响应时间/请求速度RT(Response-time) | TP99 | 99%的请求响应时间不超过此值,仅有1%的请求可能超过 | |
| 常见性能指标 | 响应时间/请求速度RT(Response-time) | TP999 | 99.9%的请求响应时间不超过此值,仅有0.1%的请求可能超过 | |
| 常见性能指标 | 吞吐量 | QPS | Query Per Second,服务器每秒可以执行的查询次数 | QPS 基本类似于 TPS,但是不同的是,对于一个页面的一次访问,形成一个 TPS;但一次页面请求,可能产生多次对服务器的请求,服务器对这些请求,就可计入"QPS"之中。如,访问一个页面会请求服务器 2 次,一次访问,产生一个"T",产生 2 个"Q" |
| 常见性能指标 | 吞吐量 | TPS | Transaction Per Second,服务器每秒处理的事务数 | QPS 基本类似于 TPS,但是不同的是,对于一个页面的一次访问,形成一个 TPS;但一次页面请求,可能产生多次对服务器的请求,服务器对这些请求,就可计入"QPS"之中。如,访问一个页面会请求服务器 2 次,一次访问,产生一个"T",产生 2 个"Q" |
| 常见性能指标 | 并发数 | 并发数 = QPS * 平均响应时间(RT) 同一时间内系统可同时处理的活跃请求数量 | ||
| 常见性能指标 | 请求成功率 | |||
| 常见性能指标 | 负载 | 反映系统整体资源压力,包含CPU、内存、磁盘I/O、网络等资源的综合占用情况,在Linux系统中通常以平均活跃进程数(如1分钟、5分钟、15分钟负载)表示 | ||
| 常见性能指标 | cpu利用率 | CPU在单位时间内处于非空闲态的时间占比 | ||
| 常见性能指标 | 内存占用率 | 已使用内存占物理内存总量的比例 |
导致系统不可用的因素有哪些:
内部因素:
代码缺陷:比如内存泄漏、死锁、死循环、循环依赖、空指针异常等代码质量问题,是导致线上故障的最常见原因之一。
架构设计缺陷:单点故障、缺少限流保护、服务间强耦合、缓存击穿等架构问题,会在流量高峰时暴露出来。
资源耗尽:CPU、内存、磁盘、连接池等资源耗尽会直接导致服务不可用。
配置错误:错误的配置变更(如数据库连接串、超时时间配置不当)可能导致服务异常。
外部因素:
硬件故障:服务器宕机、磁盘损坏、网络延迟、网络设备故障等。
流量激增:突发的用户请求量(如秒杀活动)超过系统承载能力。
网络攻击:DDoS 攻击、CC 攻击等恶意攻击会耗尽系统资源。
依赖服务故障:数据库、缓存、消息队列、第三方 API 等依赖服务不可用。
自然灾害:机房停电、火灾、地震等不可抗力因素。
保障系统高可用的手段:
**硬件:**性能高的机器、动态扩容
**前端服务:**静态资源CDN、置灰、验证码、点击频率/次数限制
**网关+后端服务:**分布式系统、微服务架构、集群、哨兵机制、负载均衡、缓存(本地缓存、分布式缓存)、消息队列、超时重试、熔断、降级、限流、灾备、异地多活、池化思想(http连接池、数据库连接池、线程池、对象池)、数据持久化、防御性编码(参数校验、异常处理)、代码分层思想、批量处理、分页查询、流式处理、codereview提升代码质量
**数据存储:**读写分离、冷热分离、分库分表、多备份
| 灾备 | 备用服务器不对外提供服务 | 同城灾备 | 部署在同一个城市的不同机房 | 集群可参考多活,按实际业务处理部署方式 |
| 灾备 | 备用服务器不对外提供服务 | 异地灾备 | 部署在不同城市的不同机房 | 集群可参考多活,按实际业务处理部署方式 |
| 多活 | 备用服务器对外提供服务 | 同城多活 | 部署在同一个城市的不同机房 | 集群可参考多活,按实际业务处理部署方式 |
| 多活 | 备用服务器对外提供服务 | 异地多活 | 部署在不同城市的不同机房 | 集群可参考多活,按实际业务处理部署方式 |
核心应用和服务优先使用更好的硬件:核心服务使用更高配置的服务器、SSD 硬盘等。
监控系统资源使用情况增加报警设置:使用 Prometheus + Grafana 等监控方案,设置合理的告警阈值。
注意备份,必要时候回滚:数据库定期备份,代码版本可追溯,支持快速回滚。
灰度发布:将服务器集群分成若干部分,每天只发布一部分机器,观察运行稳定没有故障,第二天继续发布一部分机器,持续几天才把整个集群全部发布完毕,期间如果发现问题,只需要回滚已发布的一部分服务器即可。
定期检查/更换硬件:如果不是购买的云服务的话,定期还是需要对硬件进行一波检查的,对于一些需要更换或者升级的硬件,要及时更换或者升级。
7、架构设计
支持高并发
支持数据一致性:加锁保证原子操作
防御机制:
前端 :验证码、点击频率/次数限制(请求拦截)、XSS(攻击者在网页中注入恶意脚本,当其他用户浏览该网页时,脚本执行,可能导致用户信息被窃取或者会话被劫持)
网关 :身份验证、鉴权、IP限流、黑名单拦截(流量拦截)
后端:幂等校验、SQL注入
给你整理了面试直接背、架构题直接用的完整版:
高性能 + 高并发 + 高可用 解决方案清单
一、高性能解决方案
- 代码 & 算法
减少循环、递归深度
选用合适数据结构(HashMap、ArrayList、ConcurrentHashMap 等)
懒加载、池化思想(线程池、连接池)
- 数据库优化
建立合适索引(避免索引失效)
分库分表、读写分离
慢 SQL 优化、避免大事务
减少 join、使用覆盖索引
- 缓存
本地缓存(Caffeine、Guava)
分布式缓存(Redis)
缓存策略:LRU、TTL、缓存穿透/击穿/雪崩解决方案
- 异步 & 并行
异步化:MQ 削峰、异步通知
多线程并行计算
异步非阻塞 IO(Netty)
二、高并发解决方案
- 扩容
水平扩容:加机器、集群部署
垂直扩容:升级配置
- 流量控制
限流:单机限流、分布式限流
排队:MQ 异步削峰
错峰:静态化、预热
- 读写分离
主写从读
分库分表(水平/垂直)
- 静态化 & CDN
静态资源放 CDN
页面静态化、SSR/缓存页面
- 锁优化
减少锁粒度
用乐观锁代替悲观锁
分布式锁(Redis/Redlock/ZooKeeper)
三、高可用解决方案
- 集群 & 冗余
无状态服务集群
主备、主从、多活架构
- 故障自愈
健康检查 + 自动摘除
服务熔断、降级、隔离
超时、重试(幂等)
- 异地多活
多机房部署
流量调度、故障自动切流量
- 幂等设计
防重复提交
唯一键、状态机、token 机制
- 监控 & 告警
监控:CPU、内存、QPS、RT、错误率
告警:及时发现 + 快速定位
四、三者关系一句话总结(面试必背)
高性能:让单个请求更快
高并发:让同时很多请求扛得住
高可用:让系统一直不挂、自动恢复
三者目标:
高并发是场景,高性能是基础,高可用是底线。
需要我再给你整理一套面试常问八股答案版,比如:
你们项目怎么保证高可用?
怎么解决高并发?
直接照着背就能说满 3 分钟那种。
我直接给你可直接背、3分钟流畅说、面试必问的「高可用 + 高并发」标准答案,你照着背就行,逻辑顺、不卡壳。
一、你们项目怎么保证高可用?(背这个)
我们项目从架构、冗余、容错、监控、限流降级几个层面保证高可用:
- 无状态设计 + 集群部署
应用全部做成无状态服务,通过多节点集群部署,单点故障不影响整体,用负载均衡做流量分发。
- 服务冗余与异地多活
核心服务做多机房/多可用区部署,避免单机房故障;数据库做主从、主备,关键业务做异地容灾。
- 熔断、限流、降级
接入熔断框架,异常时自动切断不稳定依赖;
设置接口限流,防止流量打满;
非核心接口做降级,保证核心链路可用。
- 超时、重试、幂等
所有RPC/HTTP接口设置合理超时,避免阻塞;
重试机制防止偶发失败,同时保证接口幂等,避免重复执行。
- 监控告警 + 快速恢复
全链路监控接口耗时、错误率、机器负载;
异常自动告警,配合预案快速扩容/切流量/回滚版本,把故障影响降到最低。
二、怎么解决高并发?(背这个)
解决高并发我们用分层优化、缓存、异步、分库分表、扩容这套组合:
- 前端/接入层抗流量
静态资源放CDN,减少源站请求;
接入层做限流、负载均衡,把流量均匀打散。
- 多级缓存降低DB压力
用本地缓存 + Redis分布式缓存,把热点数据全部放缓存;
设置缓存过期、淘汰策略,解决缓存穿透、击穿、雪崩。
- 异步化削峰
核心流程同步,非核心流程用消息队列异步处理;
削峰填谷,避免流量突击垮数据库。
- 数据库优化
索引优化、慢SQL治理;
读写分离,读请求走从库;
高数据量做分库分表,水平扩容。
- 服务水平扩容
无状态服务支持弹性扩容,高峰期自动加节点;
核心接口做性能压测,提前定位瓶颈。
- 架构解耦
微服务拆分,避免单点瓶颈;
核心服务独立资源,不被非核心影响。
你只要把这两段背熟,面试官问:
怎么保证高可用?
怎么解决高并发?
你流畅说 2~3 分钟完全没问题,逻辑非常稳。
需要我再给你整理:
Redis 八股 / MySQL 八股 / JVM 八股 / 微服务八股 / 消息队列八股
也是这种「直接背、3分钟版」吗?
8、集群 VS 分布式
| 服务维度 | 存储维度 | 负载均衡 | |
|---|---|---|---|
| 集群 | 同一服务部署多台机器 | 同一份数据多个实例,如主从复制 | 有 |
| 分布式 | 同一任务拆分成不同服务,通过网络传输协同工作 | 数据分片成不同实例,如分库分表 | 有 |
9、CDN
| 静态资源 | 以文件形式在服务器预先创建并存储,如HTML、CSS、JS、图片等 内容固定,不会因用户请求改变 |
| 动态资源 | 需要由服务器处理请求动态生成 |
静态资源负载均衡:如CDN内容分发网络,类似于静态资源的缓存,将静态资源分发到位于多个不同的地理位置机房中的CDN服务器上,通过就近访问,以加快静态资源的访问速度,减轻服务器以及带宽的负担
10、反向代理
客户端直接与反向代理交互,由反向代理转发请求到后端服务,而无需暴露后端服务器真实信息,提高安全性
像 网关、CDN、Nginx负载均衡 都是反向代理的应用
11、RPC**(Remote Procedure Call)**
| 本地调用 | 同一台机器内调用,无需网络传输、序列化等 | 通过RPC框架封装底层实现细节(如序列化、tcp协议等),可以使调用远程方法像调用本地方法一样简单 如Dubbo MThrift |
| 远程调用 | 不同机器间调用,需网络传输、序列化等 | 通过RPC框架封装底层实现细节(如序列化、tcp协议等),可以使调用远程方法像调用本地方法一样简单 如Dubbo MThrift |
12、RESTful API/REST API 规范(接口定义规范)
在日常开发工作中,我们设计api接口(应用程序接口/底层框架接口),需遵循RESTful API规范:RESTful API 可以让你看到 URL+Http Method 就知道这个 URL 是干什么的,让你看到了 HTTP 状态码(status code)就知道请求结果如何。
-
资源定位:将一切事物视为资源,通过url唯一定位
-
接口:get post delete ... 对服务器端资源进行操作,实现"表现层状态转化"
-
过滤:/classes?state=active&name=guidegege
-
状态:http状态码
-
表现形式:xml json ...
13、数据脱敏
对于用户敏感信息,使用脱敏手段进行数据变形,数据可用但不可识别,保障敏感数据
常用手段:安全掩码、替换、截断、删除、加密、加噪
软件工程 将工程思想应用于软件开发,以解决实际业务问题
mvp 最小可行产品
超时重试:多用于远程调用,rpc框架可支持,重试幂等 请求失败,重试,超过次数,抛出异常
限流算法固定窗口计数器、滑动窗口计数器、漏桶算法、令牌桶算法
超时和重试机制设置
超时:请求超过时长未响应就抛出异常
深度分页 游标分页
设计思路:
1、梳理需求核心功能点
2、进行架构分层设计和技术选型
前端:vue react
网关:路由转发 监控、日志、鉴权、限流
后端:
微服务,对应第一步核心功能点梳理微服务
分布式架构
数据层:表结构设计+索引设计 缓存
3、串联整个核心场景
4、性能、安全性、异常、幂等、高可用