本文共 1396 字,大约阅读时间需要 4 分钟。
HangFire有个很奇怪的现象,就是即使你设置的循环作业是一天一次,但是每次作业执行很长时间,我们假设是1小时,那么差不多在开始执行之后的30分钟之后,如果还在执行job,系统就会自动帮你重新开启了新的job执行。也就是撇开循环周期的影响,我一个长时间的作业,超过三十分钟的,那么系统又会在你还在执行的时候,三十分钟之后又起一个来帮你执行。
我之前做项目的时候,就遇到这个问题,莫名其妙。开始的时候,我还以为可以像Quartz加个[DisallowConcurrentExecution]了事。
后面找到这个
但是测试了下,不起作用啊。而且一旦启用分布式部署,这个就算有用,到时候不也没用了,后面想想直接来个干脆的,分布式锁。
1、进入job的时候,定义一个key,判断是否正在执行。
string uniqueKey = string.Empty; string key = "xxxxx"; if (!CacheExtension.getInstance().AddUnique($"{key}_unique", 1, DateTimeOffset.Now.AddDays(365))) { LogExtention.getInstance().WriteCustomLogAsync("", "", true, "上批次还未执行结束--xxxxxxjob"); return; } uniqueKey = $"{key}_unique";
2、redis-StringSet保证key是唯一的。
////// 新增,若缓存中已存在相同KEY,则返回false,判断高并发时使用 /// public bool AddUnique(string key, object o, DateTimeOffset expiration, string dependsOnKey = null) { key = AddSysCustomKey(key); var ts = expiration - DateTimeOffset.Now; return _client.StringSet(key, ConvertJson(o), ts, When.NotExists); }
3、执行完成的时候,去掉锁。
try { //todo } finally { CacheExtension.getInstance().Remove(uniqueKey); }
1、这样的话,就能在旧的还未完成之前,新的进来,直接return,保证唯一性,也支持了分布式处理。
2、分布式锁在很多场景,还是很实用的。
转载地址:http://tvudi.baihongyu.com/