Giter Site home page Giter Site logo

2881099 / freescheduler Goto Github PK

View Code? Open in Web Editor NEW
269.0 6.0 42.0 4.05 MB

轻量化定时任务调度,支持集群、临时的延时任务和重复循环任务(可持久化),可按秒,每天/每周/每月固定时间,自定义间隔执行,支持 .NET Core 2.1+、.NET Framework 4.0+ 运行环境。

C# 15.85% HTML 11.24% JavaScript 64.99% CSS 7.93%
freescheduler fluentscheduler hashedwheeltimer quartz

freescheduler's Introduction

FreeScheduler 是利用 IdleBus 实现的轻量化定时任务调度,支持集群、临时的延时任务和重复循环任务(可持久化),可按秒,每天/每周/每月固定时间,自定义间隔执行,支持 .NET Core 2.1+、.NET Framework 4.0+ 运行环境。

IdleScheduler 已正式改名为 FreeScheduler

如果对本项目感兴趣,欢迎加入 FreeSql QQ讨论群:8578575

Quick start

dotnet add package FreeScheduler

Install-Package FreeScheduler

static Scheduler scheduler = new FreeSchedulerBuilder()
    .OnExecuting(task =>
    {
        Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss.fff")}] {task.Topic} 被执行");
        switch (task.Topic)
        {
            case "武林大会": Wulin(task.Body); break;
            case "攻城活动": AttackCity(task.Body); break;
        }
    })
    .Build();
Method 说明
OnExecuting(Action<TaskInfo> executing) 任务触发
UseTimeZone() 设置时区
UseStorage() 基于 数据库或者 Redis 持久化
UseCluster() 开启集群(依赖 Redis),支持跨进程互通
UseCustomInterval() 自定义间隔(可实现 cron)
UseScanInterval() 扫描间隔(默认200ms),值越小触发精准
Build() 创建 Scheduler 对象

使用 ASP.NET Core 项目,一行代码解决如下:

app.UseFreeSchedulerUI("/freescheduler/");

image

集群特性

  • 支持 单项目,多站点部署
  • 支持 多进程,不重复执行
  • 支持 进程退出后,由其他进程重新加载任务(约30秒后)
  • 支持 进程互通,任意进程都可以执行(RemoveTask/ExistsTask/PauseTask/RunNowTask/RemoveTempTask/ExistsTempTask)
  • 支持 进程意外离线后,卸载进程内的任务,重新安排上线

1、临时任务(不可持久化)

void Callback()
{
    Console.WriteLine("时间到了");
    scheduler.AddTempTask(TimeSpan.FromSeconds(10), Callback); //下一次定时
}
scheduler.AddTempTask(TimeSpan.FromSeconds(10), Callback);
Method 说明
string AddTempTask(TimeSpan, Action) 创建临时的延时任务,返回 id
bool RemoveTempTask(string id) 删除任务(临时任务)
bool ExistsTempTask(string id) 判断任务是否存在(临时任务)
int QuantityTempTask 任务数量(临时任务)

2、循环任务/可持久化

//每5秒触发,执行N次
var id = scheduler.AddTask("topic1", "body1", round: -1, 5);

//每次 不同的间隔秒数触发,执行6次
var id = scheduler.AddTask("topic1", "body1", new [] { 5, 5, 10, 10, 60, 60 });

//每天 20:00:00 触发,执行N次(注意设置时区 UseTimeZone)
var id = scheduler.AddTaskRunOnDay("topic1", "body1", round: -1, "20:00:00");

//每周一 20:00:00 触发,执行1次
var id = scheduler.AddTaskRunOnWeek("topic1", "body1", round: 1, "1:20:00:00");

//每月1日 20:00:00 触发,执行12次
var id = scheduler.AddTaskRunOnMonth("topic1", "body1", round: 12, "1:20:00:00");
//每月最后一日 20:00:00 触发,执行12次
var id = scheduler.AddTaskRunOnMonth("topic1", "body1", round: 12, "-1:20:00:00");

