DotNetCore跨平台~Quartz热部署的福音~监控文件夹的变化

在DotNetCore出来之后,同时也使用了quartz进行调度中心的设计,将它做到docker里方便部署,在之前的quartz版本里支持配置文件的方式,而现在不支持了,我们应该去想一下,为什么不去支持配置文件?当然大叔也为配置文件设计了支持的方式,但我们还是应该想想作者为什么不去支持配置?

热插拔,服务发现?

和上面两个概念可能有点关系,热插拔很容易理解,就是把dll模块放到正在运行的项目时,它可以直接启动,这个功能对调度中心来说,很是必要,因为你可能需要按着不同的功能设计一些服务job,而这些服务没有什么联系,每个job功能单一,如果做成热部署,挺好!而服务发现在最近<微服务>里很是枪眼,今天说的服务发现并不是它,而是dotnet core公开的对文件夹的监控,其实就是一种事件机制,当windows底层文件夹改变时(增,删,改文件),会向上触发对应的事件,而我们只要去订阅它即可,非常的松耦合!

公开的事件

       var watcher = new FileSystemWatcher();
            watcher.Path = AppDomain.CurrentDomain.BaseDirectory;
            watcher.NotifyFilter = NotifyFilters.Attributes |
                                   NotifyFilters.CreationTime |
                                   NotifyFilters.DirectoryName |
                                   NotifyFilters.FileName |
                                   NotifyFilters.LastAccess |
                                   NotifyFilters.LastWrite |
                                   NotifyFilters.Security |
                                   NotifyFilters.Size;
            watcher.Filter = "*.dll";
            // quartz运行时,可以添加新job,但不能覆盖,删除等
            watcher.Created += new FileSystemEventHandler((o, e) =>
            {
                foreach (var module in Assembly.LoadFile(e.FullPath).GetModules())
                {
                    foreach (var type in module.GetTypes().Where(i => i.BaseType == typeof(JobBase)))
                    {
                        JoinToQuartz(type);
                    }
                }
            });

            //Start monitoring.
            watcher.EnableRaisingEvents = true;

将job添加到Quartz需要在初始化和文件夹监控两个地方用到,所以我们进行了抽象,把它提到一个委托里,使用.net4.0的Actioin<T>委托来实现最为合适了!

          Action<Type> JoinToQuartz = (type) =>
            {
                var obj = Activator.CreateInstance(type);
                string cron = type.GetProperty("Cron").GetValue(obj).ToString();
                var jobDetail = JobBuilder.Create(type)
                                          .WithIdentity(type.Name)
                                          .Build();

                var jobTrigger = TriggerBuilder.Create()
                                               .WithIdentity(type.Name + "Trigger")
                                               .StartNow()
                                               .WithCronSchedule(cron)
                                               .Build();

                StdSchedulerFactory.GetDefaultScheduler().Result.ScheduleJob(jobDetail, jobTrigger);
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine($"新添加了一个服务{nameof(type)},通过心跳Job自动被加载!");
            };

大叔把它应用到了调度中心上,具体就是当调试项目里有新的模块DLL出现后,自动将它添加到quartz的列表里,然后当然它有自己的cron表达式去控制自己的调度周期,你是定点地还是周期运行完成由自己的job去控制,如果有新功能,就加新Job,是否有点单一职责和开闭原则的意思!

JobBase,所有模块的功能Job都要继承它,可以根据自己的情况,实现cron和业务ExcuteJob方法!

  [DisallowConcurrentExecution()]
    public abstract class JobBase : IJob
    {

        #region IJob 成员

        public Task Execute(IJobExecutionContext context)
        {
            try
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(DateTime.Now.ToString() + "{0}这个Job开始执行", context.JobDetail.Key.Name);
                ExcuteJob(context);
                return Task.CompletedTask; ;
            }
            catch (Exception ex)
            {
                LoggerFactory.CreateLog().Logger_Debug(this.GetType().Name + "error:" + ex.Message);
                throw;
            }
        }

        #endregion
        /// <summary>
        /// 执行计划,子类可以重写
        /// </summary>
        public virtual string Cron => "0/5 * * * * ?";
        /// <summary>
        /// Job具体类去实现自己的逻辑
        /// </summary>
        protected abstract void ExcuteJob(IJobExecutionContext context);

    }

下面看其中一个业务Job的实现,它主要由调度计划cron和业务执行方法ExcuteJob组成

   /// <summary>
    /// 发送消息
    /// </summary>
    public class SendEmailJob : JobBase
    {
        public override string Cron => "0/2 * * * * ?";

        protected override void ExcuteJob(IJobExecutionContext context)
        {
            Console.WriteLine("发送Email");
            LoggerFactory.CreateLog().Logger_Debug("发送Email:" + DateTime.Now);
        }
    }

当我们把这个项目发布到dotnet core之后,可以设计一个web api /web mvc管理UI,然后去查看和管理自己的任务,现在quartz2.x里的crystal管理工具已经用不了了,所以咱们还是DIY一下吧!哈哈!

可以查看任务列表,管理它们的启动与停止的状态!

感谢各位的阅读!

本文转自博客园张占岭(仓储大叔)的博客,原文链接:DotNetCore跨平台~Quartz热部署的福音~监控文件夹的变化,如需转载请自行联系原博主。

时间: 2024-10-11 02:07:21

DotNetCore跨平台~Quartz热部署的福音~监控文件夹的变化的相关文章

DotNetCore跨平台~Quartz定时单次任务

之前写过一篇文件<DotNetCore跨平台~Quartz热部署的福音-监控文件夹的变化>,今天主要把框架优化了一下,支持外部触发,并支持外部将参数以JobDataMap形式进行输入,然后在咱们的Job里进行使用它,故称参数化任务. Quartz使用场景: 定时单次任务:在未来某个时间去执行一次 定点任务 :在某个时间去执行,可以是轮询的 周期任务 :按某个时间间隔去轮询执行 今天说的外部触发的任务是指第一种,即在未来某个时间点去执行,并且只执行一次.说一下思路,这种任务某个JobBase的子

DotNetCore跨平台~System.DrawingCore部署Linux需要注意的

你在windows上使用图像组件没有任务问题,但部署到linux之后,将注意以下几点: 安装nuget包ZKWeb.System.Drawing 项目里还是引用System.DrawingCore,这点不用改 安装gdiplus插件,这个需要根据linux类型不同,有不同的方法,大叔做了一下总结 安装gdiplugs的方法 大叔总结的方法ubuntu && debian sudo apt-get install libgdiplus cd /usr/lib sudo ln -s libgd

PowerShell脚本监控文件夹变化实例_PowerShell

本文介绍使用PowerShell来监视一个指定的文件夹,包括新建文件.删除文件.重命名文件等操作均会被监控或监视.本文使用了System.IO.FileSystemWatcher这个.NET对象.首先,我们来看看程序: 复制代码 代码如下: # 定义要监控的文件夹,这个文件夹必须先存在. $folder = 'D:\test' # 定义每次监控的间隔时间,这时定义为1000毫秒,即1秒 $timeout = 1000 # 创建文件系统监视对象 $FileSystemWatcher = New-O

项目部署后,某个文件夹下文件不能访问,报错:JSPG0036E: 找不到资源 /info.jsp

问题描述 各位大虾:近期调试一个小东东,在WSAD中一切安好,但是打包发布到WAS上后,有一个文件夹下面的页面,无法访问,报错:JSPG0036E:找不到资源/index.jsp其中index.jsp是info文件夹下的一个页面,从这个页面再去访问其他的同目录下的jsp文件.可是访问其他文件夹(跟info文件夹同级)下的jsp文件就可以,不知道为什么.自己在网上查了一下,有大虾说可能跟plugin-cfg.xml文件有关,我打开了HTTPServer跟AppServer下的两个文件,都有如下代码

DotNetCore跨平台~文章索引~永久更新

本索引目录主要包括仓储大叔对dotnet core架构的研究与知识积累,从2016年开始进行撰写,到今天已经有一年多了,其中有一些小知识,小技巧,小应用,希望给大家在开发时一些启发,也希望dotnet core越来越好,希望2.0正式版快点出来! 我们的框架应该是基于组件化的! 我们的系统应该是基于微服务化的! 我们的部署,应该是基于自动化的! DotNetCore跨平台目录 DotNetCore跨平台~Startup类的介绍(2016-05-31 16:25) Linux~centos上安装.

SpringBoot热部署

在SpringBoot中启用热部署是非常简单的一件事,因为SpringBoot为我们提供了一个非常方便的工具spring-boot-devtools,我们只需要把这个工具引入到工程里就OK了,下面我就说一下怎么引入spring-boot-devtools. 修改pom.xml 我们只需要在pom.xml里,引入相应的jar包就行了. <dependency> <groupId>org.springframework.boot</groupId> <artifact

Folder Monitor:文件夹监控教程

FolderMonitor?是一款绿色便携软件,主要提供文件夹监控的功能,可以监控文件的创建.删除.修改和重命名.你可以监控本地文件夹,也可以监控远程的文件夹,一旦有人动了你的文件夹,就会立即发出声音警报,当然你可以设置隐藏警告.FolderMonitor0.5.1.1汉化绿色版_监视指定文件夹的利器. FolderMonitor0.6.2.5绿色版_监视指定文件夹的变化. 设置: 添加文件夹: 开始监控:

深入探索 Java 热部署

在 JAVA 开发领域,热部署一直是一个难以解决的问题,目前的 JAVA 虚拟机只能实现方法体的修改热部署,对于整个类的结构修改,仍然需要重启虚拟机,对类重新加载才能完成更新操作.对于某些大型的应用来说,每次的重启都需要花费大量的时间成本.虽然 OSGI 架构的出现,让模块重启成为可能,但是如果模块之间有调用关系的话,这样的操作依然会让应用出现短暂的功能性休克.本文将探索如何在不破坏 JAVA 虚拟机现有行为的前提下,实现某个单一类的热部署,让系统无需重启就完成某个类的更新. 类加载的探索 首先

DotNetCore跨平台~组件化时代来了

进行dotnetcore之后,各种对象都是基于DI进行生产的,这就有了对象的生命周期一说,早在autofac里也有相关知识点,这与Microsoft.Extensions.DependencyInjection是完全温和的,方便大家理解,在讲今天的组件化之前,先对DI的三种生命周期进行理解一下: AddSingleton:单例,进程内它是唯一的 AddTransient:瞬息,在对象在当前环境内,作用域内是唯一的 AddScoped:请求,对象在一个HTTP请求内是唯一的 下面来看今天的组件化的