第2475篇:混沌工程与AI——用LLM生成更智能的故障注入场景
2026/4/30大约 7 分钟
第2475篇:混沌工程与AI——用LLM生成更智能的故障注入场景
适读人群:SRE、后端工程师、技术负责人 | 阅读时长:约16分钟 | 核心价值:用LLM生成针对性的混沌工程实验方案,让故障注入更有目标性
混沌工程这个词,现在很多团队都知道,但真正把它做起来的团队并不多。
原因我问过好几个团队,说法高度一致:不知道要打什么故障,打了也不知道学到了什么。
Netflix的混沌猴子随机Kill Pod的做法,对于他们这种微服务高度成熟的公司很有效,但对于业务系统复杂度中等、团队混沌工程经验不多的团队来说,随机注入故障就是瞎折腾——可能测了一些根本不会在生产发生的场景,遗漏了真正有价值的场景。
LLM能帮做的是:基于服务架构和历史事故,智能地规划混沌工程实验,让每次实验都有明确的目的和预期结果。
混沌工程实验设计的核心思路
好的混沌工程实验要回答三个问题:
- 假设稳态:正常情况下,这个系统的什么指标应该是什么值?
- 实验变量:我要注入什么故障?
- 预期观测:如果系统健壮,这个故障应该被如何处理?如果系统不够健壮,会发生什么?
大多数团队在第一步就卡住了——没有明确定义"稳态",也没想清楚"注什么、观察什么",导致实验没有意义。
AI实验规划系统
1. 系统脆弱性分析
@Service
public class SystemResilienceAnalyzer {
private final ChatClient chatClient;
private final ServiceTopologyRepository topologyRepository;
private final IncidentHistoryRepository incidentHistory;
/**
* 基于系统架构和历史事故,分析潜在的脆弱点
*/
public ResilienceAnalysisReport analyzeVulnerabilities(String serviceId) {
// 获取服务拓扑
ServiceTopology topology = topologyRepository.getTopology(serviceId);
// 获取历史事故(找出已经暴露过的问题)
List<IncidentRecord> incidents = incidentHistory.getRecentIncidents(
serviceId, Duration.ofDays(365)
);
String analysisPrompt = buildVulnerabilityPrompt(topology, incidents);
ChatResponse response = chatClient.call(new Prompt(
List.of(
new SystemMessage(CHAOS_ENGINEER_SYSTEM_PROMPT),
new UserMessage(analysisPrompt)
),
OpenAiChatOptions.builder()
.withModel("gpt-4o")
.withTemperature(0.3f)
.withResponseFormat(new ResponseFormat(ResponseFormat.Type.JSON_OBJECT))
.build()
));
return parseAnalysisReport(response.getResult().getOutput().getContent());
}
private String buildVulnerabilityPrompt(
ServiceTopology topology,
List<IncidentRecord> incidents) {
StringBuilder sb = new StringBuilder();
sb.append("## 系统拓扑\n");
sb.append("核心服务: ").append(topology.getCoreService()).append("\n");
sb.append("上游依赖: ").append(topology.getUpstreamServices()).append("\n");
sb.append("下游依赖(关键): ").append(topology.getCriticalDownstreams()).append("\n");
sb.append("数据存储: ").append(topology.getDataStores()).append("\n");
sb.append("消息队列: ").append(topology.getMessageQueues()).append("\n\n");
sb.append("## 已知的弹性能力\n");
topology.getResilienceFeatures().forEach(f ->
sb.append("- ").append(f).append("\n")
);
sb.append("\n## 历史事故(过去一年)\n");
incidents.forEach(inc -> sb.append(String.format(
"- [%s] 影响: %s, 根因: %s, 持续: %d分钟\n",
inc.getDate(), inc.getImpactDescription(),
inc.getRootCause(), inc.getDurationMinutes()
)));
sb.append("\n请分析:\n");
sb.append("1. 系统中最脆弱的环节(单点故障、缺少容错等)\n");
sb.append("2. 历史事故揭示的未修复的系统缺陷\n");
sb.append("3. 推荐的混沌工程实验清单(按价值排序)\n");
return sb.toString();
}
private static final String CHAOS_ENGINEER_SYSTEM_PROMPT = """
你是一个有丰富经验的混沌工程师,帮助团队识别系统弱点并设计有针对性的混沌实验。
分析时关注:
1. 依赖链路上的单点故障
2. 缺乏超时/熔断/降级的地方
3. 数据库/缓存的故障传播路径
4. 网络分区对服务的影响
5. 资源耗尽(CPU/内存/线程/连接池)场景
返回JSON:
{
"vulnerabilities": [
{
"name": "漏洞名称",
"description": "描述",
"severity": "HIGH/MEDIUM/LOW",
"type": "SPOF/CASCADING/RESOURCE_EXHAUSTION/DATA_CORRUPTION/NETWORK",
"component": "涉及的组件"
}
],
"recommendedExperiments": [
{
"name": "实验名称",
"targetVulnerability": "针对哪个漏洞",
"priority": "HIGH/MEDIUM/LOW",
"estimatedRisk": "LOW/MEDIUM/HIGH"
}
]
}
""";
}2. 实验方案生成
@Service
public class ChaosExperimentDesigner {
private final ChatClient chatClient;
/**
* 为每个脆弱点设计具体的混沌实验
*/
public ChaosExperiment designExperiment(
SystemVulnerability vulnerability,
ServiceTopology topology) {
String designPrompt = """
为以下系统脆弱点设计一个混沌工程实验:
漏洞: %s
描述: %s
涉及组件: %s
系统环境:
- 部署平台: %s
- 监控工具: %s
- 故障注入工具: %s
实验设计要包含:
1. 稳态假设:正常情况下哪些指标是健康的(给出具体数值)
2. 实验变量:具体注入什么故障(明确的操作步骤)
3. 成功标准:如果系统健壮,应该观察到什么
4. 失败标准:什么情况下要立即中止实验(保护条件)
5. 回滚步骤:如果出了问题,如何恢复
6. 预期洞察:这个实验能告诉我们什么
返回JSON格式的实验方案。
""".formatted(
vulnerability.getName(),
vulnerability.getDescription(),
vulnerability.getComponent(),
topology.getPlatform(),
topology.getMonitoringTools(),
topology.getChaosTools()
);
ChatResponse response = chatClient.call(new Prompt(
List.of(
new SystemMessage(EXPERIMENT_DESIGNER_PROMPT),
new UserMessage(designPrompt)
),
OpenAiChatOptions.builder()
.withModel("gpt-4o")
.withTemperature(0.3f)
.withResponseFormat(new ResponseFormat(ResponseFormat.Type.JSON_OBJECT))
.build()
));
return parseChaosExperiment(response.getResult().getOutput().getContent(), vulnerability);
}
private static final String EXPERIMENT_DESIGNER_PROMPT = """
你是一个混沌工程专家,擅长设计安全、有价值的混沌实验。
设计实验时的原则:
1. 最小化爆炸半径:在最小的范围内验证假设
2. 可观测性:实验期间要能清楚地观察到系统行为
3. 可回滚:任何时候都能快速停止实验并恢复
4. 明确的成功/失败标准:不要模糊
5. 渐进式:从最低风险的场景开始,逐渐升级
返回JSON:
{
"experimentName": "实验名称",
"hypothesis": "稳态假设描述",
"steadyState": {
"metrics": [{"name": "指标名", "expectedValue": "预期值", "tolerance": "±10%"}],
"measurementDuration": "测量稳态的时间"
},
"faultInjection": {
"type": "故障类型",
"target": "故障目标",
"parameters": "故障参数",
"toolCommand": "具体的工具命令(如chaos-mesh/chaosblade的YAML)",
"duration": "故障持续时间"
},
"successCriteria": ["成功标准列表"],
"abortConditions": ["中止条件列表"],
"rollbackSteps": ["回滚步骤"],
"expectedInsights": "预期能学到什么",
"riskLevel": "LOW/MEDIUM/HIGH",
"estimatedDuration": "预计总时长"
}
""";
}3. 实验执行和观测
@Service
public class ChaosExperimentOrchestrator {
private final ChaosMeshClient chaosMeshClient;
private final MetricsMonitor metricsMonitor;
private final NotificationService notificationService;
public ExperimentResult execute(ChaosExperiment experiment) {
log.info("开始混沌实验: {}", experiment.getName());
ExperimentResult.Builder result = ExperimentResult.builder()
.experimentId(experiment.getId())
.startTime(Instant.now());
try {
// 1. 验证稳态
SteadyStateResult steadyState = verifySteadyState(experiment);
result.steadyStateVerification(steadyState);
if (!steadyState.isHealthy()) {
return result.status(ExperimentStatus.ABORTED_PRE)
.abortReason("实验前系统状态不健康,中止实验")
.build();
}
// 2. 注入故障
FaultInjectionResult injection = injectFault(experiment);
result.faultInjection(injection);
// 3. 持续监控
MonitoringSession monitoring = startMonitoring(experiment);
// 4. 等待故障持续时间
boolean shouldAbort = waitWithAbortCheck(
experiment.getFaultDuration(),
monitoring,
experiment.getAbortConditions()
);
if (shouldAbort) {
result.status(ExperimentStatus.ABORTED_DURING);
result.abortReason("触发中止条件");
}
// 5. 结束故障注入
stopFaultInjection(injection);
// 6. 等待系统恢复
boolean recovered = waitForRecovery(experiment, Duration.ofMinutes(10));
// 7. 收集结果
MonitoringData monitoringData = monitoring.stop();
result.monitoringData(monitoringData);
result.recovered(recovered);
result.status(shouldAbort ? ExperimentStatus.COMPLETED_WITH_ISSUES : ExperimentStatus.COMPLETED);
// 8. 生成实验报告
ExperimentReport report = generateReport(experiment, monitoringData);
result.report(report);
} catch (Exception e) {
log.error("实验执行异常", e);
result.status(ExperimentStatus.FAILED);
result.errorMessage(e.getMessage());
// 确保清理:无论如何都要停止故障注入
cleanupFaultInjection(experiment);
}
ExperimentResult finalResult = result.endTime(Instant.now()).build();
notificationService.notifyExperimentComplete(finalResult);
return finalResult;
}
private boolean waitWithAbortCheck(
Duration duration,
MonitoringSession monitoring,
List<AbortCondition> abortConditions) {
Instant deadline = Instant.now().plus(duration);
while (Instant.now().isBefore(deadline)) {
// 每30秒检查一次中止条件
MonitoringSnapshot snapshot = monitoring.getLatestSnapshot();
for (AbortCondition condition : abortConditions) {
if (condition.isMet(snapshot)) {
log.warn("触发中止条件: {}", condition.getDescription());
return true;
}
}
try { Thread.sleep(30000); } catch (InterruptedException e) { break; }
}
return false;
}
}4. AI辅助结果分析
@Service
public class ChaosResultAnalyzer {
private final ChatClient chatClient;
public ExperimentInsights analyzeResults(
ChaosExperiment experiment,
ExperimentResult result) {
String analysisPrompt = buildAnalysisPrompt(experiment, result);
ChatResponse response = chatClient.call(new Prompt(
List.of(
new SystemMessage("你是一个混沌工程专家,分析实验结果并提炼工程洞察。"),
new UserMessage(analysisPrompt)
)
));
return parseInsights(response.getResult().getOutput().getContent());
}
private String buildAnalysisPrompt(ChaosExperiment experiment, ExperimentResult result) {
return """
分析以下混沌工程实验结果:
实验名称: %s
实验假设: %s
实验观测数据:
- 稳态验证: %s
- 故障期间关键指标变化: %s
- 系统恢复情况: %s
- 是否触发中止条件: %s
成功标准:
%s
请分析:
1. 实验是否验证了假设?系统表现是否符合预期?
2. 发现了哪些之前不知道的系统行为?
3. 有哪些需要改进的地方?给出具体的改进建议
4. 这个实验对系统可靠性的整体评估有什么贡献?
""".formatted(
experiment.getName(),
experiment.getHypothesis(),
result.getSteadyStateVerification().getSummary(),
result.getMonitoringData().getMetricChangeSummary(),
result.isRecovered() ? "完全恢复" : "未完全恢复",
result.getStatus() == ExperimentStatus.ABORTED_DURING ? "是" : "否",
String.join("\n", experiment.getSuccessCriteria())
);
}
}我们用AI混沌工程发现的问题
分享几个真实发现:
发现1:AI分析架构后,指出我们的订单服务调用库存服务时没有超时设置。设计了一个"库存服务延迟增加"的实验,注入500ms延迟。结果:订单接口P99从50ms上升到了3秒,大量超时。修复:加上100ms超时+降级逻辑。
发现2:AI基于历史事故(数据库连接池耗尽)设计了一个"模拟慢查询"实验。实验结果发现:不只是当前服务受影响,上游调用这个服务的所有服务也跟着拖慢了。发现了一个级联依赖没有隔离的架构问题。
