软件开发进阶技能之分布式与高并发(一)

简介: 教程来源 https://tmywi.cn/ 本文系统讲解分布式与高并发核心技能:从CAP/BASE理论、负载均衡、多级缓存(穿透/击穿/雪崩应对)、消息队列、分布式事务/锁,到微服务治理与限流熔断,涵盖原理、实战代码与真实场景,助你构建高可用、可扩展的现代系统。

当你开发的系统从几百个用户增长到几百万、几千万,单台服务器已经无法承载巨大的流量和数据量。这时候,系统架构必须从单体应用演进为分布式系统,并从低并发走向高并发。分布式与高并发是软件开发进阶技能中最具挑战性也最有价值的部分,它融合了网络通信、数据一致性、容错、性能优化、架构设计等众多领域的知识。

什么是分布式系统? 分布式系统是由多个通过网络通信的计算机节点组成的系统,对外表现为一个统一的整体。它的目标是:可扩展性(Scalability)、高可用性(Availability)、容错性(Fault Tolerance)。

什么是高并发? 高并发是指在极短的时间内,系统需要处理大量请求(例如双十一的秒杀、春运抢票)。高并发系统需要充分利用多核、多机并行处理,并通过多种技术手段(缓存、异步、限流、降级)保证系统稳定。

本文将从基础理论(CAP、BASE)、负载均衡、缓存设计、消息队列、分布式事务、分布式锁、服务治理与微服务、限流熔断、一致性哈希、分布式 ID 等方面,结合大量代码示例和真实场景,深入讲解分布式与高并发的核心技能。

预备知识:你已经熟悉后端开发(如 Java/Go/Python),了解数据库和网络基础,写过 Web 服务。

第一部分:分布式系统基础理论 —— CAP 与 BASE

1.1 CAP 定理
CAP 定理指出,一个分布式系统最多只能同时满足以下三个特性中的两个:

一致性(Consistency):所有节点在同一时刻看到相同的数据。即写操作完成后,读操作必须返回最新的写入值。

可用性(Availability):每个请求在有限时间内都能收到非错误的响应(但不保证是最新数据)。

分区容错性(Partition Tolerance):当网络分区(节点之间通信中断)发生时,系统依然能继续运行。

在实际分布式系统中,网络分区是不可避免的(交换机故障、光缆断裂),所以 P 必须满足。因此,系统需要在 CP(一致+分区容忍)和 AP(可用+分区容忍)之间做出权衡。

CP 系统:保证强一致性,但可能在网络分区时拒绝服务(例如 ZooKeeper、HBase、MongoDB 在某些配置下)。典型实现:多数派写入(Paxos/Raft)。

AP 系统:保证可用性,但可能读到不一致的数据(最终一致性,例如 Cassandra、DynamoDB、CouchDB)。典型实现:冲突解决(Last Write Wins, Merkle Tree 反熵)。

1.2 BASE 理论 —— 对 CAP 中一致性的弱化
BASE 是 Basically Available(基本可用)、Soft state(软状态) 和 Eventually consistent(最终一致性) 的缩写。它是对大型分布式系统实践经验的总结,强调用最终一致性换取高可用。

基本可用:系统出现故障时,允许部分功能降级(如响应时间变长、返回旧缓存数据)。

软状态:允许系统中存在中间状态,该状态不影响系统整体可用性(例如数据复制延迟)。

最终一致性:经过一段时间的异步修复,数据最终会达到一致。

最终一致性的变种:

因果一致性:有因果关系的操作需按顺序被所有节点看到。

会话一致性:同一个会话中读操作保证读到自己的写操作。

单调读一致性:一旦读到新值,不会回滚到旧值。

很多实际系统(如 DNS、Gossip 协议)都基于最终一致性设计。

第二部分:高并发架构概述 —— 纵向扩展与横向扩展

要支撑高并发,架构上要么向上(纵向扩展),换更强的服务器(CPU 更多、内存更大),要么向外(横向扩展),增加更多普通服务器。纵向扩展有物理上限且成本非线性增长,因此现代高并发系统主要依赖横向扩展。

横向扩展会带来以下挑战:

负载如何均匀分发到多台机器? → 负载均衡

用户会话(session)如何共享? → 分布式会话

数据如何分布到多个数据库? → 分库分表 / 分片

频繁读取的数据如何减轻数据库压力? → 多级缓存

大量写请求如何削峰填谷? → 消息队列

