美文网首页dotnet core 学习笔记
Hangfire 在 dotnet core 中的 应用及部署

Hangfire 在 dotnet core 中的 应用及部署

作者: 谢冰Drama | 来源:发表于2019-07-30 14:34 被阅读0次

    第一步: 创建.net core mvc 应用   

    为什么要创建MVC 呢?  因为 可以 采用登录进行控制hangfire 的权限控制,如果 不需要权限的话 api 应用也是可以的

    第二步: 下载相关的hangfire  dll   (采用的是sqlserver 进行管理任务)

    Hangfire.AspNetCore 、Hangfire.RecurringJobExtension、Hangfire.Sqlserver

    第三步: 配置Hangfire

    1.ConfigureServices

    ```

    public void ConfigureServices(IServiceCollection services)

            {

    //配置启用cookie

                services.Configure<CookiePolicyOptions>(options =>

                {

                    // This lambda determines whether user consent for non-essential cookies is needed for a given request.

                    options.CheckConsentNeeded = context => false;

                    options.MinimumSameSitePolicy = SameSiteMode.None;

                });

    //配置权限

                services.AddMvc(opt =>

                {

                    opt.Filters.Add<AdminAuthFilter>();

                }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

                services.AddScoped<IMessageService, MessageService>();

                //注入hangfire 服务

                services.AddHangfire(x =>

                {

                    x.UseSqlServerStorage(Configuration.GetConnectionString("DefaultConnection"));

                    x.UseRecurringJob(new JobProvider());

                    x.UseConsole();

                    x.UseFilter(new LogEverythingAttribute());

                });

                ApiConfig.HangfireLogUrl = Configuration["HangfireLogFileUrl"];

                //GlobalJobFilters.Filters.Add(new LogEverythingAttribute());

                //GlobalConfiguration.Configuration.UseAutofacActivator(container);

                //add dbcontext

                services.AddDbContextPool<JobsDbContext>(options =>

                    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

                services.AddAuthentication(o =>

                {

                    o.DefaultAuthenticateScheme = CookieJobsAuthInfo.AdminAuthCookieScheme;

                    o.DefaultChallengeScheme = CookieJobsAuthInfo.AdminAuthCookieScheme;

                    o.DefaultSignInScheme = CookieJobsAuthInfo.AdminAuthCookieScheme;

                    o.DefaultSignOutScheme = CookieJobsAuthInfo.AdminAuthCookieScheme;

                }).AddCookie(CookieJobsAuthInfo.AdminAuthCookieScheme, o =>

                {

                    o.LoginPath = "/Login";

                });

                //泛型注入到di

                services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>));

                services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

                services.AddSession();

                services.AddScoped<IUserService, UserService>();

                services.AddScoped<IAuthService, AuthService>();

            }

    ```

    其中

    JobProvider:

    public class JobProvider : IConfigurationProvider

        {

            public IEnumerable<RecurringJobInfo> Load()

            {

                var result = new List<RecurringJobInfo>();

                var assembly = Assembly.GetEntryAssembly();

                if (assembly == null) return result;

                foreach (var type in assembly.GetTypes())

                {

                    foreach (var method in type.GetTypeInfo().DeclaredMethods)

                    {

                        //if(!method.IsDefined(typeof(RecurringJobInfo),false))

                        //    continue;

                        var attribute = method.GetCustomAttribute<RecurringJobAttribute>(false);

                        if (attribute == null) continue;

                        if (string.IsNullOrWhiteSpace(attribute.RecurringJobId))

                        {

                            attribute.RecurringJobId =method.GetRecurringJobId();

                        }

                        result.Add(new RecurringJobInfo()

                        {

                            RecurringJobId = attribute.RecurringJobId,

                            Cron = attribute.Cron,

                            Queue = attribute.Queue,

                            Enable = attribute.Enabled,

                            Method = method,

                            TimeZone = TimeZoneInfo.Local

                        });

                    }

                }

                return result;

            }

        }

    LogEverythingAttribute:

    public class LogEverythingAttribute : JobFilterAttribute, IClientFilter, IServerFilter, IElectStateFilter, IApplyStateFilter

        {

            private static readonly ILog Logger = LogProvider.GetCurrentClassLogger();

            public void OnCreating(CreatingContext filterContext)

            {

                Logger.InfoFormat("Creating a job based on method `{0}`...", filterContext.Job.Method.Name);

                WriteLog(

                    $"{ApiConfig.HangfireLogUrl}\\OnCreating-{(filterContext.Job.Method.Name)}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.txt",

                    $"Creating a job based on method `{filterContext.Job.Method.Name}`... . 时间为:{DateTime.Now:yyyy-MM-dd-HH-mm-ss}");

            }

            public void OnCreated(CreatedContext filterContext)

            {

                WriteLog(

                    $"{ApiConfig.HangfireLogUrl}\\OnCreated-{(filterContext.BackgroundJob?.Id ?? "0")}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.txt",

                    $"Job that is based on method `{filterContext.Job.Method.Name}` has been created with id `{filterContext.BackgroundJob?.Id}` . 时间为:{DateTime.Now:yyyy-MM-dd-HH-mm-ss} \r\n");

                Logger.InfoFormat(

                    "Job that is based on method `{0}` has been created with id `{1}`",

                    filterContext.Job.Method.Name,

                    filterContext.BackgroundJob?.Id);

            }

            public void OnPerforming(PerformingContext filterContext)

            {

                Logger.InfoFormat("Starting to perform job `{0}`", filterContext.BackgroundJob.Id);

                WriteLog(

                    $"{ApiConfig.HangfireLogUrl}\\OnPerforming-{(filterContext.BackgroundJob?.Id ?? "0")}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.txt",

                    $"Starting to perform job `{filterContext.BackgroundJob.Id}` . 时间为:{DateTime.Now:yyyy-MM-dd-HH-mm-ss} \r\n");

            }

            public void OnPerformed(PerformedContext filterContext)

            {

                Logger.InfoFormat("Job `{0}` has been performed", filterContext.BackgroundJob.Id);

                WriteLog(

                    $"{ApiConfig.HangfireLogUrl}\\OnPerformed-{(filterContext.BackgroundJob?.Id ?? "0")}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.txt",

                    $"Job `{ filterContext.BackgroundJob.Id}` has been performed . 时间为:{DateTime.Now:yyyy-MM-dd-HH-mm-ss} \r\n");

            }

            public void OnStateElection(ElectStateContext context)

            {

                var failedState = context.CandidateState as FailedState;

                if (failedState != null)

                {

                    Logger.WarnFormat(

                        "Job `{0}` has been failed due to an exception `{1}`",

                        context.BackgroundJob.Id,

                        failedState.Exception);

                    WriteLog(

                        $"{ApiConfig.HangfireLogUrl}\\OnStateElection-{(context.BackgroundJob?.Id ?? "0")}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.txt",

                        $"Job `{context.BackgroundJob.Id}` has been failed due to an exception `{(JsonConvert.SerializeObject(failedState.Exception))}` . 时间为:{DateTime.Now:yyyy-MM-dd-HH-mm-ss} \r\n");

                }

            }

            public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction)

            {

                Logger.InfoFormat(

                    "Job `{0}` state was changed from `{1}` to `{2}`",

                    context.BackgroundJob.Id,

                    context.OldStateName,

                    context.NewState.Name);

                WriteLog(

                    $"{ApiConfig.HangfireLogUrl}\\OnStateApplied-{(context.BackgroundJob?.Id ?? "0")}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.txt",

                    $"Job `{context.BackgroundJob.Id}` state was changed from `{context.OldStateName}` to `{context.NewState.Name}` . 时间为:{DateTime.Now:yyyy-MM-dd-HH-mm-ss} \r\n");

            }

            public void OnStateUnapplied(ApplyStateContext context, IWriteOnlyTransaction transaction)

            {

                Logger.InfoFormat(

                    "Job `{0}` state `{1}` was unapplied.",

                    context.BackgroundJob.Id,

                    context.OldStateName);

                WriteLog(

                    $"{ApiConfig.HangfireLogUrl}\\OnStateUnapplied-{(context.BackgroundJob?.Id ?? "0")}-{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.txt",

                    $"Job `{context.BackgroundJob.Id}` state `{context.OldStateName}` was unapplied . 时间为:{DateTime.Now:yyyy-MM-dd-HH-mm-ss} \r\n");

            }

            /// <summary>

            /// 写入文本

            /// </summary>

            /// <param name="path">路径</param>

            /// <param name="message"></param>

            public void WriteLog(string path,string message)

            {

                var fileUrl = path;

                if (!File.Exists(fileUrl))

                {

                    File.Create(fileUrl).Close();

                }

                FileStream fs = new FileStream(fileUrl, FileMode.Append);

                byte[] data = System.Text.Encoding.Default.GetBytes(message??"");

                fs.Write(data, 0, data.Length);

                fs.Close();

            }

        }

    2. Configure 配置

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)

            {

                if (env.IsDevelopment())

                {

                    app.UseDeveloperExceptionPage();

                }

                else

                {

                    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.

                    app.UseHsts();

                }

                //app.UseHttpsRedirection();

                //app.UseMvc();

                app.UseStaticFiles();

                //app.UseHangfireServer();//启动hangfire 服务

                app.UseAuthentication();

                app.UseSession();

                app.UseMvc(routes =>

                {

                    routes.MapRoute(

                        name: "default",

                        template: "{controller=Login}/{action=Index}");

                    routes.MapRoute(

                        name: "areas",

                        template: "{area:exists}/{controller=Login}/{action=Index}/{id?}");

                });

                //配置任务属性

                var jobOptions = new BackgroundJobServerOptions()

                {

                    Queues = new[] { "default", "apis", "job" },//队列名称,只能小写

                    WorkerCount = Environment.ProcessorCount * 5,//并发任务数

                    ServerName = "hangfire"//服务器名称

                };

                app.UseHangfireServer(jobOptions);

                //配置hangfire访问权限

                var options = new DashboardOptions()

                {

                    Authorization = new[] { new HangfireAuthorizationFilter() },

                };

                app.UseHangfireDashboard("/hangfire", options);//启动hangfire 面板

                //HandfireExtension.Register();

                //app.Run(ctx =>

                //{

                //    ctx.Response.Redirect($"{Configuration["WebRootUrl"]}/hangfire"); //可以支持虚拟路径或者index.html这类起始页.

                //    return Task.FromResult(0);

                //});

            }

    第四步:

    具体样例

    第五步:

    dotnet core 部署在 iis 上,如果不设置 闲置超时的话  iis 会 自动闲置

    可根据项目情况 调整 或  转换成 windows service 或计划任务

    结尾:

    github demo 地址:https://github.com/xiehanbing/JobHangfire

    相关文章

      网友评论

        本文标题:Hangfire 在 dotnet core 中的 应用及部署

        本文链接:https://www.haomeiwen.com/subject/znqnrctx.html