//自定义间隔 cron
var id = scheduler.AddTaskCustom("topic1", "body1", "0/1 * * * * ? ");
new FreeSchedulerBuilder()
    ...
    .UseCustomInterval(task =>
    {
        //利用 cron 功能库解析 task.IntervalArgument 得到下一次执行时间
        //与当前时间相减,得到 TimeSpan,若返回 null 则任务完成
        return TimeSpan.FromSeconds(5);
    })
    .Build();
Method 说明
void ctor(ITaskHandler) 指定任务调度器(单例)
string AddTask(string topic, string body, int round, int seconds) 创建循环定时任务,返回 id
string AddTask(string topic, string body, int[] seconds) 创建每轮间隔不同的定时任务,返回 id
string AddTaskRunOnDay(..) 创建每日循环任务,返回 id
string AddTaskRunOnWeek(..) 创建每周循环任务,返回 id
string AddTaskRunOnMonth(..) 创建每月循环任务,返回 id
string AddTaskCustom(string topic, string body, string expression) 创建自定义任务,返回 id
bool RemoveTask(string id) 删除任务
bool ExistsTask(string id) 判断任务是否存在
bool ResumeTask(string id) 恢复已暂停的任务
bool PauseTask(string id) 暂停正在运行的任务
bool RunNowTask(string id) 立刻运行任务(人工触发)
TaskInfo[] FindTask(lambda) 查询正在运行中的任务
int QuantityTask 任务数量

3、预留任务

[系统预留]清理任务数据

//每小时触发,定期清理24小时之前的数据(单位:秒)
scheduler.AddTask("[系统预留]清理任务数据", "86400", round: -1, 3600);

4、管理任务

// 使用 FreeSql 或者 SQL 查询 TaskInfo、TaskLog 两个表进行分页显示
fsql.Select<TaskInfo>().Count(out var total).Page(pageNumber, 30).ToList();
fsql.Select<TaskLog>().Count(out var total).Page(pageNumber, 30).ToList();

//暂停任务
scheduler.PauseTask(id);
//恢复暂停的任务
scheduler.ResumeTask(id);
//删除任务
scheduler.RemoveTask(id);
//立刻运行任务(人工触发)
scheduler.RunNowTask(id);

如果正在使用 ASP.NET Core 项目,一行代码解决如下:

app.UseFreeSchedulerUI("/freescheduler/");

https://github.com/2881099/FreeScheduler/tree/master/Examples/Examples_FreeScheduler_Net60 image

Performance

FreeScheduler Quartz.net FluentScheduler HashedWheelTimer
(500,000 Tasks + 10s) (500,000 Tasks + 10s) (500,000 Tasks + 10s) (500,000 Tasks + 10s)
383M 1700+M StackOverflow 213M
70563.6066ms 50692.5365ms 未知 33697.8758ms

FluentScheduler 单个 Registry 测试正常,但目测单线程执行(间隔1-10ms),处理速度不理想 View Code

我尝试把 FreeScheduler 内核改成 HashedWheelTimer 内存占用更高(600兆),结论:FreeScheduler 功能需要占用更多资源

💕 Donation (捐赠)

感谢你的打赏

🗄 License (许可证)

MIT

freescheduler's People

Contributors

2881099 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

freescheduler's Issues

scheduler.RemoveTask报错

执行报错:ERR wrong number of arguments for 'hdel' command,先用ExistsTask判断了任务存在,然后调用的删除任务,是一个循环任务,持久化用的FreeRedis

任务分组功能

关于任务分组功能,不知道如何扩展实现。或是能不能计划在下一个版本中加入?
为每个任务分配一个分组标识。任务初始化和起动时,只初始化和起动对应分组的标识的任务。
这样在任务特别多时,就可以用多个服务器根据分组进行分摊运行。有点像分布式?

在没有这功能前,我是想把标识写在 task.body里。
但不知道下面这个初始化,如何只查询调用 task.body 包含特别标识的任务。
_scheduler = new Scheduler(new MyTaskHandler(_fsql), new MyCustomTaskHandler());

_scheduler 找回

