コード例 #1
0
        public static void RememberTenant(int tenantId)
        {
            string redisAllTenantIdsSetKey = RedisConfig.TotalUseTimerTenantIds;
            int    systemTenantId          = RedisConfig.UPaasSystemTenantId;

            RedisCacheHelper.SAdd(systemTenantId, redisAllTenantIdsSetKey, tenantId.ToString());
        }
コード例 #2
0
        public static void InitialJobs(string jobAppName)
        {
            string redisAllTenantIdsSetKey = RedisConfig.TotalUseTimerTenantIds;
            int    systemTenantId          = RedisConfig.UPaasSystemTenantId;
            var    members = RedisCacheHelper.SMembers(systemTenantId, redisAllTenantIdsSetKey);

            if (members == null || members.Count == 0)
            {
                return;
            }
            members = members.Distinct().ToList();
            foreach (var member in members)
            {
                if (!member.ToInt().HasValue)
                {
                    continue;
                }
                var    tenantId      = member.ToInt().Value;
                string redisKey      = MakeRedisKey(tenantId, jobAppName);
                var    redisContents = RedisCacheHelper.GetHRedis(tenantId, redisKey);
                foreach (var kv in redisContents)
                {
                    var infos = GetJobValue(kv.Value);
                    if (infos == null || infos.Item2 < DateTime.Now)
                    {
                        RedisCacheHelper.DelHRedis(tenantId, redisKey, kv.Key);
                        continue;
                    }
                    //将redis的数据加载到服务器内存
                    AddJob(new JobArgs()
                    {
                        TenantId   = tenantId,
                        OperatorId = infos.Item1,
                        JobKey     = kv.Key,
                        RunTime    = infos.Item2,
                        Job        = infos.Item3,
                        JobAppName = jobAppName
                    }, true);
                }
            }
        }
コード例 #3
0
        public static bool AddJob(JobArgs args, bool fromRedis = false)
        {
            ArgumentHelper.AssertValuesPositive(args.TenantId);
            ArgumentHelper.AssertNotNullOrEmpty(args.JobKey);
            ArgumentHelper.AssertNotNullOrEmpty(args.JobAppName);
            ArgumentHelper.AssertNotNull(args.Job, "job must not null");

            string redisKey     = MakeRedisKey(args.TenantId, args.JobAppName);
            string redisLockKey = MakeLockKey(args.TenantId, args.JobKey, args.JobAppName);

            //不是从redis加载的需要保存到redis,如果是从redis加载则不用再回写了
            if (!fromRedis)
            {
                string redisJobValue = MakeJobValue(args.OperatorId, args.RunTime, args.Job);
                RedisCacheHelper.SetHRedis(args.TenantId, redisKey, args.JobKey, redisJobValue);
            }

            JobManager.AddJob(
                () =>
            {
                //加分布式锁
                //获取Key 对应的Value。
                //拆Value,获取Runtime
                //比较runtime,如果在允许的时间差范围内,则执行。否则,return
                //执行完,删掉jobKey
                //释放分布式锁
                ApplicationContext.Current.TenantId        = args.TenantId;
                ApplicationContext.Current.UserId          = args.OperatorId;
                ApplicationContext.Current.ApplicationName = args.JobAppName;
                var lockRes = DistributeRedisLock.TryLock(args.TenantId, redisLockKey, "", args.LimitSeconds);
                if (!lockRes)
                {
                    LogHelper.Instance.Debug($"定时任务未执行,加锁失败。LockKey:{redisLockKey},JobKey:{args.JobKey}");
                    return;
                }
                try
                {
                    var jobValue = RedisCacheHelper.GetHRedis(args.TenantId, redisKey, args.JobKey);
                    if (string.IsNullOrEmpty(jobValue))
                    {
                        LogHelper.Instance.Debug($"定时任务未执行,Key不存在。{args.JobKey}");
                        return;
                    }
                    var jobInfo = GetJobValue(jobValue);
                    if (jobInfo == null)
                    {
                        LogHelper.Instance.Debug($"定时任务未执行,JobInfo为空。JobKey:{args.JobKey}, JobValue:{jobValue}");
                        return;
                    }
                    //比如,一个Job的实际执行时间是12:00:00,Redis里存的是12:00:00,实际FluentScheduler也是12:00:00触发执行的。
                    //但是执行到比较时间这块,可能是12:00:05了(可能要排队、或者性能问题等),导致时间不匹配。因此,我们允许时间出现轻微误差
                    //但是,如果时间间隔超过该轻微误差(1分钟),则认为时间不匹配
                    if (Math.Abs((jobInfo.Item2 - DateTime.Now).TotalSeconds) >= 60)
                    {
                        LogHelper.Instance.Debug($"定时任务未执行,时间不匹配。JobKey:{args.JobKey}, JobValue:{jobValue}");
                        return;
                    }
                    args.Job.Execute();
                    RedisCacheHelper.DelHRedis(args.TenantId, redisKey, args.JobKey);
                    LogHelper.Instance.Debug($"执行定时任务成功。JobKey:{args.JobKey},JobValue{jobValue}");
                }
                catch (Exception ex)
                {
                    LogHelper.Instance.Error($"执行定时任务异常。JobKey:{args.JobKey},EX:{ex.Message}");
                }
                finally
                {
                    DistributeRedisLock.UnLock(args.TenantId, redisLockKey, "");
                }
            },
                (schedule) =>
            {
                RememberTenant(args.TenantId);
                schedule.WithName(args.JobKey).ToRunOnceAt(args.RunTime);
            });
            return(true);
        }
コード例 #4
0
        public static bool DeleteJob(int tenantId, string jobKey, string jobAppName)
        {
            string redisKey = MakeRedisKey(tenantId, jobAppName);

            return(RedisCacheHelper.DelHRedis(tenantId, redisKey, jobKey) > 0);
        }