亿级分布式系统架构演进实战(二)- 横向扩展(服务无状态化)
亿级分布式系统架构演进实战(一)- 总体概要
服务无状态化详细设计
目标:确保服务实例完全无状态,可任意扩缩容
1. 会话存储改造(Session Management)
核心问题:传统单体应用中,用户会话存储在服务实例内存,无法支持多实例负载均衡。
解决方案:
用户请求 → [LB] → 任意实例 → 会话数据统一存储 → [分布式存储]
使用分布式会话存储,避免横向扩展后多节点会话信息不能共享问题,如用户登录会话。
1.1 分布式会话存储选型比较
方案 | 实现方式 | 适用场景 |
---|---|---|
Redis Cluster | 会话数据以Key-Value形式存储,支持TTL过期、高可用 | 高并发、强一致性要求(生产首选) |
Memcached | 多节点分布式缓存,协议简单 | 需要极低延迟但允许短暂数据丢失的场景 |
Database | 会话数据存入MySQL/PostgreSQL | 小规模系统,需强事务保障(不推荐高并发) |
本项目选择的是Redis Cluster来实现分布式会话存储。
会话管理可优化方向:
• 数据压缩:采用Zstandard/LZ4压缩会话数据(减少30%存储占用)
技术方案
压缩场景: 仅对会话中大于1KB的字段(如用户画像、历史记录)启用压缩。压缩算法选择:LZ4:适用于文本类数据(压缩率20%-30%)Zstandard:适用于二进制数据(压缩率30%-40%) 生产级优化监控压缩率:在Redis写入时记录原始大小和压缩后大小,低于20%压缩率触发告警。动态降级:当CPU使用率超过80%时,自动关闭压缩功能。
• 安全加密:敏感会话字段(如UserID)使用AES-GCM加密存储
• 分片策略:采用Redis Cluster分片,避免单点热点
原生分片机制
哈希槽分配:16384个槽位自动分配到集群节点。客户端路由:使用CRC16算法计算键名哈希值,定位目标分片。
• 容灾机制:跨机房部署Redis Cluster(如3机房部署,每个分片3副本)
这个看情况去选择,开始可以先选择简单的主从结构去代替即可。
数据同步一致性保障写入流程:客户端写入本地机房Master节点Master异步复制到其他两个机房的Slave节点超过半数的节点ACK后返回客户端成功
故障恢复:机房级故障时,通过Raft协议选举新Master数据修复:使用NCDC(Network-Constrained Data Consistency)算法保证最终一致性
1.2 会话迁移策略
场景:旧系统迁移到无状态架构时的会话兼容
(PS 其实这步只是为了在生产环境验证程序的准确性,认真完成后业务允许的话直接停机切换最彻底)
• 双写过渡:
- 新会话写入Redis Cluster
- 旧会话保留在本地内存(Tomcat Session)
- 通过Nginx路由新请求到无状态实例
• 灰度切流:
• 按用户ID范围逐步迁移(如尾号0~9分批切换)
• 监控会话丢失率(要求<0.01%)
1.3 会话安全
• 防窃取:
• Cookie设置HttpOnly、Secure、SameSite属性
• 动态Token刷新机制(每5分钟更新Session ID)
• 防篡改:
• 会话数据签名(HMAC-SHA256)
• 客户端IP绑定(检测IP变更时强制重新认证)
2. 配置外置(Externalized Configuration)
核心问题:配置硬编码或本地文件导致实例间不一致,无法动态生效。
2.1 动态配置中心选型
工具 | 核心能力 | 生产建议 |
---|---|---|
Nacos | 支持配置推送、版本历史、灰度发布,集成Spring Cloud Alibaba | 推荐(阿里生产验证) |
Spring Cloud Config | 与Spring生态无缝集成,支持Git/SVN存储 | 旧系统迁移场景 |
Consul | 服务发现与配置管理一体化,强一致性保证 | 多语言混合技术栈 |
本项目选择的是Nacos作为服务的配置中心
配置分类管理:
• 环境配置(Env):数据库地址、缓存集群节点(区分dev/test/prod)
• 业务规则(Biz):限流阈值、开关配置(如促销活动开关)
• 安全配置(Security):密钥、白名单IP(加密存储)
2.2 灰度发布策略
• 按应用分组:
新配置 → 10%的实例组(如Canary组) → 监控1小时 → 全量发布
• 按用户分桶:
if (userId % 100 < 5) { // 5%用户灰度 applyNewConfig();
}
• 回滚机制:
• 自动回滚:配置更新后错误率上升5%则自动回退
• 版本快照:保留最近10个版本,支持一键回滚
2.3 配置安全
Nacos如果没有修改源码做不了这么细,可以选择每个环境搭建一个Nacos这样的方式。
• 权限分级:
• 开发人员:只读测试环境配置
• 运维人员:可修改生产环境非敏感配置
• 安全管理员:管理密钥类配置
• 审计追踪:
• 记录配置修改人、时间、旧值/新值
• 集成LDAP/AD账号体系
3. 资源管理(Resource Management)
核心问题:服务实例依赖本地资源(文件、缓存),导致状态残留。
3.1 文件存储外迁
• 对象存储方案:
存储类型 | 使用场景 | 示例 |
---|---|---|
热数据 | 频繁访问的文件(如图片缩略图) | 阿里云OSS标准存储 |
冷数据 | 归档日志、备份文件 | 阿里云OSS归档存储/Glacier |
临时文件 | 处理中生成的文件(需定时清理) | 本地SSD + CronJob清理 |
• 上传优化:
• 客户端直传OSS(减少服务端带宽压力)
• 分片上传(支持大文件断点续传)
3.2 内存缓存治理
这项改造其实跟服务无状态话这个目标是没有什么关联性的,本地内存的作用是提升性能,这里是顺便优化了,你们可以根据情况自行选择。
• 本地缓存策略:
缓存类型 | 使用场景 | 淘汰策略 |
---|---|---|
Caffeine | 高频读、数据量小(如用户基础信息) | LRU + 最大条目数限制 |
Guava | 兼容旧系统 | 基于权重淘汰 |
本项目本地缓存使用的是Caffeine
• 防缓存滥用:
• 限制最大内存占比(如JVM堆的20%)
• 监控缓存命中率(低于70%时告警)
3.3 临时资源清理
• 临时文件:
• 定时任务(Cron)清理超过24小时的/tmp文件
• 使用内存文件系统(如tmpfs)加速处理
• 线程池管理:
• 禁止使用全局静态线程池(导致内存泄漏)
• 统一由Spring Bean管理,应用关闭时自动销毁
4. 生产级实施步骤
-
架构评估:
• 识别现有状态:会话存储位置、本地配置文件、资源依赖
• 确定技术栈:Redis版本、配置中心选型、存储迁移工具 -
灰度迁移:
• 阶段1:新会话写入Redis,同时保留本地Session(双写)
• 阶段2:配置中心逐步替换本地配置文件
• 阶段3:文件存储迁移到OSS,删除本地存储逻辑 -
验证与监控:
• 自动化测试:模拟实例重启,验证会话不丢失
• 监控看板:会话存储延迟、配置推送成功率、临时文件磁盘占用 -
全量切换:
• 旧服务下线:确保所有流量切至无状态实例
• 资源清理:关闭本地Session存储,删除冗余配置
5. 升级效果
总结:
1、利用redis存储服务会话信息
2、利用nacos config 实现服务配置信息管理
3、利用OSS做文件上传、读取
以上应用服务可以实现无状态话,当应用服务达到性能瓶颈的时候,可通过横向增加节点,然后利用nginx的负载均衡调度,实现性能增加。
相关文章:

