You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot中Chaos Monkey测试数据库重试失效问题及替代方案咨询

问题描述

我在微服务中实现了数据库记录保存时的重试机制(通过@Retryable注解配置,针对SQLException,最大重试3次,间隔1秒),该机制已正常工作。但我希望在不关闭数据库的测试环境中验证它,因此引入了Chaos Monkey。

相关代码与配置

DemoService类代码

public class DemoService {

    @Autowired
    private DemoRepo demoRepo;
    static private int i=0;

    @Retryable(value={SQLException.class},maxAttempts = 3, backoff = @Backoff(delay = 1000))
    public Demo save(Demo demo){
        log.info("Retry is working"+(i+1));
       return demoRepo.save(demo);
    }
}

application.yml配置文件

spring:
  jpa:
    hibernate:
      ddl-auto: update
  datasource:
    url: jdbc:mysql://localhost:3306/chaostest
    username: root
    password: 1234
    driver-class-name: com.mysql.cj.jdbc.Driver
  profiles:
    active: chaos-monkey

chaos:
  monkey:
    enabled: true
    assaults:
      exceptionsActive: true
      exception:
        type: java.sql.SQLException
      level: 5
    watcher:
      demoRepo: true

logging:
  level:
    de:
      codecentric:
        spring:
          boot:
            chaos:
              monkey: DEBUG

当前问题:Chaos Monkey并未触发数据库异常,事务首次执行就直接成功,无法验证重试机制是否正常工作。咨询以下两点:

  1. 需要修改哪些配置或代码才能让Chaos Monkey正常生效?
  2. 有无无需关闭数据库的其他测试方法?

解决方案

1. 调整Chaos Monkey配置与代码使其生效

  • 修正Watcher配置:Chaos Monkey针对Spring Data Repository的监听,建议显式开启repositories类型的Watcher,确保能识别到Repo Bean。修改配置:
    chaos:
      monkey:
        watcher:
          repositories: true
          demoRepo: true
    
  • 调高异常触发概率:当前level:5仅5%的触发概率,测试阶段建议改为level:100(100%触发),确保每次调用都能抛出异常,验证完成后再调回:
    chaos:
      monkey:
        assaults:
          level: 100
    
  • 匹配实际抛出的异常类型:Hibernate会将SQLException包装为PersistenceException,导致@Retryable无法捕获。可以同步调整两处:
    • 修改@Retryable的异常范围:@Retryable(value={SQLException.class, PersistenceException.class})
    • 让Chaos Monkey抛出PersistenceException:
      chaos:
        monkey:
          assaults:
            exception:
              type: javax.persistence.PersistenceException
      
  • 确认代理与依赖兼容性:检查Spring Boot与Chaos Monkey版本是否匹配(比如Spring Boot 3.x对应Chaos Monkey 2.x),同时确保DemoRepo是被Spring正确代理的Bean,通过DEBUG日志查看Chaos Monkey是否成功注册了对该Bean的监听。

2. 无需关闭数据库的其他测试方法

  • Mock数据层抛出异常:在单元/集成测试中用Mockito模拟Repo行为,强制抛出异常验证重试逻辑,示例:
    @SpringBootTest
    @EnableRetry
    class DemoServiceTest {
    
        @MockBean
        private DemoRepo demoRepo;
    
        @Autowired
        private DemoService demoService;
    
        @Test
        void testSaveRetry() {
            // 模拟前两次抛异常,第三次返回成功结果
            when(demoRepo.save(any(Demo.class)))
                .thenThrow(new SQLException("Mock DB error"))
                .thenThrow(new SQLException("Mock DB error"))
                .thenReturn(new Demo());
    
            Demo result = demoService.save(new Demo());
    
            // 验证save方法被调用3次
            verify(demoRepo, times(3)).save(any(Demo.class));
            assertNotNull(result);
        }
    }
    
  • 自定义AOP切面注入异常:编写Spring AOP切面,在DemoRepo.save方法执行时手动抛出SQLException,通过开关控制是否触发,灵活测试重试逻辑。
  • 数据库主动触发故障:用MySQL的KILL CONNECTION命令,在测试时主动断开当前连接,模拟数据库异常;或借助Testcontainers启动临时数据库容器,通过网络工具模拟网络中断。

内容的提问来源于stack exchange,提问作者Rashmi Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 16:33:27