我是用FreeScheduler 做一个硬件信息的采集任务。
.net web 页面执行后,开始任务_scheduler,关了页面任务还是在执行,这很好,可是如果我改动了页面代码,重新上传到服务器。
这时:_scheduler 已经为null 了。 但网站的任务_scheduler还在线程里运行。
我如何在不重新IIS的情况下,中止或操作运行中的其中一个任务。这感谢是一个编程的问题,如果你知道,还请帮忙指导一下。

Feature Request AHeadTask Api Need

添加 scheduler.AHeadTask Api
就是让一个Task下次触发任务提前执行。然后其他不变。

如果可以,给这个API加个bool 参数。是否修改计时器(true/false).
是-立即执行后,变成等10分钟。
否-相当于,当前插入一个执行。下次执行还是等5分钟。

例如:
Task 每次10分钟执行一次。
当前时间距离下次执行还有5分钟。
现在要对其进行干预,跳过这5分钟,立即执行任务。
执行后下次执行就还是等10分钟。

OnExecuted 是不是无法重写

public void OnExecuted(Scheduler scheduler, TaskInfo task, TaskLog result)
{
_fsql.Transaction(() =>
{
_fsql.Update().NoneParameter().SetSource(task)
.UpdateColumns(a => new { a.CurrentRound, a.ErrorTimes, a.LastRunTime, a.Status })
.ExecuteAffrows();
_fsql.Insert().NoneParameter().AppendData(result).ExecuteAffrows();
});
}

是否可以支持Crontab

您好,我的想法是在webapi项目中定时执行一个函数用于刷新Token,想把执行任务以Crontab的方式放在appsetting.json中,应用启动时读取配置后就开始按指定频率执行,这个好像也不算临时任务,也不算持久化任务,这种可以实现吗?

结合freesql使用时idle出现连接数过多的情况

环境.net6 + PostgreSQL 12.12, compiled by Visual C++ build 1914, 64-bit

每次执行时idle都会增加占用连接,并且没有释放持续增加
一定时间后就会出现连接数过多异常:【主库】Next recovery time

image

常见问题

任务不触发

FreeScheduler 默认是串行任务设计,最多支持30个任务同时触发,超出这个量要排队触发

耗时较高的任务,避免长时间占用触发队列,可在 OnExecuting 内使用 Task.Run(() => { ... }) 的方式执行

造成的问题:上一次任务还未执行完(耗时较久的任务),下一次任务又触发了,应加大定时间隔

AddTaskCustom必须自己实现CustomHandler吗

image

NextDelay的具体实现可以给个demo吗?
另外,实现的MyCustomTaskHandler,可以同时实现 ITaskIntervalCustomHandler、FreeSqlHandler吗?分开实现有什么优势吗?

支持串行执行吗?

比如我一个任务执行1分钟,但是调度间隔是20秒,可以等待上一个任务执行完成不啊?

根据Topic 查询指定任务

根据Topic 查询指定任务.
有的时候经常要对指定的任务进行干预操作.
而id一般都是系统自动生成的,没有意义.
因此能够根据Topic操作任务也就变的至关重要.

FreeScheduler v2.0.18 - 在界面增加任务后的潜在重复执行问题;

在界面上添加任务之后,返回到列表,这个时候其实已经默认已经执行了,而在列表中(如果任务还没有运行完毕)则会出现一个立即执行按钮,这是不需要的,因为会造成重复执行;
解决方案一:
把这个列表中的立即执行按钮删掉
解决方案二:
在添加任务界面做两个按钮,一个立即执行,一个手动执行。如果用户点击立即执行,则列表中不需要立即执行按钮;如果用户点击手动执行,则列表中可以有立即执行按钮

来给叶老板增加强度

1,支持分布式调度,在不同的机器中运行着处理机客户端系统;

2,各处理机客户端之间,如何分割任务及子任务的大小,使并行度很高,辅助开销比较小;

3,如何协调好并行执行的任务和进程间同步问题,负载均衡;

4,将各个任务分配到一个或多个处理机上,解决好任务调度,处理机调度和资源分配问题。

5,一旦某个客户端处理机发生故障,如何应对系统进行组织,不使瘫痪;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.