【发布时间】:2015-04-10 06:33:54
【问题描述】:
我知道当队列中有新消息可用时,会调用 QueueTrigger 内容。然而,这种“框架风格”的 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 中连续运行时是否存在潜在问题?如果是这样,有哪些可能的替代方法可以避免“框架式”WebJobs?
编辑
根据 Victor 的要求,这里有一些关于我为什么不想使用 QueueTrigger 方法的更多信息。基本上有两个原因。
第一个上面已经提到了,就是框架调用了一个带有QueueTrigger属性的方法。这意味着我必须将所有初始化都放在该方法中。
我们的 Web 应用程序中有一个两阶段的 IoC 容器(每个应用程序和每个请求),我想让 WebJobs 尽可能靠近 Web 应用程序,所以我想使用这两个WebJobs 中的阶段 IoC 也是如此(每个应用程序的 IoC 会进行一些繁重的初始化,然后在所有请求中重用)。这样做的结果是我必须将每个应用程序容器放在静态变量或单例中,以便我可以从静态 QueueTrigger 方法访问它。这是我不愿意做的设计怪癖(IMO,微软在这方面做得太多了,例如Thread.CurrentCulture 或HttpContext.Current - 这真的是一种反模式并且会损害可测试性)。
针对上述情况的完美 WebJobs SDK 将使基础架构(后退计时器、毒物处理等)可作为服务使用,以便主控制流始终由应用程序保留。这可能适用于 SDK 的所有功能,也可能不可能,我对 SDK 的了解还不够,无法判断。
第二个原因是开发者方便。我们有一个分布式团队,有时在离线环境中工作。从我读过的here 和here 来看,不可能使用存储模拟器在本地运行WebJob 应用程序并让它出列消息。使用我现在采用的自我投票方法,这就像一个魅力。
【问题讨论】:
-
请注意,如果您担心 IoC,您可以使用 WebJobs SDK 的 IJobActivator 接口并包装您选择的容器来执行您在网络作业中编写的所有实例化功能。虽然我同意我们不能针对本地存储模拟运行 webjobs 是一种痛苦,但我们已经通过将 webjobs 编写为控制台应用程序来克服这个问题。在本地运行它们并对其进行测试很容易。
-
@Øyvind 小更新,有可用的测试/实验包。更多信息here
标签: azure-webjobs azure-webjobssdk azure-storage-queues