可以通過WebRole.cs OnStart()方法運行線程,以便我們可以通過aspx頁面訪問它以執行後臺工作? 我知道正確的做法是使用工人角色,但我希望儘可能降低運行成本。Azure Web角色中的後臺線程
這個想法是創建一個線程,總是會運行並等待工作,例如,如果我想進行阻塞操作就像發送電子郵件我會使用線程給出SendEmail方法,是否有可能去做?如果是這樣,你能否給我提供一些可以指引我正確方向的例子?
可以通過WebRole.cs OnStart()方法運行線程,以便我們可以通過aspx頁面訪問它以執行後臺工作? 我知道正確的做法是使用工人角色,但我希望儘可能降低運行成本。Azure Web角色中的後臺線程
這個想法是創建一個線程,總是會運行並等待工作,例如,如果我想進行阻塞操作就像發送電子郵件我會使用線程給出SendEmail方法,是否有可能去做?如果是這樣,你能否給我提供一些可以指引我正確方向的例子?
我會suggets一個解決方案,是從萊昂和大衛的解決方案不同:
的另一種選擇,你應該看看使用的是Windows Azure存儲隊列(他們很便宜)在這種情況下:
該解決方案有很多優點。 WebRole.cs運行在與Web應用程序不同的進程中,因此對請求線程沒有影響。除此之外,如果發送郵件因任何原因失敗,郵件將保留在隊列中並在下次處理。如果應用程序或進程崩潰,這將確保您不會丟失任何要執行的任務。
下面是一個讓你開始的例子。請注意,如果您希望生產準備就緒(重試策略,異常處理,退避輪詢等),則需要改進此代碼:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using System.Threading.Tasks;
namespace MvcWebRole1
{
public class WebRole : RoleEntryPoint
{
public override bool OnStart()
{
Task.Factory.StartNew(InitializeQueueListener);
return base.OnStart();
}
private void InitializeQueueListener()
{
Microsoft.WindowsAzure.CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
{
configSetter(Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.GetConfigurationSettingValue(configName));
});
var storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
var queueStorage = storageAccount.CreateCloudQueueClient();
var queue = queueStorage.GetQueueReference("myqueue");
queue.CreateIfNotExist();
while (true)
{
CloudQueueMessage msg = queue.GetMessage();
if (msg != null)
{
// DO SOMETHING HERE
queue.DeleteMessage(msg);
}
else
{
System.Threading.Thread.Sleep(1000);
}
}
}
}
}
似乎是更好的解決方案,我願意執行的工作類型,無論如何,我打算讓隊列與內部應用程序「交談」,所以它不會那麼昂貴......您可以進一步詳細瞭解「在啓動實例時產生一個新的線程並讓它監聽來自該隊列的消息」? **如果你可以給我一個例子,或者指向一個樣例,它解釋了在WebRole.cs **中啓動一個監聽線程所涉及的線程部分,那將是非常好的。謝謝 – ToinoBiclas
同意 - 隊列非常有彈性。我的意圖是指出創建線程的可行性(這並不總是顯而易見的)。 –
@Sandrino讓我知道如果這是內聯與您的解決方案...在WebRole.OnStart()'新線程(新ThreadStart(ClassListeningToQueue.Method0)''創建一個線程'然後在Method0內寫入一個無限循環或條件循環它只通過WebRole.OnStop()'while(true){try {CloudQueueMessage msg = queue.GetMessage(); if(msg!= null){''finnaly根據msg中的值執行任務,例如我可以有一個字段指出調用的方法和參數,在主線程中調用其他線程是否安全? – ToinoBiclas
我發現這個時候我一直在尋找的「蔚藍計劃任務」:http://www.ronaldwidha.net/2011/02/23/cron-job-on-azure-using-scheduled-task-on-a-web-role-to-replace-azure-worker-role-for-background-job/
看起來正是你要尋找的。
您指出的例子是用於運行預定作業,很像Linux中的crontabs。我願意做一個等待被髮信號的線程。 – ToinoBiclas
這只是指出,完全可以做這些事情。我想你可以用一點創意想出一個解決方案。 –
絕對可以創建一個線程(或很多)。 Web角色基本上是Windows 2008 Server。您不需要單獨的工作人員角色來設置後臺任務。當然,你的可以有一個單獨的輔助角色,這將允許你擴展這些實例,而不依賴於你的Web角色實例。這是您需要平衡性能/擴展與成本之間的關係。
你能給我一些關於如何做到這一點的細節?如果我已經在WebRole:RoleEntryPoint中聲明瞭,我怎樣才能從一個aspx網頁訪問線程變量? – ToinoBiclas
如果您需要與aspx頁面中的線程交互,爲什麼不從global.asax啓動線程? RoleEntryPoint將在單獨的AppDomain中運行,因此您不會在應用程序和線程之間進行交互。 –
老實說從未想過這件事。我將嘗試使用global.asax中聲明的線程池進行一些測試。 – ToinoBiclas
這將如何降低運行成本?你想要什麼不同於單實例單一併發服務? – Paparazzi
@Blam - 在Web角色中運行後臺任務允許將操作組合成一組VM實例。這與將背景操作放在單獨的一組角色實例中形成鮮明對比。組合成一個角色將節省成本,因爲每個角色必須至少有一個實例正在運行。對於小批量網站,這是一個非常節省成本的架構。如果存在背景任務捱餓網站的風險,或者需要分別縮放前端和後臺任務(或者需要不同的VM大小),則值得考慮轉向單獨的角色。 –
@DavidMakogon謝謝我不知道一個工作者角色需要一個單獨的實例。我沒有試圖回答這個問題。 +1我從這個問題中學到了很多東西。 – Paparazzi