JMS微服務開發示例(三)使用分布式鎖和編寫定時任務


分布式鎖

在Controller當中,提供了分布式鎖的功能,代碼如下:

    class HelloworldController : MicroServiceControllerBase
    {
        static List<string> Users = new List<string>();

        ILogger<HelloworldController> _logger;
        public HelloworldController(ILogger<HelloworldController> logger)
        {
            _logger = logger;
        }

        public void Test()
        {
            //鎖定指定的key
            if( this.TryLock("my key"))
            {
                _logger.LogInformation("鎖成功");

                //使用完畢這里記住要釋放鎖
                this.TryUnLock("my key");
            }
        }
    }

編寫定時任務

創建一個類,實現JMS.IScheduleTask接口

    class AutoRun : JMS.IScheduleTask
    {
        public double[] Timers => null;

        public int Interval => 5000;//設置每隔5秒執行一次

        public void Run()
        {
            Console.WriteLine("auto running at " + DateTime.Now);
        }
    }

注冊定時任務

            var msp = new MicroServiceHost(services);
            msp.Register<HelloworldController>("Hello world");
            msp.RegisterScheduleTask<AutoRun>();
            msp.Build(port, gateways)
                .Run();

如果定時任務時間間隔單位較大,應設置Times屬性

如:Times = new [] { 11.30  18.45 }  表示在每天的11:30 和 18:45 分別執行一次

在定時任務中使用分布式鎖

定時任務默認支持依賴注入,所以,注入IKeyLocker即可使用分布式鎖

    class AutoRun : JMS.IScheduleTask
    {
        IKeyLocker _keyLocker;
        public AutoRun(IKeyLocker keyLocker)
        {
            _keyLocker = keyLocker;
        }
        public double[] Timers => new[] { 11.47 };

        public int Interval => 0;

        public void Run()
        {
            var tranid = $"A{ Thread.CurrentThread.ManagedThreadId }";

            if( _keyLocker.TryLock(tranid, "test"))
            {
                _keyLocker.TryUnLock(tranid, "test");
            }
            Console.WriteLine("auto running at " + DateTime.Now);
        }
    }

tranid是自定義的事務id,為了和controller事務id 區分開來,我使用了字母+線程id的規則生成一個事務id。

controller當中默認事務id為純數字。

使用Quartz實現定時任務

由於quartz能實現更多功能,如支持cron表達式,所以也可以選擇quartz來實現定時任務,如何使用quartz,可以參考

https://www.cnblogs.com/IWings/p/14205224.html

在微服務中使用quartz和在控制台里面使用是一樣的,畢竟微服務也是一個控制台程序而已,唯一需要注意,就是當程序被kill -15強制退出時,我們需要保證正在運行的定時任務執行完畢,

才允許程序退出,為了實現這一點,只需要在創建Task時,改用SafeTaskFactory創建

    public class TimingJob : IJob
    {

        Task IJob.Execute(IJobExecutionContext context)
        {
             
            return host.ServiceProvider.GetService<SafeTaskFactory>().StartNew(() => {
                Console.WriteLine("我的任務運行了");
            });
        }
    }    

這樣,程序被強行關閉時,就不會出現任務執行一半就退出的情況。

 

上一篇 示例(二)    下一篇 示例(四)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM