chaos monkey for spring boot (二)

四.源码二

  1. ChaosMonkeyScheduler 

      在ChaosMonkeyConfiguration中,如果要启动定时器,要有taskScheduler这个bean,否则无法启动

   @Bean
    public ChaosMonkeyScheduler scheduler(@Nullable TaskScheduler scheduler, ChaosMonkeyRuntimeScope runtimeScope) {
        ScheduledTaskRegistrar registrar = null;
        if (scheduler != null) {
            registrar = new ScheduledTaskRegistrar();
            registrar.setTaskScheduler(scheduler);
        }
        return new ChaosMonkeyScheduler(registrar, assaultProperties, runtimeScope);
    }
    public ChaosMonkeyScheduler(ScheduledTaskRegistrar scheduler, AssaultProperties config, ChaosMonkeyRuntimeScope runtimeScope) {
        this.scheduler = scheduler;
        this.config = config;
        this.runtimeScope = runtimeScope;

        if (scheduler == null) {
            LOGGER.warn("No ScheduledTaskRegistrar available in application context, scheduler is not functional");
        }

        reloadConfig();
    }

    public void reloadConfig() {
        //获取cron表达式
        String cronExpression = config.getRuntimeAssaultCronExpression();
        boolean active = !"OFF".equals(cronExpression);

        if (currentTask != null) {
            LOGGER.info("Cancelling previous task");
            currentTask.cancel();
            currentTask = null;
        }

        if (active) {
            //如果应用里没有tasksheduler这个bean则抛错
            if (scheduler == null) {
                // We might consider an exception here, since the user intent could clearly not be serviced
                LOGGER.error("No scheduler available in application context, will not process schedule");
            } else {
                //把ChaosMonkeyRuntimeScope下的攻击全部交给定时任务,但是只有两种方式内存和杀死应用两种攻击
                CronTask task = new CronTask(runtimeScope::callChaosMonkey, cronExpression);
                currentTask = scheduler.scheduleCronTask(task);
            }
        }
    }

2.AssaultProperties

public class AssaultProperties implements Serializable {
    @Value("${level : 5}")
    @Min(value = 1)
    @Max(value = 10000)
    //级别,表示概率,比如level为1,那么1/(level+1)的概率
    private int level;

    @Value("${latencyRangeStart : 1000}")
    @Min(value = 1)
    @Max(value = Integer.MAX_VALUE)
    //延迟时间范围起始值
    private int latencyRangeStart;

    @Value("${latencyRangeEnd : 3000}")
    @Min(value = 1)
    @Max(value = Integer.MAX_VALUE)
    //延迟时间范围结束值
    private int latencyRangeEnd;

    @Value("${latencyActive : true}")
    //延迟攻击是否生效
    private boolean latencyActive;

    @Value("${exceptionsActive : false}")
    //异常攻击是否生效
    private boolean exceptionsActive;

    @AssaultExceptionConstraint
    //自定义异常
    private AssaultException exception;

    @Value("${killApplicationActive : false}")
    //是否kill应用
    private boolean killApplicationActive;

    @Value("${memoryActive : false}")
    //内存攻击是否生效
    private volatile boolean memoryActive;

    @Value("${memoryMillisecondsHoldFilledMemory : 90000}")
    @Min(value = 1500)
    @Max(value = Integer.MAX_VALUE)
    //内存攻击持续时间
    private int memoryMillisecondsHoldFilledMemory;

    @Value("${memoryMillisecondsWaitNextIncrease : 1000}")
    @Min(value = 100)
    @Max(value = 30000)
    //每次上升内存间隔时间
    private int memoryMillisecondsWaitNextIncrease;

    @Value("${memoryFillIncrementFraction : 0.15}")
    @DecimalMax("1.0")
    @DecimalMin("0.0")
    //每次上升剩余内存百分比
    private double memoryFillIncrementFraction;

    @Value("${memoryFillTargetFraction : 0.25}")
    @DecimalMax("0.95")
    @DecimalMin("0.05")
    private double memoryFillTargetFraction;

