小编所在公司做的项目,大官人说要在项目中添加定时推送短信的功能,每周1推送一次,以便大官人可以不登录系统,知道还有什么紧急事情要处理。so接了任务,就得完成,所以我首先想到了使用定时任务+分布式锁来完成。定时任务定时发送短信,因为是集群部署,到时间点,每个服务器都要发送短信,怎么样只让一台服务器发送短信呢,所以要用到分布式锁,那台服务抢到锁,发送短信的任务就交给它。
背景交代清楚了,开始coding吧
第一步:写个定时任务
@Configuration //1.主要用于标记配置类,兼备Component的效果。
@EnableScheduling // 2.开启定时任务
public class SaticScheduleTask {
//3.添加定时任务
@Scheduled(cron = “0/5 * * * * ?”)
//或直接指定时间间隔,例如:5秒
//@Scheduled(fixedRate=5000)
private void configureTasks() {
System.err.println("执行静态定时任务时间: " + LocalDateTime.now());
}
}
第二步:写个分布式锁,小编使用set+lua脚本的方式,实现分布式锁。
@Slf4j
@RestController
@RequestMapping("/")
public class distributeLock {
@Autowired
private RedisTemplate redisTemplate;
/**
* redis 分布式锁 : set+lua脚本
*/
@RequestMapping(value = "redisLock",method = RequestMethod.GET)
public String RedisLock(){
// key是业务类型名称
String key = "redisKey";
// value是用来校验删除的是否是当前的线程的锁
String value = UUID.randomUUID().toString();
// 被回调函数,声明一个锁,作用是set一个值是否成功
RedisCallback redisCallback = (connection)->{
// nx,如果为false表示设置失败,为true表示该key未被设置过
RedisStringCommands.SetOption setOption = RedisStringCommands.SetOption.ifAbsent();
// 过期时间
Expiration expiration = Expiration.seconds(30);
byte[] keys = redisTemplate.getKeySerializer().serialize(key);
byte[] values = redisTemplate.getValueSerializer().serialize(value);
//set()来实现分布式锁
Boolean result = connection.set(keys, values, expiration, setOption);
return result;
};
// 执行set
Boolean execute = (Boolean)redisTemplate.execute(redisCallback);
if (execute){
// 业务逻辑
log.info("=====我获得了锁,进入了业务逻辑=====");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
// 执行完毕业务之后,释放锁,使用lua脚本
String lu = "if redis.call('get', KEYS[1]) == ARGV[1] \n" +
" then \n" +
"\t return redis.call('del', KEYS[1]) \n" +
"\t else \n" +
"\t return 0 \n" +
"end";
// 执行lua脚本
RedisScript<Boolean> redisScript = RedisScript.of(lu, Boolean.class);
List<String> keyss = Arrays.asList(key);
Boolean bool = (Boolean)redisTemplate.execute(redisScript, keyss,value);
log.info("释放锁的结果:"+bool);
}
}
return null;
}
}
上面是个例子,仅供参考:
核心思想就是:多个服务器抢这把锁,谁抢到谁发送短信
作者:一起写程序