使用.NET Core 2.1的Azure WebJobs

WebJobs不是Azure和.NET中的新事物。 Visual Studio 2017中甚至还有一个默认的Azure WebJob模板,用于完整的.NET Framework。 可是,Visual Studio中以某种方式遗漏了.NET Core中WebJobs的相似模板。 在这篇文章中,我使用的是.NET Core 2.1来建立WebJobs。web

在.NET Core中建立WebJob并不难,但你必须知道一些技巧,特别是若是你想使用一些.NET Core好特性,好比日志和DI。json

在这篇文章中,咱们将构建一个WebJob并使用Visual Studio,Azure门户和VSTS将其发布到Azure。浏览器

什么是WebJobs

WebJob是在App Service后台运行的程序。 它与您的Web应用程序在相同的环境中运行,无需额外费用。 也许你须要作一些每小时任务或天天凌晨1点作一些清理工做。 Azure Application Insights使用WebJob报告应用程序的统计信息。网络

WebJobs能够按小时或天天安排,但也能够触发。 触发器能够是文件上载或队列上的新消息。app

WebJobs 对比 Functions

我常常在WebJobs和Azure Functions之间比较。 在某种程度上,Functions是WebJobs的后继者。 Functions(一般)是在Azure中运行的一小段代码,就像WebJobs同样,在某个事件中触发,包括HTTP触发器。ide

Functions一般是WebJobs的一个很好的替代品,但若是你已经有了一个Web应用程序,那么使用WebJob就能够了。 特别是当您想在WebJob和Web应用程序之间共享代码或设置,这也使部署很是容易,由于它们在相同的上下文中运行。ui

建立一个Storage帐户

在咱们继续以前,先让咱们先处理一下。 WebJob须要Azure Storage帐户。 我将快速引导您完成建立过程。this

在Azure中,找到“Storage Azure( 存储账户)”并添加一个。 您必须选择一个在Azure中惟一的名称。 除此以外,您能够保留默认值。编码

一旦你的 Storage Account就绪,选择它并找到您的“Access keys(访问密钥)”。 咱们稍后须要的两个链接字符串之一。spa

建立WebJob

前面已经说过,完整的.NET Framework有一个WebJob模板。 我建议你看看。 首先建立一个ASP.NET Web应用程序,而后添加一个新的WebJob。 若是您尝试当即建立WebJob,则会收到错误消息,指出项目须要先保存(尽管它确实建立了WebJob)。

这边文章写的是.NET Core的WebJob。 首先,建立一个ASP.NET Core Web应用程序,而后将新的.NET Core Console应用程序项目添加到您的解决方案中。

咱们须要作的第一件事是从NuGet安装Microsoft.Azure.WebJobs包。 咱们还应该安装Microsoft.Azure.WebJobs.Extensions。 这些库的最新稳定版本依赖于完整的.NET Framework,所以咱们将须要3.0.0-beta5版本(在撰写本文时),它与.NET Core彻底兼容。

咱们须要的其余NuGet包是Microsoft.Extensions.Options.ConfigurationExtensions(它还提供了咱们还须要的Microsoft.Extensions.Options包),Microsoft.Extensions.DependencyInjection和Microsoft.Extensions.Logging.Console。 请确保安装这些软件包的2.1.0版本,由于.NET Core 2.1中彷佛存在一个错误,致使您没法使用包含修补程序版本的软件包,例如2.1.1。

添加到Program.cs文件

咱们须要作的下一件事是更改咱们的Program.cs文件。 若是您使用.NET Framework模板建立了WebJob,则只需复制并粘贴在那里生成的Program.cs文件(您可能须要更改命名空间)。

 

using Microsoft.Azure.WebJobs;
 
namespace NetCoreWebJob.WebJob
{
    // To learn more about Microsoft Azure WebJobs SDK, please see https://go.microsoft.com/fwlink/?LinkID=320976
    internal class Program
    {
        // Please set the following connection strings in app.config for this WebJob to run:
        // AzureWebJobsDashboard and AzureWebJobsStorage
        private static void Main()
        {
            var config = new JobHostConfiguration();
            if (config.IsDevelopment)
            {
                config.UseDevelopmentSettings();
            }
            var host = new JobHost(config);
            // The following code ensures that the WebJob will be running continuously
            host.RunAndBlock();
        }
    }
}

 

添加配置和依赖

您会用到.NET Core里面好的特性,好比日志和DI。 默认状况下,Console App不具有任何功能,但您能够自行添加。

private static void Main()
{
    IServiceCollection services = new ServiceCollection();
    ConfigureServices(services);
 
    // ...
}
 
private static IConfiguration Configuration { get; set; }
 
private static void ConfigureServices(IServiceCollection services)
{
    var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
 
    Configuration = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true)
        .AddEnvironmentVariables()
        .Build();
 
    services.AddSingleton(Configuration);
    services.AddTransient<Functions, Functions>();
    services.AddLogging(builder => builder.AddConsole());
}

接下来,建立一个appsettings.json文件并将“复制到输出目录”属性设置为“始终复制”。 appsettings.json文件应该有两个链接字符串,如Program.cs模板文件中所述。 这些是咱们以前建立的存储账户链接字符串。

 

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "ConnectionStrings": {
    "AzureWebJobsDashboard": "[your Storage Account connection string]",
    "AzureWebJobsStorage": "[your Storage Account connection string]"
  }
}

 

接下来咱们须要的是一个自定义的IJobActivator,可用于将依赖项注入到咱们的类中。 它须要在Program类的JobHostConfiguration上设置。

using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.DependencyInjection;
using System;
 
namespace NetCoreWebJob.WebJob
{
    public class JobActivator : IJobActivator
    {
        private readonly IServiceProvider services;
 
        public JobActivator(IServiceProvider services)
        {
            this.services = services;
        }
 
        public T CreateInstance<T>()
        {
            return services.GetService<T>();
        }
    }
}
var config = new JobHostConfiguration();
config.JobActivator = new JobActivator(services.BuildServiceProvider());

添加Trigger(触发器)

以后,建立一个类并将其命名为Functions(就像在WebJob模板中同样)。 Functions类将包含WebJob的实际代码。

固然,咱们须要添加一个触发器。 这与完整的.NET Framework不一样。 毕竟,模板使用静态方法,这使得DI没法实现。 说到DI,请注意咱们还将Functions类自己添加到DI容器中。

为简单起见,咱们将使用TimerTrigger,它由所谓的CRON表达式触发。 这只是意味着它在某一分钟,小时,一天等时触发。在这个例子中,它会触发每一分钟。

咱们还须要在JobHostConfiguration上配置计时器。

using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using System;
 
namespace NetCoreWebJob.WebJob
{
    public class Functions
    {
        private readonly ILogger<Functions> logger;
 
        public Functions(ILogger<Functions> logger)
        {
            this.logger = logger;
        }
 
        public void ProcessQueueMessage([TimerTrigger("* * * * *")]TimerInfo timerInfo)
        {
            logger.LogInformation(DateTime.Now.ToString());
        }
    }
}
var config = new JobHostConfiguration();
config.JobActivator = new JobActivator(services.BuildServiceProvider());
config.UseTimers();

运行示例

若是您正确地执行了全部操做,或者若是您正在从GitHub运行个人代码,那么您如今应该可以运行控制台应用程序。 若是您在例外状况下中断或者您正在观看“输出”窗口,您可能会注意到不少StorageExceptions。 不要担忧它们,忽略它们。 这是WebJobs库中的一个错误,不会影响您的程序。 您的触发器可能须要一分钟才会消失,因此要有一点耐心。

若是您转到Azure存储账户,您应该看到两个Blob容器,“azure-jobs-host-output”和“azure-webjobs-hosts”。 这里有不少东西,但你能够忽略它。 我发现个人WebJob触发器因为某种缘由不会消失,删除Blob容器一般会有所帮助。 显然,存储在那里的某些状态在从新添加和删除WebJobs时并不老是正确处理掉。

 

发布到Azure

咱们要作的下一件事是将WebJob部署到Azure。为了运行WebJob,须要一些能够用来运行的可执行脚本。支持许多文件类型,但对于咱们Windows用户来讲,使用exe,cmd,bat或PowerShell文件。

控制台应用程序曾经是一个exe文件,但在.NET Core中,它会生成一个咱们须要手动启动的常规DLL文件。所以,建立一个文件并将其命名为“run.cmd”并确保它以UTF-8编码没有BOM(您可使用Notepad ++之类的东西来检查)。它只须要一行代码,即“dotnet NetCoreWebJob.WebJob.dll”。这会运行您的控制台应用。确保将文件的“复制到输出目录”设置为“始终复制”。

最后一件事,因为某种缘由,Azure WebJobs须要WebJob的全部依赖项,这意味着咱们用来构建它的全部.NET Core包。您能够经过编辑csproj文件并将“<CopyLocalLockFileAssemblies> true </ CopyLocalLockFileAssemblies>”添加到第一个<PropertyGroup>(在“<TargetFramework>”下面)来完成此操做。

在咱们部署WebJob以前,咱们须要部署咱们的Web应用程序。右键单击ASP.NET项目,而后单击“发布...”。只需按照向导操做,Visual Studio就会为您部署您的应用程序。您能够建立新的Web应用程序或选择现有的应用程序。此步骤并不是严格必要,由于您能够托管独立的WebJobs,但这应该是熟悉的,它为您提供了咱们能够用于WebJob的App Service。

使用Visual Studio发布

使用Visual Studio部署WebJobs应该很容易。事实上,你可能已经知道如何作到这一点(尽管不这样作)。右键单击WebJob项目,而后单击“发布...”。如下向导看起来很像咱们刚刚作的Web应用程序的发布。您能够选择“选择现有”并选择咱们刚建立的Azure Web应用程序。

