从 WebJob 对 Azure 存储队列进行轮询和睡眠
Poll-and-sleep on Azure storage queue from WebJob
我知道当队列中有新消息可用时会调用 QueueTrigger
东西。但是,这个 "Framework style" WebJobs 让我很难正确初始化我的环境。
这就是我要自己轮询队列的原因,基本模式是这样的:
var account = CloudStorageAccount.Parse("connectionString");
var client = account.CreateCloudQueueClient();
// Per application initialization stuff goes here
while(true) {
var queue = client.GetQueueReference("myqueue");
var message = queue.GetMessage();
if (message != null) {
// Per message initialization stuff goes here
// Handle message
queue.DeleteMessage(message);
}
else {
Thread.Sleep(10000); // Or some exponential back-off algorithm
}
}
我的问题是,当在 WebJob 中连续 运行ning 时,这种方法是否存在潜在问题?如果是这样,有哪些可能的替代方案可以避免 "framework-style" WebJobs?
编辑
应 Victor 的要求,这里有一些关于我不想使用 QueueTrigger
方法的原因的更多信息。基本上有两个原因。
第一个上面已经说了,就是框架调用了QueueTrigger
属性的方法。这意味着我必须将所有初始化都放在该方法中。
我们的网络应用程序中有一个两阶段的 IoC 容器(每个应用程序和每个请求),我想让 WebJobs 尽可能靠近网络应用程序,所以我想使用WebJobs 中的两阶段 IoC(每个应用程序 IoC 进行一些繁重的初始化,然后在所有请求中重复使用)。这样做的结果是我必须将每个应用程序容器放在静态变量或单例中,以便我可以从静态 QueueTrigger
方法访问它。这是我不愿意做出的设计怪癖(IMO,微软在这方面做得太多了,例如 Thread.CurrentCulture
或 HttpContext.Current
- 这确实是一种反模式并且会损害可测试性)。
适用于上述情况的完美 WebJobs SDK 将使基础设施(退避计时器、病毒处理等)可作为服务使用,以便应用程序始终保持主要控制流。这可能适用于 SDK 的所有功能,也可能不适用,我对 SDK 的了解还不足以判断。
第二个原因是开发者方便。我们有一个分布式团队,有时在离线环境中工作。根据我的阅读 here and here,不可能 运行 WebJob 应用程序在本地使用存储模拟器并让它使消息出列。使用我现在采用的自轮询方法,这非常有效。
你的方法没有问题。它会起作用,并且与 WebJobs SDK 在后台所做的非常相似(我们有一个指数退避算法)。
我很好奇,SDK初始化什么环境比较复杂?
我知道当队列中有新消息可用时会调用 QueueTrigger
东西。但是,这个 "Framework style" WebJobs 让我很难正确初始化我的环境。
这就是我要自己轮询队列的原因,基本模式是这样的:
var account = CloudStorageAccount.Parse("connectionString");
var client = account.CreateCloudQueueClient();
// Per application initialization stuff goes here
while(true) {
var queue = client.GetQueueReference("myqueue");
var message = queue.GetMessage();
if (message != null) {
// Per message initialization stuff goes here
// Handle message
queue.DeleteMessage(message);
}
else {
Thread.Sleep(10000); // Or some exponential back-off algorithm
}
}
我的问题是,当在 WebJob 中连续 运行ning 时,这种方法是否存在潜在问题?如果是这样,有哪些可能的替代方案可以避免 "framework-style" WebJobs?
编辑
应 Victor 的要求,这里有一些关于我不想使用 QueueTrigger
方法的原因的更多信息。基本上有两个原因。
第一个上面已经说了,就是框架调用了QueueTrigger
属性的方法。这意味着我必须将所有初始化都放在该方法中。
我们的网络应用程序中有一个两阶段的 IoC 容器(每个应用程序和每个请求),我想让 WebJobs 尽可能靠近网络应用程序,所以我想使用WebJobs 中的两阶段 IoC(每个应用程序 IoC 进行一些繁重的初始化,然后在所有请求中重复使用)。这样做的结果是我必须将每个应用程序容器放在静态变量或单例中,以便我可以从静态 QueueTrigger
方法访问它。这是我不愿意做出的设计怪癖(IMO,微软在这方面做得太多了,例如 Thread.CurrentCulture
或 HttpContext.Current
- 这确实是一种反模式并且会损害可测试性)。
适用于上述情况的完美 WebJobs SDK 将使基础设施(退避计时器、病毒处理等)可作为服务使用,以便应用程序始终保持主要控制流。这可能适用于 SDK 的所有功能,也可能不适用,我对 SDK 的了解还不足以判断。
第二个原因是开发者方便。我们有一个分布式团队,有时在离线环境中工作。根据我的阅读 here and here,不可能 运行 WebJob 应用程序在本地使用存储模拟器并让它使消息出列。使用我现在采用的自轮询方法,这非常有效。
你的方法没有问题。它会起作用,并且与 WebJobs SDK 在后台所做的非常相似(我们有一个指数退避算法)。
我很好奇,SDK初始化什么环境比较复杂?