外卖霸王餐API故障演练:Java团队基于Chaos Monkey模拟“Redis集群宕机”“数据库主从延迟”场景的应急恢复预案验证
外卖霸王餐API故障演练Java团队基于Chaos Monkey模拟“Redis集群宕机”“数据库主从延迟”场景的应急恢复预案验证背景为什么外卖霸王餐API需要故障演练作为外卖霸王餐API唯一供给源头同时也是霸王餐外卖CPS取链源头俱美开放平台承载着海量高并发的请求。在“霸王餐”活动期间瞬时流量可能激增数十倍任何基础设施的微小故障都可能被放大导致服务雪崩。传统的测试只能验证功能正确性无法暴露系统在极端情况下的脆弱性。因此我们引入了混沌工程Chaos Engineering理念通过主动注入故障来验证系统的弹性和应急预案的有效性。技术选型为什么是Chaos MonkeyChaos Monkey是Netflix开源的混沌工程工具它能随机终止生产环境中的实例迫使工程师构建更具弹性的服务。在我们的Java技术栈中我们使用了其JVM层面的实现——chaos-monkey-spring-boot它能无侵入地对我们的Spring Boot应用进行故障注入。演练场景一模拟Redis集群宕机Redis作为我们的核心缓存存储着用户会话、活动配置和热点数据。一旦Redis集群宕机所有请求将直接穿透到数据库后果不堪设想。1. 引入Chaos Monkey依赖!-- pom.xml --dependencygroupIdde.codecentric/groupIdartifactIdchaos-monkey-spring-boot/artifactIdversion2.5.0/version/dependency2. 配置Chaos Monkey# application.ymlchaos:monkey:enabled:truewatcher:repository:true# 开启对Repository层的监控rest-controller:true# 开启对Controller层的监控assaults:level:5# 攻击等级1-10latency-active:true# 开启延迟攻击latency-range-start:5000# 延迟5秒latency-range-end:10000exception-active:true# 开启异常攻击exceptions:-java.net.ConnectException# 模拟连接异常3. 编写业务代码与降级策略我们的业务代码需要能够优雅地处理Redis不可用的情况。packagebaodanbao.com.cn.service;importbaodanbao.com.cn.model.Activity;importbaodanbao.com.cn.repository.ActivityRepository;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.cache.annotation.Cacheable;importorg.springframework.dao.DataAccessException;importorg.springframework.data.redis.connection.RedisConnection;importorg.springframework.data.redis.core.RedisCallback;importorg.springframework.data.redis.core.RedisTemplate;importorg.springframework.stereotype.Service;/** * 活动服务 * author baodanbao.com.cn */ServicepublicclassActivityService{AutowiredprivateActivityRepositoryactivityRepository;AutowiredprivateRedisTemplateString,ObjectredisTemplate;/** * 获取活动详情带缓存 * param activityId 活动ID * return 活动信息 */Cacheable(valueactivity,key#activityId)publicActivitygetActivityDetail(LongactivityId){// 模拟从数据库查询returnactivityRepository.findById(activityId).orElse(null);}/** * 模拟Redis宕机时的降级查询 * param activityId 活动ID * return 活动信息 */publicActivitygetActivityWithFallback(LongactivityId){try{// 尝试访问Redis如果Redis宕机这里会抛出异常redisTemplate.execute((RedisCallbackObject)RedisConnection::ping);returngetActivityDetail(activityId);}catch(DataAccessExceptione){// Redis不可用执行降级策略直接查数据库System.out.println(Redis不可用执行降级策略直接查询数据库);returnactivityRepository.findById(activityId).orElse(null);}}}演练场景二模拟数据库主从延迟在外卖霸王餐业务中用户下单后需要立即查询订单状态。如果此时发生数据库主从延迟用户可能会看到“订单不存在”的错误提示体验极差。1. 配置读写分离首先我们需要配置主从数据源。packagebaodanbao.com.cn.config;importorg.springframework.beans.factory.annotation.Qualifier;importorg.springframework.boot.context.properties.ConfigurationProperties;importorg.springframework.boot.jdbc.DataSourceBuilder;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.Primary;importorg.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;importjavax.sql.DataSource;importjava.util.HashMap;importjava.util.Map;/** * 数据源配置 * author baodanbao.com.cn */ConfigurationpublicclassDataSourceConfig{Bean(namemasterDataSource)ConfigurationProperties(prefixspring.datasource.master)publicDataSourcemasterDataSource(){returnDataSourceBuilder.create().build();}Bean(nameslaveDataSource)ConfigurationProperties(prefixspring.datasource.slave)publicDataSourceslaveDataSource(){returnDataSourceBuilder.create().build();}BeanPrimarypublicDataSourceroutingDataSource(Qualifier(masterDataSource)DataSourcemasterDataSource,Qualifier(slaveDataSource)DataSourceslaveDataSource){DynamicDataSourcedynamicDataSourcenewDynamicDataSource();MapObject,ObjecttargetDataSourcesnewHashMap();targetDataSources.put(DataSourceType.MASTER,masterDataSource);targetDataSources.put(DataSourceType.SLAVE,slaveDataSource);dynamicDataSource.setTargetDataSources(targetDataSources);dynamicDataSource.setDefaultTargetDataSource(masterDataSource);// 默认使用主库returndynamicDataSource;}}/** * 动态数据源 * author baodanbao.com.cn */publicclassDynamicDataSourceextendsAbstractRoutingDataSource{OverrideprotectedObjectdetermineCurrentLookupKey(){returnDataSourceContextHolder.getDataSourceType();}}/** * 数据源上下文 * author baodanbao.com.cn */publicclassDataSourceContextHolder{privatestaticfinalThreadLocalDataSourceTypeCONTEXTnewThreadLocal();publicstaticvoidsetDataSourceType(DataSourceTypetype){CONTEXT.set(type);}publicstaticDataSourceTypegetDataSourceType(){returnCONTEXT.get();}publicstaticvoidclearDataSourceType(){CONTEXT.remove();}}/** * 数据源类型枚举 * author baodanbao.com.cn */publicenumDataSourceType{MASTER,SLAVE}2. 模拟主从延迟并验证我们通过Chaos Monkey在从库上注入延迟然后验证业务代码是否能正确处理。packagebaodanbao.com.cn.service;importbaodanbao.com.cn.config.DataSourceContextHolder;importbaodanbao.com.cn.config.DataSourceType;importbaodanbao.com.cn.model.Order;importbaodanbao.com.cn.repository.OrderRepository;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;/** * 订单服务 * author baodanbao.com.cn */ServicepublicclassOrderService{AutowiredprivateOrderRepositoryorderRepository;/** * 创建订单 * param order 订单对象 * return 创建的订单 */publicOrdercreateOrder(Orderorder){// 写操作强制使用主库DataSourceContextHolder.setDataSourceType(DataSourceType.MASTER);OrdersavedOrderorderRepository.save(order);DataSourceContextHolder.clearDataSourceType();returnsavedOrder;}/** * 查询订单模拟主从延迟场景 * param orderId 订单ID * return 订单信息 */publicOrdergetOrder(LongorderId){// 读操作默认使用从库DataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE);OrderorderorderRepository.findById(orderId).orElse(null);// 如果从库查不到可能是主从延迟降级到主库查询if(ordernull){System.out.println(从库未查到订单可能为主从延迟降级查询主库);DataSourceContextHolder.setDataSourceType(DataSourceType.MASTER);orderorderRepository.findById(orderId).orElse(null);}DataSourceContextHolder.clearDataSourceType();returnorder;}}演练执行与结果分析启动应用启动我们的Spring Boot应用确保Chaos Monkey已生效。触发攻击通过Actuator端点POST /actuator/chaosmonkey/assaults触发异常攻击。观察日志Redis宕机日志中应出现“Redis不可用执行降级策略直接查询数据库”的打印且接口响应时间略有增加但服务未中断。数据库主从延迟日志中应出现“从库未查到订单可能为主从延迟降级查询主库”的打印最终能正确返回订单信息。验证监控检查Prometheus/Grafana监控面板确认在故障期间QPS、响应时间、错误率等指标在可接受范围内。通过以上演练我们验证了俱美开放平台在面对Redis宕机和数据库主从延迟等极端情况时具备完善的应急恢复预案和系统弹性能够保障外卖霸王餐API的稳定运行。本文著作权归 俱美开放平台 转载请注明出处

