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

简介: 教程来源 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/

相关文章
|
19小时前
|
人工智能 Rust 监控
这 3 个开源小工具,帮你让 Coding Agent 少吃点 Token
今天我们就来分享 3 个有用的开源项目,专门帮你的 Coding Agent 整理“上下文”:让它少翻无关代码,少吞冗长日志,把 token 留给更关键的信息。
这 3 个开源小工具,帮你让 Coding Agent 少吃点 Token
|
1天前
|
机器学习/深度学习 人工智能 自然语言处理
可计算元认知文本分析:跨领域语义漂移的多层解释框架与实证研究
背景:跨领域语义漂移(semantic drift)是自然语言处理与知识融合中的核心障碍。前期研究已构建了三种量化手段——Jaccard(结构漂移)、Word2Vec(语义漂移)与 SBERT(句子级漂移),但仅提供“漂移多少”的数值,缺乏可解释性与因果解释。 结论:四层框架实现了从“是否漂移” → “漂移多少” → “为何漂移” → “如何漂移”的完整链路,为跨领域知识对话提供了量化 解释 因果 句子四维支撑。该框架可推广至其他多学科语料,助力AI Human 协同的可解释知识融合。 关键词:语义漂移;可解释性;大语言模型(LLM);因果推断;SBERT;可计算元认知
|
20小时前
|
消息中间件 NoSQL 中间件
软件开发进阶技能之分布式与高并发(二)
教程来源 https://oplhc.cn/ 消息队列(MQ)是分布式系统核心中间件,以异步通信实现服务解耦、流量削峰与最终一致性。支持可靠投递、幂等消费与死信处理,广泛应用于秒杀、日志收集等高并发场景。
|
20小时前
|
缓存 NoSQL 数据库
软件开发进阶技能之数据库进阶(六)
教程来源 https://bncne.cn/ 本节深入探讨NoSQL数据库与混合持久化架构:涵盖Redis高级用法(数据结构、RDB/AOF持久化、Sentinel/Cluster)、MongoDB索引与聚合,以及MySQL+Redis+Elasticsearch+Cassandra的电商混合存储实践,并通过游戏排行榜案例对比三种实现方案,强调性能、一致性与成本的平衡。
|
9天前
|
JavaScript 安全 Java
软件开发进阶技能之编程语言深度运用(一)
教程来源 http://xbivx.cn/ 本文聚焦编程进阶核心——从“会用”到“用好”的跃迁。通过深度解析类型系统(泛型、类型推断、ADT/模式匹配)、内存、并发、函数式等共性机制,结合Java/Python/TS/Go实战示例,助开发者写出更安全、高效、优雅的代码。
88 0
|
19小时前
|
存储 人工智能 安全
阿里云服务器经济型e实例2核2G、2核4G、4核8G等配置解析:实例性能、适用场景与活动价格参考
阿里云经济型e实例是面向个人开发者、学生及小微企业的入门级云服务器,2核2G3M带宽仅99元/年,热门配置享3.9折起优惠。产品采用Intel Xeon处理器,支持ESSD Entry云盘,具备企业级SLA与安全标准,国内32个可用区广泛售卖。适用于AI智能体轻载部署、个人学习测试、中小型网站搭建、开发测试环境及轻量级企业应用等场景。
|
20小时前
|
数据采集 监控 前端开发
如何自动追踪 eBay 售价?Python 爬虫实战解析
如何自动追踪 eBay 售价?Python 爬虫实战解析
|
8天前
|
存储 人工智能 算法
告别无效刷屏!TrendRadar:最快30秒部署的开源热点助手,让你只看真正关心的新闻
TrendRadar 是一个轻量级、易部署的热点新闻聚合与推送工具。它能够从知乎、抖音、B站、微博、百度、华尔街见闻等11个主流平台抓取热搜榜单,然后根据你设定的关键词进行智能筛选,最终将你最关心的内容推送到手机或邮箱。
181 13
 告别无效刷屏!TrendRadar:最快30秒部署的开源热点助手,让你只看真正关心的新闻
|
19小时前
|
存储 监控 数据可视化
RFID赋予档案智能数字身份
RFID档案智能化管理通过电子标签为档案赋予唯一“数字身份证”,结合软硬件与物联网,实现入库、借阅、盘点、防盗等全生命周期自动化管控,解决传统管理“查找慢、易丢失、难盘点”等痛点,提升效率90%,准确率达99.9%。(238字)
|
19小时前
|
人工智能 自然语言处理 安全
阿里云JVS Claw是什么?使用JVS龙虾AI能做哪些事?JVS Claw收费价格指南
阿里云JVS Claw是面向个人、开发者及轻量团队的AI智能执行助理,将AI从“对话助手”升级为可自主操作的“数字员工”。支持云端/本地双模部署,在安全CloudSpace中自动处理文档、代码、邮件、日程等任务。可视化执行、5000+自进化技能、金融级隔离保障。新用户享7天免费体验,3分钟极速上手。阿里云官方活动:https://t.aliyun.com/U/OTnSAH
36 0