zoukankan      html  css  js  c++  java
  • ScheduleMaster新特性之延时任务初体验

    ScheduleMaster在上个月底更新到了2.0版本,在功能和代码以及文档上都往前跨了很大一步,详细信息可以参考这篇文章:https://www.cnblogs.com/hohoa/p/12772945.html

    对ScheduleMaster还不熟悉的朋友可以先移步作者的系列文章:https://www.cnblogs.com/hohoa/category/1628282.html

    这次的更新点主要包含:

    • 开发了延时任务功能。

    • 抽象出分布式锁服务并默认数据库实现。

    • 补充了单元测试。

    • 补充了几篇文档。

    • 修复了已知的bug。

    其中的重头戏自然是延时任务功能,所谓的延时任务就是在指定时刻执行指定逻辑,这在平时需求开发中是非常常见的,作为一款功能齐全的调度系统这当然也是必备的功能。

    关于延时任务的实现原理我早期写过一篇文章《采用简易的环形延时队列处理秒级定时任务的解决方案》来介绍,ScheduleMaster也是在这个基础上改进而来。

    当然了,其他的实现方式也还有很多,主流的实现方案可以参考下面这篇文章,整理的比较齐全:https://www.cnblogs.com/vipstone/p/12696465.html

    我采用的就是比较经典的时间轮算法,原理就不再重复介绍了可以移步到我前面的文章,下面看看实现效果。


    实现了什么效果

    我们先通过一段测试代码看看延时队列的运行情况:

     [Fact]
     public void Run()
     {
         //初始化容器
         DelayPlanManager.Init();
         Debug.WriteLine($"延时队列初始化完成时间:{DateTime.Now}");
    
         Func<DelayQueueSlot, Task> callback = (result) =>
          {
              var np = result as NotifyPlan;
              //模拟业务
              Debug.WriteLine($"[{DateTime.Now}]ID:{np.Key},地址:{np.NotifyUrl},延迟秒数:{np.TimeSpan}");
    
              return Task.CompletedTask;
          };
    
         //模拟生产端写入任务
         Task[] tasks = new Task[10];
         for (int i = 0; i < 10; i++)
         {
             tasks[i] = new Task(() =>
             {
                 for (int k = 0; k < 200; k++)
                 {
                     int rndNum = new Random().Next(20, 500);
                     DelayPlanManager.Insert(new NotifyPlan
                     {
                         NotifyUrl = "http://localhost:56655/api/1.0/value/delaypost",
                         Key = Guid.NewGuid().ToString(),
                         Callback = callback
                     }, DateTime.Now.AddSeconds(rndNum));
                 }
             }, TaskCreationOptions.LongRunning);
             tasks[i].Start();
         }
         Task.WaitAll(tasks);
    
         //构造消费者
         while (true)
         {
            DelayPlanManager.Read();
            System.Threading.Thread.Sleep(1000);
         }
     }
    

    代码中创建了2000个延时任务,延时范围在20秒至500秒,所以我们预测在程序启动后最快20秒就开始有信息输出,程序调式结果为:

    当一个周期执行完后刚好过了1分钟:

    分秒不差。


    先睹为快

    再看看在项目中的实际应用。

    控制台创建任务页面:

    不过实际使用中通过API方式创建显然更符合需求,所以一如既往地提供了开放API供业务系统接入,详细使用方式参考官方文档【使用API接入任务】。

    系统提供了2种延迟模式供选择,即相对时间绝对时间,可以在系统参数中配置,默认是使用相对时间。但使用相对时间模式有一点要注意,各节点间可能存在系统时间差导致任务被多次执行,所以业务做好幂等性控制至关重要。

    延时任务管理页面:

    这里解释下任务的各个状态

    • 已作废,表示已经从执行计划移除

    • 已创建,表示刚创建好还没有加入执行计划

    • 已就绪,表示已加入到执行计划中等待执行

    • 已完成,表示执行成功

    • 异常,表示执行失败

    继续看一下任务运行情况。

    单节点执行成功:

    异常重试效果:

    可用的参数配置:

    更多好玩的东西欢迎下载体验~


    写在最后

    喜欢的朋友请来一波star支持,并持续关注~~

    传送门:

  • 相关阅读:
    关于oracle的相关基础语句
    devexpress中如何给TabPage控件的Tab定义背景色
    asp.net中当点击按钮时出现grid编辑弹框
    DEV中dx:ASPxPopupControl 控件的使用(在窗口关闭或隐藏时,清楚文本框中的内容)
    aspx中如何绑定llistbox数据列表
    asp.net中选择数字时,另外的数字同时发生变化(适用dev控件)
    js中substring和substr的用法(文章来自bobo327的博客园)
    QT中常用控键
    sqlite常用语句
    计算机视觉-基于内容的图像检索
  • 原文地址:https://www.cnblogs.com/hohoa/p/12912774.html
Copyright © 2011-2022 走看看