相关新闻

C++在线OJ负载均衡实战:从单体架构到高可用集群的设计与实现

C++在线OJ负载均衡实战:从单体架构到高可用集群的设计与实现

1. 项目概述:从单点崩溃到弹性服务的蜕变 做在线评测系统(Online Judge, OJ)的,谁没经历过半夜被流量打崩的噩梦?尤其是当学校搞个编程竞赛,或者某门课的实验DDL快到了,几百上千个学…

2026/10/19 14:40:43 阅读更多 →
从浏览器输入URL到页面显示——计算机网络原理解析

从浏览器输入URL到页面显示——计算机网络原理解析

本文以计算机网络课程知识为主线,结合Web开发中的实际场景(Tomcat、Servlet、Ajax、HTTP状态码等),深入浅出地讲解应用层、传输层、网络层、数据链路层及物理层的工作原理,并完整剖析DNS解析、IP/MAC寻址、路由与交换等…

2026/10/18 16:03:58 阅读更多 →
Sqribble:基于模板规则的云原生文档自动化操作系统

Sqribble:基于模板规则的云原生文档自动化操作系统

1. 项目概述:当“模板”成为文档生产的操作系统 我第一次用 Sqribble 是在帮一个做知识付费的朋友赶制一份《新手理财避坑指南》。他手上有三篇写得不错的公众号文章,但排版成 PDF 发给学员时,Word 导出的格式乱得像被猫抓过,自己…

