使用Windows服务运行Hangfire,并添加网站作为控制面板(上)

  |   0 评论   |   606 浏览

前言

由于hangfire在asp.net环境有不稳定因素,例如IIS中应用程序池默认会在闲时自动休眠、隔一段时间会自动重启等问题,在对可用性要求高的场景就会凸显这种不稳定。
虽然官方给出了解决方法,但终究不太科学,IIS的应用程序池天生就是需要隔一段时间就回收一下的东西,强制“always running”其实并不和谐。

我认为更合理的方式是使用Windows Service来运行Hangfire,然后另开一个网站作为Hangfire的操控面板。

这里会使用两到三篇文章的篇幅来分享,从新建项目到调试和安装这样一个完整的过程。分享的粒度会尽量细一些,以免节奏太快让大家看不明白。


建立Windows service项目并引入Hangfire

建立Windows service项目:

文件 ——> 新建 ——> Windows 服务

引入Hangfire:

工具 ——> NuGet包管理器 ——> 程序包管理器控制台

在控制台中输入:
PM> Install-Package Hangfire.Core
PM> Install-Package Hangfire.SqlServer

这里也可以在可视化的NuGet包管理器中搜索这两个包进行安装。

只要 Hangfire.Core 就足够了。
不需要安装 hangfire ,这个 package 包含一些你不需要的依赖项。(例如:Microsoft.Owin.Host.SystemWeb

这里演示中使用SqlServer作为Hangfire服务的Storage。
Hangfire官方在免费版中只提供了SqlServer接入的支持,在收费版多一个Redis。
需要MongoDB、MySql、PostgreSql、SQLite等其他Storages的可以自己寻找第三方的开源项目,这里有一个官方推荐的扩展清单,清单中列出了一些其他种类的Storages。

初始化Hangfire服务并添加任务

进入Service1的代码视图,添加一个后台任务服务。

using System.ServiceProcess;
using Hangfire;
using Hangfire.SqlServer;

namespace WindowsService1
{
    public partial class Service1 : ServiceBase
    {
        private BackgroundJobServer _server;

        public Service1()
        {
            InitializeComponent();
            //记得在配置文件中添加数据库连接字符串
            GlobalConfiguration.Configuration.UseSqlServerStorage("connection_string");
        }

        protected override void OnStart(string[] args)
        {
            _server = new BackgroundJobServer();
            //可以在BackgroundJobServer实例化之后的任意位置添加任务
        }

        protected override void OnStop()
        {
            _server.Dispose();
        }
    }
}

可以在BackgroundJobServer实例化之后的任意位置添加定时任务,添加的任务会持久化在Storage中,关于任务的添加及相关配置这里不做说明,请参见官方文档

为该Windows 服务添加安装程序

在服务的设计视图中右键,选择添加安装程序。

为服务起一个名字,并添加描述。

使用Visual Studio工具安装和卸载服务

Windows 服务无法在VS中直接调试或运行,需要把该程序安装为服务才能运行。后文会详细讲解如何调试安装好的服务。

可以使用 sc create 命令创建 Windows 服务,这里讲解一种.NET环境下独有的方式。
.net framwork提供了一个名为 InstallUtil.exe 的工具,可以在cmd中使用该工具。

通常可以在 C:\Windows\Microsoft.NET\Framework\*version* 找到这个工具,然后在该目录启动cmd来使用它。

可但是,微软官方推荐使用Visual Studio的命令行开发人员工具来搞事,所以这里演示使用Visual Studio开发人员工具来 安装/卸载 服务。

桌面 ——> 开始 ——> 所有应用程序 ——> Visual Studio ——> Visual Studio 工具 ——> 开发人员命令提示

大概是这样一个路径能找到这个工具,不同的操作系统略有差异,我Win10 + VS2017的环境找到的工具名称是 Developer Command Prompt for VS 2017

注意:这里必须使用管理员身份启动该工具,否则会报一个如下所示的异常。

在安装程序集“D:\OneDrive\Code\WindowsService.Hangfire.exe”。
受影响的参数是:
   logtoconsole = 
   logfile = D:\OneDrive\Code\WindowsService.Hangfire.InstallLog
   assemblypath = D:\OneDrive\Code\WindowsService.Hangfire.exe
正在安装服务 Himall.Hangfire...
正在日志 Application 中创建 EventLog 源 Himall.Hangfire...
正在回滚程序集“D:\OneDrive\Code\WindowsService.Hangfire.exe”。
受影响的参数是:
   logtoconsole = 
   logfile = D:\OneDrive\Code\WindowsService.Hangfire.InstallLog
   assemblypath = D:\OneDrive\Code\WindowsService.Hangfire.exe
正在将事件日志还原到源 Himall.Hangfire 的前一状态。
在 System.Diagnostics.EventLogInstaller 安装程序的“回滚”阶段发生异常。
System.Security.SecurityException: 未找到源,但未能搜索某些或全部事件日志。  不可访问的日志: Security。
在安装的“回滚”阶段发生异常。将忽略该异常并继续回滚。但是,在完成回滚后计算机可能无法完全还原到它的初始状态。

打开Visual Studio开发人员工具之后,输入如下命令来安装和卸载服务。
安装:

installutil D:\OneDrive\Code\WindowsService.Hangfire.exe

卸载:

installutil /u D:\OneDrive\Code\WindowsService.Hangfire.exe

安装之后可以通过 事件查看器 检查服务是否正常启动。

编写bat文件简化安装与卸载

因为 installutil 命令安装好的服务并不会自动启动,自动启动的设置需要操作系统重启后才生效,然后在开发过程中需要频繁地
修改代码…卸载服务…编译…安装…启动服务………修改代码…卸载服务…编译…安装…启动服务………修改代码…卸载服务…编译…安装…启动服务………

那么编写一个批处理工具简化流程就显得非常重要,这里提供一键 安装/卸载 的代码。
安装:

@echo off

echo 正在安装服务...

cd C:\Windows\Microsoft.NET\Framework\v4.0.30319

C:

InstallUtil.exe %~dp0HangfireTest.exe

echo 安装完成。

echo ----------------------------------------------------------

net start HangfireTest

pause

卸载:

@echo off

echo 正在卸载服务...

cd C:\Windows\Microsoft.NET\Framework\v4.0.30319

c:

InstallUtil.exe /u %~dp0HangfireTest.exe


pause

脚本中的 %~dp0 表示bat文件所在的目录路径。



都看到这里了  如果不发表评论以示支持  你的良心不会痛么?

评论

发表评论

validate