当前位置: 首页 > news >正文

亿级分布式系统架构演进实战(二)- 横向扩展(服务无状态化)


亿级分布式系统架构演进实战(一)- 总体概要

服务无状态化详细设计

目标:确保服务实例完全无状态,可任意扩缩容


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加密存储

用户登录
生成明文Session数据
敏感字段标记
AES-GCM加密
直接存储
存储密文+IV+AuthTag

分片策略:采用Redis Cluster分片,避免单点热点

原生分片机制
​   哈希槽分配:16384个槽位自动分配到集群节点。​客户端路由:使用CRC16算法计算键名哈希值,定位目标分片。

容灾机制:跨机房部署Redis Cluster(如3机房部署,每个分片3副本)
这个看情况去选择,开始可以先选择简单的主从结构去代替即可。

机房C
机房B
机房A
异步复制
异步复制
异步复制
异步复制
异步复制
异步复制
Master-分片3
Slave-分片1
Master-分片2
Slave-分片3
Master-分片1
Slave-分片2
数据同步一致性保障​写入流程:客户端写入本地机房Master节点Master异步复制到其他两个机房的Slave节点超过半数的节点ACK后返回客户端成功
​  故障恢复:机房级故障时,通过Raft协议选举新Master数据修复:使用NCDC(Network-Constrained Data Consistency)算法保证最终一致性
1.2 会话迁移策略

场景:旧系统迁移到无状态架构时的会话兼容
(PS 其实这步只是为了在生产环境验证程序的准确性,认真完成后业务允许的话直接停机切换最彻底)

双写过渡

  1. 新会话写入Redis Cluster
  2. 旧会话保留在本地内存(Tomcat Session)
  3. 通过Nginx路由新请求到无状态实例

灰度切流
• 按用户ID范围逐步迁移(如尾号0~9分批切换)
• 监控会话丢失率(要求<0.01%)

User Nginx NewApp OldApp Redis Tomcat 请求 /api/login 转发请求 写入新会话(user123) 双写旧会话(user123) 返回登录成功 请求 /api/profile (携带Cookie) 旧版实例处理 读取旧会话(user123) 返回用户数据 User Nginx NewApp OldApp Redis Tomcat
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. 生产级实施步骤
  1. 架构评估
    • 识别现有状态:会话存储位置、本地配置文件、资源依赖
    • 确定技术栈:Redis版本、配置中心选型、存储迁移工具

  2. 灰度迁移
    • 阶段1:新会话写入Redis,同时保留本地Session(双写)
    • 阶段2:配置中心逐步替换本地配置文件
    • 阶段3:文件存储迁移到OSS,删除本地存储逻辑

  3. 验证与监控
    • 自动化测试:模拟实例重启,验证会话不丢失
    • 监控看板:会话存储延迟、配置推送成功率、临时文件磁盘占用

  4. 全量切换
    • 旧服务下线:确保所有流量切至无状态实例
    • 资源清理:关闭本地Session存储,删除冗余配置


5. 升级效果

总结:
1、利用redis存储服务会话信息
2、利用nacos config 实现服务配置信息管理
3、利用OSS做文件上传、读取
以上应用服务可以实现无状态话,当应用服务达到性能瓶颈的时候,可通过横向增加节点,然后利用nginx的负载均衡调度,实现性能增加。
在这里插入图片描述

相关文章:

亿级分布式系统架构演进实战(二)- 横向扩展(服务无状态化)

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

零成本短视频爆款制造手册

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

红队思想:Live off the Land - 靠山吃山,靠水吃水

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

C语言八股---预处理,编译,汇编与链接篇

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

平衡二叉树(AVL树)

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

SpringBoot(一)--搭建架构5种方法

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

RabbitMQ使用延迟消息

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

MyBatis-Plus 分页查询接口返回值问题剖析

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

DeepLabv3+改进7:在主干网络中添加SegNext_Attention|助力涨点

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

c语言笔记 内存管理之栈内存

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

分布式事务的原理

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

鸿基智启:东土科技为具身智能时代构建确定性底座

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

SQL29 计算用户的平均次日留存率

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

MWC 2025 | 移远通信推出AI智能无人零售解决方案,以“动态视觉+边缘计算”引领智能零售新潮流

在无人零售市场蓬勃发展的浪潮中&#xff0c;自动售货机正经历着从传统机械式操作向AI视觉技术的重大跨越。 移远通信作为全球领先的物联网整体解决方案供应商&#xff0c;精准把握行业趋势&#xff0c;在2025世界移动通信大会&#xff08;MWC&#xff09;上宣布推出全新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.数据库应用程序人员的主要职责&#xff1a;编写应用系统的程序模块 3.关系规范化理论主要属于数据库理论的研究范畴 4.数据库主要有检索和修改&#xff08;包括插入&#xff0c;删除&#xff0c;更新&#xff09;两大操作 5.概念模型又称为语义模型。…...

接口自动化入门 —— Http的请求头,请求体,响应码解析!

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

tcc编译器教程6 进一步学习编译gmake源代码

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

公司共享网盘怎么建立

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

【高分论文密码】AI大模型和R语言的全类型科研图形绘制,从画图、标注、改图、美化、组合、排序分解科研绘图每个步骤

在科研成果竞争日益激烈的当下&#xff0c;「一图胜千言」已成为高水平SCI期刊的硬性门槛——数据显示很多情况的拒稿与图表质量直接相关。科研人员普遍面临的工具效率低、设计规范缺失、多维数据呈现难等痛点&#xff0c;因此科研绘图已成为成果撰写中的至关重要的一个环节&am…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中&#xff0c;明确沟通敏捷转型目的尤为关键&#xff0c;团队成员只有清晰理解转型背后的原因和利益&#xff0c;才能降低对变化的…...

Pydantic + Function Calling的结合

1、Pydantic Pydantic 是一个 Python 库&#xff0c;用于数据验证和设置管理&#xff0c;通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发&#xff08;如 FastAPI&#xff09;、配置管理和数据解析&#xff0c;核心功能包括&#xff1a; 数据验证&#xff1a;通过…...

相关类相关的可视化图像总结

目录 一、散点图 二、气泡图 三、相关图 四、热力图 五、二维密度图 六、多模态二维密度图 七、雷达图 八、桑基图 九、总结 一、散点图 特点 通过点的位置展示两个连续变量之间的关系&#xff0c;可直观判断线性相关、非线性相关或无相关关系&#xff0c;点的分布密…...

UE5 音效系统

一.音效管理 音乐一般都是WAV,创建一个背景音乐类SoudClass,一个音效类SoundClass。所有的音乐都分为这两个类。再创建一个总音乐类&#xff0c;将上述两个作为它的子类。 接着我们创建一个音乐混合类SoundMix&#xff0c;将上述三个类翻入其中&#xff0c;通过它管理每个音乐…...

麒麟系统使用-进行.NET开发

文章目录 前言一、搭建dotnet环境1.获取相关资源2.配置dotnet 二、使用dotnet三、其他说明总结 前言 麒麟系统的内核是基于linux的&#xff0c;如果需要进行.NET开发&#xff0c;则需要安装特定的应用。由于NET Framework 是仅适用于 Windows 版本的 .NET&#xff0c;所以要进…...