    @Value("${runtime.scope.assault.cron.expression:OFF}")
    //定时任务cron表达式
    private String runtimeAssaultCronExpression;

    @Value("${watchedCustomServices:#{null}}")
    //监听的服务
    private List<String> watchedCustomServices;
}

3.WatcherProperties

public class WatcherProperties implements Serializable {
    //是否对cotroller进行切面
    @Value("${controller:false}")
    private boolean controller;
    //是否对restController进行切面
    @Value("${restController:false}")
    private boolean restController;
    //是否对service进行切面
    @Value("${service:true}")
    private boolean service;
    //是否对repository进行切面
    @Value("${repository:false}")
    private boolean repository;
    //是否对component进行切面
    @Value("${component:false}")
    private boolean component;
}

4.ChaosMonkeyConfiguration

public class ChaosMonkeyConfiguration {
    private static final Logger LOGGER = LoggerFactory.getLogger(ChaosMonkeyConfiguration.class);
    private final ChaosMonkeyProperties chaosMonkeyProperties;
    private final WatcherProperties watcherProperties;
    private final AssaultProperties assaultProperties;

    public ChaosMonkeyConfiguration(ChaosMonkeyProperties chaosMonkeyProperties, WatcherProperties watcherProperties,
                                    AssaultProperties assaultProperties) {
        this.chaosMonkeyProperties = chaosMonkeyProperties;
        this.watcherProperties = watcherProperties;
        this.assaultProperties = assaultProperties;

        try {
            String chaosLogo = StreamUtils.copyToString(new ClassPathResource("chaos-logo.txt").getInputStream(), Charset.defaultCharset());
            LOGGER.info(chaosLogo);
        } catch (IOException e) {
            LOGGER.info("Chaos Monkey - ready to do evil");
        }

    }

    @Bean
    @ConditionalOnClass(name = "io.micrometer.core.instrument.MeterRegistry")
    public Metrics metrics() {
        return new Metrics();
    }


    @Bean
    public MetricEventPublisher publisher() {
        return new MetricEventPublisher();
    }

    @Bean
    //配置ChaosMonkeySettings,所有配置都在这
    public ChaosMonkeySettings settings() {
        return new ChaosMonkeySettings(chaosMonkeyProperties, assaultProperties, watcherProperties);
    }

    @Bean
    //配置延迟攻击bean
    public LatencyAssault latencyAssault() {
        return new LatencyAssault(settings(), publisher());
    }

    @Bean
    //配置异常攻击bean
    public ExceptionAssault exceptionAssault() {
        return new ExceptionAssault(settings(), publisher());
    }

    @Bean
    //配置杀死应用bean
    public KillAppAssault killAppAssault() {
        return new KillAppAssault(settings(), publisher());
    }

    @Bean
    //配置内存攻击bean
    public MemoryAssault memoryAssault() {
        return new MemoryAssault(Runtime.getRuntime(), settings(), publisher());
    }

    @Bean
    //配置请求作用域
    public ChaosMonkeyRequestScope chaosMonkeyRequestScope(List<ChaosMonkeyRequestAssault> chaosMonkeyAssaults, List<ChaosMonkeyAssault> allAssaults) {
        return new ChaosMonkeyRequestScope(settings(), chaosMonkeyAssaults, allAssaults, publisher());
    }

    @Bean
    //定时任务,注意自己注入taskScheduler bean
    public ChaosMonkeyScheduler scheduler(@Nullable TaskScheduler scheduler, ChaosMonkeyRuntimeScope runtimeScope) {
        ScheduledTaskRegistrar registrar = null;
        if (scheduler != null) {
            registrar = new ScheduledTaskRegistrar();
            registrar.setTaskScheduler(scheduler);
        }
        return new ChaosMonkeyScheduler(registrar, assaultProperties, runtimeScope);
    }

