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键值对