基于数据库实现配置管理和定时任务启停

发布于:2025-06-14 ⋅ 阅读:(19) ⋅ 点赞:(0)

1、背景

项目中,定时任务的控制,常常通过配置文件中的开关,但如果定时任务很多,配置文件维护就很烦,且要考虑配置热部署的问题

2、实现思路

上一篇提到了一些启停任务的实现思路:

  • 修改定时表达式为"-"
  • 条件控制定时任务所在类的Bean加载
  • 自定义启停接口等等

不管哪种,核心思路可以用下面这段代码表示:

@Service
@Slf4j
public class SchedulerService {

    @Value("${enable.scheduler}")
    private boolean enableScheduler;

    @Scheduled(cron = "0/5 * * * * ?")
    public void schedulerTask1() {
        if (enableScheduler) {
            log.info("task 1 begin to run");
        }
    }
}

3、基于数据库实现

考虑引入一张全局配置的数据库表,结构如下:

CREATE TABLE `global_config` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `t_key` varchar(64) NOT NULL,
  `t_value` varchar(64) NOT NULL,
  `addTimeStamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `modTimeStamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `global_config_unique` (`t_key`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

在这里插入图片描述

写一个服务,用于获取每一项的配置:

@Service
@Slf4j
public class ConfigManager {
	
    private final GlobalConfigMapper configMapper;

    public ConfigManager(GlobalConfigMapper globalConfigMapper) {
        this.configMapper = globalConfigMapper;
    }

    public String getValue(String key) {
        if (StringUtils.isBlank(key)) {
            return null;
        }
        Example example = new Example(GlobalConfig.class);
        example.createCriteria().andEqualTo("key", key);
        GlobalConfig result = configMapper.selectOneByExample(example);
        return result != null ? result.getValue() : "";
    }

	// 查询对应配置的key,查不到则返回传入的默认值 
    public boolean getBoolean(String key, boolean defaultValue) {
        String value = getValue(key);
        if (StringUtils.isBlank(value)) {
            return defaultValue;
        }
		// 转boolean
        return value.equalsIgnoreCase("1") || value.equalsIgnoreCase("true");
    }

    public boolean isBillingEnabled() {
        return getBoolean("billing-enabled", false);
    }
}

由此,定时任务可以写成:

@Service
@Slf4j
public class SchedulerService {

    @Scheduled(cron = "0/5 * * * * ?")
    public void schedulerTask1() {
    	if (!configManager.isBillingEnabled()) {
            log.warn("task1 switch disabled, skip");
            return;
        }
        log.info("task 1 begin to run");
    }
}

每次执行定时任务,都是现查的配置,这个就非常可控了

4、总结

基于数据库表,来分担一部分配置文件的实现方式,有些场景下非常适用,当然,配置很多的话,也可以考虑给表结构加一个分类字段,不同业务不同的type值,同一个type下有多个key-value键值对


网站公告

今日签到

点亮在社区的每一天
去签到