2026/10/17 5:38:03 阅读更多 →

最新新闻

AI平台选型指南:从通用对话到开源自部署的实战策略

AI平台选型指南:从通用对话到开源自部署的实战策略

1. 主流AI平台的全景地图与选型逻辑1.1 为什么现在聊“AI平台”比聊“AI模型”更实际过去一年我接触了不少团队,从几个人的小工作室到上百人的产品线,大家问得最多的问题早就不是“哪个模型最强”,而是“我该把活儿交给哪个平台”。这个转变很…

2026/10/20 21:33:02 阅读更多 →
Win11 25H2下WPS频繁未响应:一个从证据到方向的完整排查记录

Win11 25H2下WPS频繁未响应:一个从证据到方向的完整排查记录

先说结论:我遇到的这个“Win11 25H2 WPS 频繁未响应”问题,直到现在还没有一个确定的根因。但是经过几天反复测试和收集证据,基本可以锁定它并不是WPS软件自身单独惹的祸,而是系统底层和当前环境里某个驱动层组件有兼容性冲突。这…

2026/10/20 21:33:02 阅读更多 →
MCP / Agent / Skill 技术生态分类汇总:用 TaoToken 统一 Key 打通三类工具链

MCP / Agent / Skill 技术生态分类汇总:用 TaoToken 统一 Key 打通三类工具链

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 21:33:02 阅读更多 →
Claude账号防封全攻略:避开风控红线,让账号长期稳定

Claude账号防封全攻略:避开风控红线,让账号长期稳定

说来有点丢人,我在刚接触 Claude 的头两个月里,就亲眼看着身边三个朋友先后被提示账号异常,其中一个甚至用了不到三天就进小黑屋。那时候大家的第一反应都是"平台是不是疯了",但后来我对照着官方使用条款和自己的操作记…

2026/10/20 21:33:02 阅读更多 →
AI漫剧工业化生产流水线:人机协作边界与六层技术栈实战

AI漫剧工业化生产流水线:人机协作边界与六层技术栈实战

1. 项目概述:这不是“白嫖教程”,而是一套可落地的AI漫剧工业化生产流水线“AI漫剧制作全教程”这个标题,乍看是知识付费圈常见的流量钩子,但真正拆开来看,它背后指向的是一整套正在快速成型的数字内容工业化新范式。我…

2026/10/20 21:33:01 阅读更多 →
FPGA开发者必看:SRIO协议从IP配置到数据收发的完整调试指南

FPGA开发者必看:SRIO协议从IP配置到数据收发的完整调试指南

简介:面向FPGA与嵌入式系统开发者,这套Xilinx SRIO使用例程围绕Serial RapidIO高速串行互连协议在Spartan6系列中的实际部署,系统覆盖硬核配置、端口速率选择、测试平台搭建与仿真验证,解决高带宽低延迟场景下的接口设计与调试难题…

2026/10/20 21:31:57 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →