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。瀏覽器
WebJob是在App Service後臺運行的程序。 它與您的Web應用程序在相同的環境中運行,無需額外費用。 也許你須要作一些每小時任務或天天凌晨1點作一些清理工做。 Azure Application Insights使用WebJob報告應用程序的統計信息。網絡
WebJobs能夠按小時或天天安排,但也能夠觸發。 觸發器能夠是文件上載或隊列上的新消息。app
我常常在WebJobs和Azure Functions之間比較。 在某種程度上,Functions是WebJobs的後繼者。 Functions(一般)是在Azure中運行的一小段代碼,就像WebJobs同樣,在某個事件中觸發,包括HTTP觸發器。ide
Functions一般是WebJobs的一個很好的替代品,但若是你已經有了一個Web應用程序,那麼使用WebJob就能夠了。 特別是當您想在WebJob和Web應用程序之間共享代碼或設置,這也使部署很是容易,由於它們在相同的上下文中運行。ui
在咱們繼續以前,先讓咱們先處理一下。 WebJob須要Azure Storage帳戶。 我將快速引導您完成建立過程。this
在Azure中,找到「Storage Azure( 存儲賬戶)」並添加一個。 您必須選擇一個在Azure中惟一的名稱。 除此以外,您能夠保留默認值。編碼
一旦你的 Storage Account就緒,選擇它並找到您的「Access keys(訪問密鑰)」。 咱們稍後須要的兩個鏈接字符串之一。spa
前面已經說過,完整的.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文件。 若是您使用.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());
以後,建立一個類並將其命名爲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部署WebJobs應該很容易。事實上,你可能已經知道如何作到這一點(儘管不這樣作)。右鍵單擊WebJob項目,而後單擊「發佈...」。如下向導看起來很像咱們剛剛作的Web應用程序的發佈。您能夠選擇「選擇現有」並選擇咱們剛建立的Azure Web應用程序。
不幸的是,微軟以最糟糕的方式搞砸了這個功能。 Visual Studio將使用與項目相同的名稱部署WebJob,即「NetCoreWebJob.WebJob」,除了dot是WebJob名稱中的非法字符!這搞砸了個人項目很是糟糕我不得不手動編輯它以使個人解決方案再次運行。
因此這就是你作的。在嚮導開始時,您能夠選擇新的或現有的App Service,單擊「當即發佈」旁邊的箭頭,而後選擇「建立配置文件」。如今,您能夠先在設置中更改WebJob的名稱,而後再進行部署。確保您沒有選擇「刪除目的地的其餘文件」,不然您將刪除您的網絡應用程序。
如今,瀏覽到Azure門戶並查找您的Web應用程序。你會在菜單中找到「WebJobs」。你會看到你的WebJob,但它沒有作任何事情。您須要經過選擇它並單擊「運行」來手動運行它。狀態應更新爲「正在運行」。您如今能夠查看日誌以肯定它確實有效。您可能會看到有關鏈接字符串的錯誤,但您能夠忽略它們。若是您切換輸出,您仍然會看到一個日誌寫入控制檯,讓您知道它的工做原理!若是您沒有當即看到日誌,請嘗試等待一兩分鐘,不要忘記手動刷新輸出。
Azure WebJobs圖
添加新的WebJob時,您須要填寫一些選項。 您能夠組成一些名稱,將類型設置爲「已觸發」,將觸發器設置爲「手動」。 你的選擇是一個「連續」WebJob,它只是運行和關閉(除非你在你的應用程序中實現了無限循環); 以及「預約」觸發的工做,這基本上就是咱們所擁有的,除非咱們本身實施了計劃。
「文件上傳」須要一些解釋。 在這裏,您能夠上傳包含WebJob的zip文件。 所以,請轉到Visual Studio並構建您的解決方案。 而後轉到WebJob項目的輸出文件夾,例如「MyProject \ bin \ [Debug | Release] \ netcoreapp2.1」,並將該文件夾中的全部內容放入zip文件中。 而後在新WebJob的「文件上傳」中選擇它。
添加 WebJob
Azure須要幾秒鐘才能建立您的WebJob,所以請在刷新以前保持刷新。 以後,您必須再次手動啓動它,您能夠查看日誌。
最終,咱們但願將咱們的WebJob添加到VSTS中的CI / CD管道中。 不幸的是,這個功能並非即拿即用的。 幸運的是,這也不是很困難。
當您在Azure門戶中時,找到App Service的「App Service Editor(預覽)」。 這使您能夠瀏覽App Service中的全部文件。 咱們注意到的一件事是您的WebJob位於「App_Data \ jobs \ triggered \ [WebJob名稱]」中。 因爲您的WebJob實際上只是WebJob項目構建的輸出,所以只需將WebJob文件複製到App_Data便可。
因此去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構建
最後,但並不是最不重要的是,發佈。 在VSTS中建立新版本,選擇「Azure App Service部署」模板並填寫空白,這是工件和環境中的Azure設置。 由於咱們沒有壓縮咱們的構建,因此咱們只須要更改一個設置。 在「部署Azure應用程序服務」任務是「包或文件夾」設置,其默認值爲「[...] / * .zip」,顯然不起做用。 而是使用瀏覽器(帶有「...」的按鈕)並選擇您的drop文件夾。
保存,點擊新版本並選擇最新版本。 若是一切順利,您應該在Azure門戶中看到新的WebJob!
喜歡這篇文章就轉載吧!不要直接copy過去哦!原文地址和源代碼:使用.NET Core 2.1的Azure WebJobs