    @Bean
    //运行时作用域
    public ChaosMonkeyRuntimeScope chaosMonkeyRuntimeScope(List<ChaosMonkeyRuntimeAssault> chaosMonkeyAssaults) {
        return new ChaosMonkeyRuntimeScope(settings(), chaosMonkeyAssaults);
    }

    @Bean
    @Conditional(AttackControllerCondition.class)
    //配置controller切面
    public SpringControllerAspect controllerAspect(ChaosMonkeyRequestScope chaosMonkeyRequestScope) {
        return new SpringControllerAspect(chaosMonkeyRequestScope, publisher());
    }

    @Bean
    @Conditional(AttackRestControllerCondition.class)
    //配置restController切面
    public SpringRestControllerAspect restControllerAspect(ChaosMonkeyRequestScope chaosMonkeyRequestScope) {
        return new SpringRestControllerAspect(chaosMonkeyRequestScope, publisher());
    }

    @Bean
    @Conditional(AttackServiceCondition.class)
    //配置service切面
    public SpringServiceAspect serviceAspect(ChaosMonkeyRequestScope chaosMonkeyRequestScope) {
        return new SpringServiceAspect(chaosMonkeyRequestScope, publisher());
    }

    @Bean
    @Conditional(AttackComponentCondition.class)
    //配置component切面
    public SpringComponentAspect componentAspect(ChaosMonkeyRequestScope chaosMonkeyRequestScope) {
        return new SpringComponentAspect(chaosMonkeyRequestScope, publisher());
    }

    @Bean
    @Conditional(AttackRepositoryCondition.class)
    //配置respository切面
    public SpringRepositoryAspect repositoryAspect(ChaosMonkeyRequestScope chaosMonkeyRequestScope) {
        return new SpringRepositoryAspect(chaosMonkeyRequestScope, publisher());
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnEnabledEndpoint
    //配置restEndPoint,提供对外web服务
    public ChaosMonkeyRestEndpoint chaosMonkeyRestEndpoint(ChaosMonkeyRuntimeScope runtimeScope, ChaosMonkeyScheduler scheduler) {
        return new ChaosMonkeyRestEndpoint(settings(), runtimeScope, scheduler);
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnEnabledEndpoint
    public ChaosMonkeyJmxEndpoint chaosMonkeyJmxEndpoint() {
        return new ChaosMonkeyJmxEndpoint(settings());
    }

}

五.yml配置

chaos:
  monkey:
    #是否开启混沌工程
    enabled: true
    assaults:
      #攻击级别,表示概率,具体也就是2/(level+1)
      level: 1
      #开启延迟攻击
      latencyActive: true
      #开启异常攻击
      exceptionsActive: true
      #自定义异常
      exception:
        #指定自定义
        type: pl.piomin.services.customer.ZuoqiException
        arguments[0]:
          className: java.lang.String
          value: "这是自定义异常"
      #开启kill应用攻击
      killApplicationActive: true
      #开启定时任务,需要taskSh
      runtime-assault-cron-expression: 5/20 * * * * ?
      #延迟时间范围结束
      latency-range-end: 2000
      #延迟时间范围开始
      latency-range-start: 100
      #开启内存攻击
      memory-active: true
      #内存攻击时剩余内存比例,例如内存攻击前freeMemory为200M,攻击后会剩200*0.2
      memory-fill-increment-fraction: 0.2
      #内存攻击持续时间
      memory-milliseconds-hold-filled-memory: 1500
      #内存攻击每次吃掉的内存比例,例如内存攻击前freeMemory为200M,在达到200*0.2M前,每次吃掉内存
      memory-fill-target-fraction: 0.05
      #内存攻击每次吃掉的内存间隔时间
      memory-milliseconds-wait-next-increase: 100
      #watchedCustomServices: [ "pl.piomin.services.customer.controller.CustomerController.findById"]
  }
    watcher:
      #监控配置
      repository: true
      restController: false
      
management:
  endpoint:
    chaosmonkey:
      enabled: true
  endpoints:
    web:
      exposure:
        include: health,info,chaosmonkey

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值