内部应用程序¶

对于在服务器上运行的Web应用程序(物理或虚拟),您需要使用版本高于2008的 Windows Server 附带的IIS≥7.5的自启功能。完整设置需要完成以下步骤:


    - 允许 Windows Process Activation (WAS) 和 World Wide Web Publishing (W3SVC) 服务自启(默认自启)。
    - 允许应用程序池 配置自启.aspx) (默认开启)。
    - 启用应用程序池的始终运行模式,并配置自启功能,如下所示。

创建几个类¶

首先,您需要一个实现 IProcessHostPreloadClient 接口的特殊类。 它将会随着 Windows Process Activation 服务启动、每个应用程序池回收之后自动调用。

  1. public class ApplicationPreload : System.Web.Hosting.IProcessHostPreloadClient
  2. {
  3. public void Preload(string[] parameters)
  4. {
  5. HangfireBootstrapper.Instance.Start();
  6. }
  7. }

然后, 如下所述更新您的 global.asax.cs 文件。 关键 是记得为 BackgroundJobServer 的实例调用 Stop 方法。 同时启动Hangfire server,即使在没有自启功能的环境(如开发环境)中。

  1. public class Global : HttpApplication
  2. {
  3. protected void Application_Start(object sender, EventArgs e)
  4. {
  5. HangfireBootstrapper.Instance.Start();
  6. }
  7.  
  8. protected void Application_End(object sender, EventArgs e)
  9. {
  10. HangfireBootstrapper.Instance.Stop();
  11. }
  12. }

接着, 如下创建 HangfireBootstrapper 类。 即使 Application_StartPreload 方法将在自启的环境中被调用,也需要确保初始化逻辑将被调用一次。

  1. public class HangfireBootstrapper : IRegisteredObject
  2. {
  3. public static readonly HangfireBootstrapper Instance = new HangfireBootstrapper();
  4.  
  5. private readonly object _lockObject = new object();
  6. private bool _started;
  7.  
  8. private BackgroundJobServer _backgroundJobServer;
  9.  
  10. private HangfireBootstrapper()
  11. {
  12. }
  13.  
  14. public void Start()
  15. {
  16. lock (_lockObject)
  17. {
  18. if (_started) return;
  19. _started = true;
  20.  
  21. HostingEnvironment.RegisterObject(this);
  22.  
  23. GlobalConfiguration.Configuration
  24. .UseSqlServerStorage("connection string");
  25. // Specify other options here
  26.  
  27. _backgroundJobServer = new BackgroundJobServer();
  28. }
  29. }
  30.  
  31. public void Stop()
  32. {
  33. lock (_lockObject)
  34. {
  35. if (_backgroundJobServer != null)
  36. {
  37. _backgroundJobServer.Dispose();
  38. }
  39.  
  40. HostingEnvironment.UnregisterObject(this);
  41. }
  42. }
  43.  
  44. void IRegisteredObject.Stop(bool immediate)
  45. {
  46. Stop();
  47. }
  48. }

另外, 如果想要启用 Hangfire Dashboard UI, 请创建一个 OWIN startup 类:

  1. public class Startup
  2. {
  3. public void Configuration(IAppBuilder app)
  4. {
  5. var options = new DashboardOptions
  6. {
  7. AuthorizationFilters = new[]
  8. {
  9. new LocalRequestsOnlyAuthorizationFilter()
  10. }
  11. };
  12.  
  13. app.UseHangfireDashboard("/hangfire", options);
  14. }
  15. }

启用服务自动启动¶

创建上述类后,您应该编辑全局的 applicationHost.config 文件 (%WINDIR%\System32\inetsrv\config\applicationHost.config)。首先,您需要将应用程序池的启动模式更改为 AlwaysRunning 模式,然后启用 Service AutoStart Providers。

记得保存所有的修改

进行这些更改后,相应的应用程序池将自动重新启动。只有 在确保所有元素 修改后 才保存更改。

  1. <applicationPools>
  2. <add name="MyAppWorkerProcess" managedRuntimeVersion="v4.0" startMode="AlwaysRunning" />
  3. </applicationPools>
  4.  
  5. <!-- ... -->
  6.  
  7. <sites>
  8. <site name="MySite" id="1">
  9. <application path="/" serviceAutoStartEnabled="true"
  10. serviceAutoStartProvider="ApplicationPreload" />
  11. </site>
  12. </sites>
  13.  
  14. <!-- Just AFTER closing the `sites` element AND AFTER `webLimits` tag -->
  15. <serviceAutoStartProviders>
  16. <add name="ApplicationPreload" type="WebApplication1.ApplicationPreload, WebApplication1" />
  17. </serviceAutoStartProviders>

请注意最后一项, WebApplication1.ApplicationPreload 在程序中是类的全名,并且 IProcessHostPreloadClientWebApplication1 是应用程序库的名称。 更多资料请参阅 这里

没有必要将IdleTimeout设置为零 – 当应用程序池的启动模式设置为 AlwaysRunning, idle timeout 将失去作用。

确保自启功能正在工作¶

如果出现问题…

如果您的应用程序在进行这些更改后无法加载,请通过打开 控制面板管理工具事件查看器来检查Windows事件日志 。然后通过 Windows日志 → 应用程序 查找最新的错误记录。

最简单的检查方法 - 回收您的应用程序池,5分钟后转到Hangfire 仪表盘并检查当前的 Hangfire Server 实例是否在5分钟前启动。如果您有问题 - 请不要犹豫,在 论坛上 提问。

原文:

http://hangfirezh.zhs.press/deployment-to-production/making-aspnet-app-always-running.html