服务之间如何通信和治理? → 微服务 + 服务注册发现

下面将逐一深入讲解。

第三部分:负载均衡 —— 流量的交通警察

负载均衡器(Load Balancer)是分布式系统的门面,它接收所有客户端请求,然后按照一定策略分发到后端服务器。

3.1 负载均衡层次
DNS 负载均衡:最简单的全局负载,将域名解析到不同 IP。缺点:缓存生效慢,无法感知服务健康状态。

硬件负载均衡(F5、A10):性能极高,但昂贵,通常用于大型入口。

软件负载均衡(Nginx、HAProxy、LVS):开源、灵活,是主流选择。

客户端负载均衡(Ribbon、Spring Cloud LoadBalancer):内嵌在应用内,通过服务注册中心获取可用列表,自行选择节点。

3.2 常见负载均衡算法
image.png
3.3 Nginx 配置示例

upstream backend {
    # 加权轮询
    server 192.168.1.10 weight=3;
    server 192.168.1.11 weight=1;
    # 最少连接
    least_conn;
    # IP Hash
    ip_hash;
    # 健康检查(需 nginx plus 或第三方模块)
    server 192.168.1.12 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

3.4 分布式会话问题与解决方案
当负载均衡使用轮询时,用户请求可能落在不同服务器,导致 session 丢失。解决方案:

粘性会话(Sticky Session):通过 IP Hash 或 cookie 绑定,但某台机器宕机时会话仍会丢失。

会话复制(Session Replication):在 Tomcat 等容器中同步 session 到所有节点,网络开销大,不推荐。

集中存储(推荐):将 session 存入 Redis 或数据库,所有服务器共享。Spring Session + Redis 是典型方案。

Spring Session + Redis 示例:

@Configuration
@EnableRedisHttpSession
public class SessionConfig {
    @Bean
    public LettuceConnectionFactory connectionFactory() {
        return new LettuceConnectionFactory("redis-host", 6379);
    }
}

第四部分:缓存 —— 性能加速的利器

缓存是扛高并发最有效的手段之一。正确使用缓存可以让读请求在内存中直接返回,避免穿透到数据库。

4.1 缓存层次
客户端缓存(浏览器缓存、App 本地缓存)

CDN 缓存:分发静态资源,减轻源站压力。

反向代理缓存(Nginx、Varnish):缓存动态页面片段。

应用本地缓存(Guava Cache、Caffeine):进程内缓存,速度极快,但无法跨服务共享。

分布式缓存(Redis、Memcached):独立于应用,多节点共享。

4.2 缓存模式
4.2.1 Cache Aside(旁路缓存)
这是最常用的模式:

读:先读缓存,命中则返回;未命中则读数据库,写回缓存。

写:先更新数据库,然后删除缓存(或更新缓存,但删除更简单,避免并发脏数据)。

public User getUser(Long id) {
    // 读缓存
    User user = redis.get("user:" + id);
    if (user != null) return user;
    // 读数据库
    user = db.query("SELECT * FROM user WHERE id = ?", id);
    if (user != null) {
        redis.setex("user:" + id, 3600, user);
    }
    return user;
}

public void updateUser(User user) {
    db.update("UPDATE user SET name=? WHERE id=?", user.getName(), user.getId());
    redis.del("user:" + user.getId());  // 删除缓存
}

为什么是删除而不是更新? 因为更新缓存可能有并发问题:两个写线程,一个更新了数据库,另一个用旧值覆盖了缓存。删除后,下次读会重新加载新值。

4.2.2 Read/Write Through(读写穿透)
应用只和缓存交互,缓存作为代理负责读写数据库。适合对应用透明的场景,但缓存层实现复杂。

4.2.3 Write Behind Caching(写回)
先写缓存,异步批量写数据库。写入性能极高,但可能丢失数据(缓存宕机)。适用对数据丢失不敏感的日志、计数等。

4.3 缓存三大痛点:穿透、击穿、雪崩
image.png
布隆过滤器示例(Guava 版)

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;

BloomFilter<Long> bloom = BloomFilter.create(Funnels.longFunnel(), 1000000, 0.01);
// 初始化时将所有存在的 id 加入
for (Long id : allUserIds) {
    bloom.put(id);
}

// 查询前先判断
if (!bloom.mightContain(userId)) {
    return null; // 一定不存在,直接返回
}
// 否则走缓存/DB

互斥锁防止击穿(Redis 分布式锁)

public User getWithMutex(Long id) {
    String key = "user:" + id;
    User user = redis.get(key);
    if (user != null) return user;

    // 尝试获取锁
    String lockKey = "lock:user:" + id;
    Boolean locked = redis.setnx(lockKey, "1", 10, TimeUnit.SECONDS);
    if (locked) {
        try {
            user = db.query(...);
            redis.setex(key, 3600, user);
        } finally {
            redis.del(lockKey);
        }
    } else {
        // 等待一小段时间后重试
        Thread.sleep(50);
        return getWithMutex(id);
    }
    return user;
}

4.4 缓存一致性(双写一致性)
当数据库和缓存同时写时,保证一致性是难点。除了 Cache Aside 模式(先更新 DB 再删缓存),还可以:

订阅数据库变更日志(Canal):解析 MySQL binlog,异步刷新缓存。

延时双删:先删缓存,再更新 DB,然后延时(如 1 秒)再删一次,解决并发读导致的脏数据问题。
来源:
https://yyvgt.cn/

相关文章
|
17天前
|
人工智能 自然语言处理 文字识别
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
Qwen3.7-Max是阿里云百炼面向智能体时代推出的新一代旗舰模型,对标GPT-5.5、Claude Opus 4.7等闭源旗舰。该模型支持百万级token上下文窗口,具备顶级推理能力、多模态搜索与视觉理解增强、流式输出低延迟响应等核心优势,覆盖编程、办公、长周期自主执行等复杂场景。同时支持OpenAI接口兼容,便于系统快速迁移。用户可通过Token Plan团队或节省计划等订阅方式灵活调用,适合企业级高要求场景使用。
6283 30
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
|
2天前
|
数据采集 人工智能 前端开发
让 Coding Agent 从黑盒到透明:阿里云 Agent 观测审计数据采集实践
AI Agent 规模化落地带来执行黑盒、行为难追溯、成本难度量三大难题。阿里云基于 OTel 标准,面向 Coding Agent、个人通用助理和框架型 Agent,推出 LoongSuite Pilot、插件及探针等无侵入采集方案,让 Agent 实现可看见、可分析、可审计、可治理。
582 135
|
12天前
|
存储 定位技术 数据库
CodeGraph 如何让 Claude Code减少 7 成工具调用?
CodeGraph 为 Coding Agent 提供本地代码知识图谱,把函数、类、调用链和框架路由提前整理成“项目地图”,减少盲目搜索和文件读取。它不是新 Agent,而是上下文基础设施,让 Agent 更快找到正确代码路径,平均减少 7 成工具调用。
1238 3
|
9天前
|
人工智能 安全 定位技术
CodeGraph深度解析 让Claude Code工具调用直降七成的核心原理与实操教程
如今以Claude Code为代表的AI编程智能体已经成为开发者日常编码、项目重构、漏洞修复的必备工具。但在长期使用过程中,几乎所有开发者都会遇到同一个明显痛点:AI虽然具备强大的代码生成与分析能力,却常常陷入盲目探索的循环中。
1088 1
|
19天前
|
人工智能 自然语言处理 供应链
|
9天前
|
人工智能 弹性计算 安全
阿里云618活动时间、活动入口、优惠活动详细解读
2026年阿里云618创新加速季已全面开启,作为年度力度最大的云产品促销活动,本次大促覆盖轻量应用服务器、ECS云服务器、GPU云服务器、数据库、AI算力、安全服务、CDN等全品类产品,推出5亿元算力补贴、新用户限时秒杀、普惠满减、企业专享、免费试用、云大使返佣等多重福利,个人开发者、中小企业、AI团队均可享受专属低价。本文将系统梳理2026年阿里云618活动的完整时间节点、官方参与入口、各类优惠细则、使用规则、热门产品推荐及实操代码,帮助用户精准参与、高效省钱,以最低成本完成上云部署。
871 5
|
8天前
|
人工智能 自然语言处理 安全
Vibe Coding 实战:别盲目跟风,先分清 vibe coding 适合什么场景
本文系统总结vibe coding实战经验:明确其适用场景(原型、小工具、标准化模块),剖析5步落地流程(场景判定→结构化提示词→目录初始化→分模块生成→自动化校验),指出四大常见误区,并推荐适配工具Trae。强调“场景匹配+规则前置”是提效关键,避免盲目套用。
723 1