研究了一整天的quartz.net,发现一直无法解决cluster模式下多个node独立运行的问题,改了很多配置项,仍然是每个node各自为战。本来cluster模式下的各个node应该是负载均衡的,现在却变成了“冗余”。quartz.net的文档很不完善,而且最新版是2018年发布的了,虽然很容易调通单机版的quartz.net,但是考虑到docker环境下负载均衡时多容器共同运行的问题,必须解决cluster中多个节点同时只运行1个的问题,也就是说“1分钟1次”是指全局所有节点“1分钟1次”,而不是每个节点“1分钟1次”。
痛苦之后,发现了hangfire!配置非常简单,而且支持redis,支持di,配置了一下,一次成功!
开发环境:asp.net core 3.1
首先安装必要的包:
<ItemGroup> <PackageReference Include="Hangfire.AspNetCore" Version="1.7.11" /> <PackageReference Include="Hangfire.Redis.StackExchange" Version="1.8.2" /> </ItemGroup>
然后修改Startup.cs
namespace HangfireTest { public class Startup { public static ConnectionMultiplexer Redis; public Startup(IConfiguration configuration) { Configuration = configuration; Redis = ConnectionMultiplexer.Connect("redis"); } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews(); services.AddHangfire(configuration => { configuration.UseRedisStorage(Redis); }); services.AddSingleton<TestJob>(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { //... app.UseHangfireServer(); RecurringJob.AddOrUpdate<TestJob>("MinutelyEcho", jobs => jobs.Run(), Cron.Minutely); } } }
然后,实现一个“正常的”任务类:
using System; namespace HangfireTest { public class TestJob { public void Run(){ Console.WriteLine(DateTime.Now); } } }
在Startup中注册任务类和添加调度,这里是每分钟1次。
为了测试多个node的实际运行情况,将程序打包成docker(省略Dockerfile),并编写docker-compose文件:
version: '3' services: app: image: hftest deploy: replicas: 2 ports: - 80:80 redis: image: redis
hftest是我打包好的docker镜像,注意这里relicas=2,设置了2个备份。
然后,使用docker stack deploy命令进行部署,使用docker logs命令观察任务执行情况。
docker logs 节点1
info: Microsoft.Hosting.Lifetime[0] Content root path: /app 04/30/2020 06:57:08 04/30/2020 06:59:07
docker logs 节点2
info: Microsoft.Hosting.Lifetime[0] Content root path: /app 04/30/2020 06:58:07
证明任务在多个节点上的运行就如同在1个节点一样,并未重复运行。
最后简单对比一下quartz.net和hangfire(hangfire仅接触1天,说的可能不正确,请指正):
项目 | quartz.net | hangfire |
最新代码 | 2018 | 几天前 |
支持redis | 不支持 | 支持 |
图形界面 | 不支持 | 支持 |
cluster | 有问题(重复执行) | 完美 |
配置代码量 | 高 | 低 |
任务支持依赖注入 | 默认不支持 | 支持 |
总体来说,除了quartz在java上比较流行的优势之外,在.net上,目前hangfire应该是完胜quartz.net.