亿级分布式系统架构演进实战(二)- 横向扩展(服务无状态化)
亿级分布式系统架构演进实战(一)- 总体概要 服务无状态化详细设计 目标:确保服务实例完全无状态,可任意扩缩容 1. 会话存储改造(Session Management) 核心问题:传统单体应用中,用…...

零成本短视频爆款制造手册
——Q版+情感+互动的流量密码拆解 适用平台:抖音/快手/视频号 核心指标:点赞率>10% | 完播率>40% | 涨粉成本<0.3元 一、底层逻辑框架 1. 爆款元素融合公式 [ 3秒钩子 ] + [ 7秒沉浸 ] + [ 5秒引爆 ] = 15秒黄金结构 │ │ └─▶ 互动指令+情感…...

红队思想:Live off the Land - 靠山吃山,靠水吃水
在网络安全领域,尤其是红队(Red Team)渗透测试中,“Live off the Land”(简称 LotL,中文可译为“靠山吃山,靠水吃水”)是一种极具隐秘性和实用性的攻击策略。这一理念源于现实生活中…...

C语言八股---预处理,编译,汇编与链接篇
前言 从多个.c文件到达一个可执行文件的四步: 预处理–>编译–>汇编–>链接 预处理 预处理过程就是预处理器处理这些预处理指令(要不然编译器完全不认识),最终会生成 main.i的文件 主要做的事情有如下几点: 展开头文件展开宏条件编译删除注释添加行号等信息保留…...

平衡二叉树(AVL树)
平衡二叉树是啥我就不多说了,本篇博客只讲原理与方法。 首先引入平衡因子的概念。平衡因子(Balance Factor),以下简称bf。 bf 右子树深度 - 左子树深度。平衡结点的平衡因子可为:-1,0,1。除此…...

SpringBoot(一)--搭建架构5种方法
目录 一、⭐Idea从spring官网下载打开 2021版本idea 1.打开创建项目 2.修改pom.xml文件里的版本号 2017版本idea 二、从spring官网下载再用idea打开 三、Idea从阿里云的官网下载打开 编辑 四、Maven项目改造成springboot项目 五、从阿里云官网下载再用idea打开 Spri…...

RabbitMQ使用延迟消息
RabbitMQ使用延迟消息 1.什么情况下使用延迟消息 延迟消息适用于需要在一段时间后执行某些操作的场景,常见的有以下几类: 1.1. 订单超时取消(未支付自动取消) 场景: 用户下单后,如果 30 分钟内未付款&a…...

MyBatis-Plus 分页查询接口返回值问题剖析
在使用 MyBatis-Plus 进行分页查询时,很多开发者会遇到一个常见的问题:当分页查询接口返回值定义为 Page<T> 时,执行查询会抛出异常;而将返回值修改为 IPage<T> 时,分页查询却能正常工作。本文将从 MyBatis-Plus 的分页机制入手,详细分析这一问题的根源,并提…...

DeepLabv3+改进7:在主干网络中添加SegNext_Attention|助力涨点
🔥【DeepLabv3+改进专栏!探索语义分割新高度】 🌟 你是否在为图像分割的精度与效率发愁? 📢 本专栏重磅推出: ✅ 独家改进策略:融合注意力机制、轻量化设计与多尺度优化 ✅ 即插即用模块:ASPP+升级、解码器 PS:订阅专栏提供完整代码 论文简介 近期有关移动网络设计…...

c语言笔记 内存管理之栈内存
物理内存和虚拟内存 在c语言的程序需要内存资源,用来存放变量,常量,函数代码等,不同的内容存放在不同的内存区域,不同的内存区域有着不同的特征。 c语言的每一个进程都有着一片结构相同的 虚拟内存,虚拟内…...

分布式事务的原理
文章目录 基于 XA 协议的两阶段提交(2PC)三阶段提交(3PC)TCC(Try-Confirm-Cancel)Saga 模式消息队列(可靠消息最终一致性) 分布式事务是指在分布式系统中,涉及多个节点或…...

鸿基智启:东土科技为具身智能时代构建确定性底座
人类文明的每一次跨越都伴随着工具的革新。从蒸汽机的齿轮到计算机的代码,生产力的进化始终与技术的“具身化”紧密相连。当大语言模型掀起认知革命,具身智能正以“物理实体自主决策”的双重属性重新定义工业、医疗、服务等领域的运行逻辑。在这场革命中…...

SQL29 计算用户的平均次日留存率
SQL29 计算用户的平均次日留存率 计算用户的平均次日留存率_牛客题霸_牛客网 题目:现在运营想要查看用户在某天刷题后第二天还会再来刷题的留存率。 示例:question_practice_detail -- 输入: DROP TABLE IF EXISTS question_practice_detai…...

MWC 2025 | 移远通信推出AI智能无人零售解决方案,以“动态视觉+边缘计算”引领智能零售新潮流
在无人零售市场蓬勃发展的浪潮中,自动售货机正经历着从传统机械式操作向AI视觉技术的重大跨越。 移远通信作为全球领先的物联网整体解决方案供应商,精准把握行业趋势,在2025世界移动通信大会(MWC)上宣布推出全新AI智能…...

sparkTTS window 安装
下载 Spark-TTS Go to Spark-TTS GitHubClick "Code" > "Download ZIP", then extract it. 2. 建立 Conda 环境 conda create -n sparktts python3.12 -y conda activate sparktts 3. Install Dependencies pip install -r requirements.txt In…...

数据库原理6
1.数据是信息的载体 2.数据库应用程序人员的主要职责:编写应用系统的程序模块 3.关系规范化理论主要属于数据库理论的研究范畴 4.数据库主要有检索和修改(包括插入,删除,更新)两大操作 5.概念模型又称为语义模型。…...

接口自动化入门 —— Http的请求头,请求体,响应码解析!
在接口自动化测试中,HTTP请求头、请求体和响应码是核心组成部分。理解它们的作用、格式和解析方法对于进行有效的接口测试至关重要。以下是详细解析: 1. HTTP 请求头(Request Header) 1.1 作用 请求头是客户端向服务器发送的附加…...

tcc编译器教程6 进一步学习编译gmake源代码
本文以编译gmake为例讲解如何使用tcc进行复杂一点的c代码的编译 1 简介 前面主要讲解了如何编译lua解释器,lua解释器的编译很简单也很容易理解.当然大部分c语言程序编译没那么简单,下面对前面的gmake程序进行编译. 2 gmake源码结构 首先打开之前tcc-busybox-for-win32\gmak…...

公司共享网盘怎么建立
公司共享网盘的建立,关键在于明确使用需求、选择合适的网盘服务、搭建统一的文件管理规范、做好权限分级与安全防护。尤其要强调选择合适的网盘服务这一点,如果企业规模较大,且对协同办公的需求强烈,就需要考虑支持多人实时协作、…...

【高分论文密码】AI大模型和R语言的全类型科研图形绘制,从画图、标注、改图、美化、组合、排序分解科研绘图每个步骤
在科研成果竞争日益激烈的当下,「一图胜千言」已成为高水平SCI期刊的硬性门槛——数据显示很多情况的拒稿与图表质量直接相关。科研人员普遍面临的工具效率低、设计规范缺失、多维数据呈现难等痛点,因此科研绘图已成为成果撰写中的至关重要的一个环节&am…...

深入理解Java中的static关键字及其内存原理
static是Java中实现类级共享资源的核心修饰符,它突破了对象实例化的限制,使得变量和方法能够直接与类本身绑定。这种特性让static成为构建工具类、全局配置等场景的利器,但同时也带来独特的内存管理机制需要开发者关注。 static修饰成员变量…...

linux 系统 之centos安装 docker
对于 CentOS 安装 Docker 的前置条件 首先,需要安装一些必要的软件包, 对于 CentOS 7,可以使用以下命令: sudo yum install -y yum-utils device-mapper-persistent-data lvm2添加 Docker 仓库 设置 Docker 的官方仓库。对于 …...

Python语法核心架构与核心知识点:从理论到实践
一、Python的核心设计哲学 Python以“简洁优雅”为核心理念,遵循以下原则: # Zen of Python(输入 import this 可查看) >>> import this The Zen of Python, by Tim Peters ... Simple is better than complex. Readab…...

FreeRTOS(5)内核控制函数及其他函数
FreeRTOS 提供了一些用于控制内核的 API 函数,这些 API 函数主要包含了进出临界区、开关中断、启停任务调度器等一系列用于控制内核的 API 函数。本章就来学习 FreeRTOS 的内 核控制函数。 内核控制函数 1. 函数 taskYIELD() 此函数用于请求切换任务, …...

网络DNS怎么更改?
访问速度慢或某些网站无法打开?改变网络DNS设置可能会帮助解决这些问题。本文将详细介绍如何更改网络DNS,包括更改的原因、具体步骤。 一、为什么要更改DNS? 更改DNS的原因有很多,以下是一些主要的考虑因素:某些公共DNS服务器的响应速度比…...

VIC模型有哪些优势?适用哪些范围?基于QGIS的VIC模型建模;未来气候变化模型预测;基于R语言VIC参数率定和优化
VIC模型是一个大尺度的半分布式水文模型,其设计之初就是为了模拟大流域的水文过程;它能够计算陆地-大气的能量通量,考虑土壤性质和土地利用的影响,自带有简化的湖泊/湿地模块,也能够将植被状况,…...

脏读、不可重复读,幻读的区别 mvcc及四种隔离级别
脏读:事务a还未提交更新事务b就可以看见 不可重复读:强调修改和删除,一个事务多次查询同一个表结果不同 幻读:强调新增,也是一个事务多次查询同一个表结果不同 mvcc是用来解决读写冲突的无锁并发控制 三个实现基础&…...

SpringAI介绍及本地模型使用方法
博客原文地址 前言 Spring在Java语言中一直稳居高位,与AI的洪流碰撞后也产生了一些有趣的”化学反应“,当然你要非要说碰撞属于物理反应也可以, 在经历了一系列复杂的反应方程后,Spring家族的新成员——SpringAI,就…...

numpy广播性质
一、核心规则 一维数组本质 shape (n,)的数组是无方向向量,既非严格行向量也非列向量 自动广播机制 在矩阵乘法(或np.dot())中,一维数组会自动调整维度: 前乘时视为行向量 shape (1,n)后乘时视为列向量 shape (n,1) 二、运算类型对比 假…...

Flutter_学习记录_实现列表上下拉加载 +实现加载html的数据
1. 效果图 2. 下拉加载的实现RefreshIndicator 在Flutter官方sdk中给我们提供了下拉刷新的组件RefreshIndicator。 // 显示内容列表Widget _showNewsListWidget() {if (_newsDataList.isNotEmpty) {// RefreshIndicator 来实现下拉加载的功能return RefreshIndicator(onRefr…...