不幸的是,微软以最糟糕的方式搞砸了这个功能。 Visual Studio将使用与项目相同的名称部署WebJob,即“NetCoreWebJob.WebJob”,除了dot是WebJob名称中的非法字符!这搞砸了个人项目很是糟糕我不得不手动编辑它以使个人解决方案再次运行。

因此这就是你作的。在向导开始时,您能够选择新的或现有的App Service,单击“当即发布”旁边的箭头,而后选择“建立配置文件”。如今,您能够先在设置中更改WebJob的名称,而后再进行部署。确保您没有选择“删除目的地的其余文件”,不然您将删除您的网络应用程序。

如今,浏览到Azure门户并查找您的Web应用程序。你会在菜单中找到“WebJobs”。你会看到你的WebJob,但它没有作任何事情。您须要经过选择它并单击“运行”来手动运行它。状态应更新为“正在运行”。您如今能够查看日志以肯定它确实有效。您可能会看到有关链接字符串的错误,但您能够忽略它们。若是您切换输出,您仍然会看到一个日志写入控制台,让您知道它的工做原理!若是您没有当即看到日志,请尝试等待一两分钟,不要忘记手动刷新输出。

WebJobs in Azure

Azure WebJobs图

使用Azure Portal发布

添加新的WebJob时,您须要填写一些选项。 您能够组成一些名称,将类型设置为“已触发”,将触发器设置为“手动”。 你的选择是一个“连续”WebJob,它只是运行和关闭(除非你在你的应用程序中实现了无限循环); 以及“预约”触发的工做,这基本上就是咱们所拥有的,除非咱们本身实施了计划。

“文件上传”须要一些解释。 在这里,您能够上传包含WebJob的zip文件。 所以,请转到Visual Studio并构建您的解决方案。 而后转到WebJob项目的输出文件夹,例如“MyProject \ bin \ [Debug | Release] \ netcoreapp2.1”,并将该文件夹中的全部内容放入zip文件中。 而后在新WebJob的“文件上传”中选择它。

Add WebJob

添加 WebJob

Azure须要几秒钟才能建立您的WebJob,所以请在刷新以前保持刷新。 以后,您必须再次手动启动它,您能够查看日志。

使用VSTS发布

最终,咱们但愿将咱们的WebJob添加到VSTS中的CI / CD管道中。 不幸的是,这个功能并非即拿即用的。 幸运的是,这也不是很困难。

当您在Azure门户中时,找到App Service的“App Service Editor(预览)”。 这使您能够浏览App Service中的全部文件。 咱们注意到的一件事是您的WebJob位于“App_Data \ jobs \ triggered \ [WebJob名称]”中。 因为您的WebJob实际上只是WebJob项目构建的输出,所以只需将WebJob文件复制到App_Data便可。

WebJob file location

WebJob文件位置
 

 

构建

因此去VSTS并建立一个新版本。选择存储库,分支,而后选择“ASP.NET Core”做为模板。咱们只须要在这里改变两件事。咱们须要更改现有的“发布”任务并添加新的“.NET Core”任务来发布咱们的WebJob。

将现有发布任务的名称更改成“发布Web应用程序”,取消选中“发布Web项目”复选框,而后输入“项目路径”,即“** / NetCoreWebJob.csproj”。此外,取消选中“Zip Published Projects”和“Add project name to publish path”复选框,由于它们最终会破坏咱们的版本。

以后,建立一个新的.NET Core任务,将“Command”设置为“publish”,并将任务名称更改成“Publish web job”。再次,取消“发布Web项目”并设置“项目路径”,即“** / NetCoreWebJob.WebJob.csproj”。再次,不要压缩已发布的项目或将项目名称添加到发布路径。这里的最后一步是“Arguments”字段,能够从其余发布步骤复制/粘贴,除了咱们要添加一点:“ - configuration $(BuildConfiguration) - output $(build。 artifactstagingdirectory)\ App_Data文件\ \做业引起\ WebJobVSTS”。

VSTS WebJob build

VSTS WebJob构建

发布

最后,但并不是最不重要的是,发布。 在VSTS中建立新版本,选择“Azure App Service部署”模板并填写空白,这是工件和环境中的Azure设置。 由于咱们没有压缩咱们的构建,因此咱们只须要更改一个设置。 在“部署Azure应用程序服务”任务是“包或文件夹”设置,其默认值为“[...] / * .zip”,显然不起做用。 而是使用浏览器(带有“...”的按钮)并选择您的drop文件夹。

保存,点击新版本并选择最新版本。 若是一切顺利,您应该在Azure门户中看到新的WebJob!

结束语

喜欢这篇文章就转载吧!不要直接copy过去哦!原文地址和源代码:使用.NET Core 2.1的Azure WebJobs

相关文章
相关标签/搜索