ASP.NET应用程序可以处理NServiceBus事件吗?

问题描述:

如果不是所有的NSB例子为ASP.NET(或MVC)具有Web应用程序使用Bus.Send发送消息,并可能是注册一个简单的回调,这基本上是我如何在我的应用程序中使用它。ASP.NET应用程序可以处理NServiceBus事件吗?

我想知道的是,如果在同一个ASP.NET应用程序中可能和/或对句柄消息有任何意义。

主要的原因我问的是缓存。该过程可能是这样的:

  1. 用户从Web应用程序发起请求。
  2. Web应用程序向独立应用程序服务器发送消息,并将更改记录在本地数据库中。
  3. 在来自同一用户的未来页面请求中,Web应用程序知道该更改并将其列为“待处理”状态。
  4. 一堆东西发生在后端,最终请求被批准或拒绝。参考原始请求发布事件。
  5. 此时,Web应用程序应该开始显示的最新信息。

现在,在一个真正的web应用程序中,这个挂起的请求将被缓存,很可能很长一段时间,因为否则应用程序必须在数据库中查询挂起的更改每次用户要求提供当前信息。

所以,当请求最终完成对后端 - 这可能需要一分钟或一天 - Web应用程序的需求,至少,为了无效该缓存条目,做一套DB查询。

现在我意识到这可以通过SqlDependency对象等来管理,但是让我们假设它们不可用 - 可能它不是SQL Server后端,或者当前信息查询可能转到Web服务, 随你。问题是,Web应用程序如何意识到状态的变化?

如果它是可能在ASP.NET应用程序中处理NServiceBus消息,那么处理程序的上下文是什么?换句话说,IoC容器将不得不注入一堆依赖项,但它们的范围是什么?这是否全部在HTTP请求的上下文中执行?还是一切都需要静态/单身的消息处理程序?

对这类问题有更好的/推荐的方法吗?

+0

我不知道如何处理IIS中的事件,但是无论何时您引入异步过程,您都必须处理最终的一致性。网络应用程序是否需要立即更新,或者每分钟15分钟每小时刷新一次缓存? – Ryan

+0

@Ryan:我们可以逃避吗?大概。我对客户POV感到满意吗?不是真的。我对EC一般都很满意 - 例如,我意识到,如果网站或应用程序池未运行,直到它再次启动,并且* *完全正常 - 但信息应该已启动在某些用户实际请求它的几分钟之内,数据真的应该被缓存更长的时间。这种差异通常通过手动或基于依赖关系的缓存失效来解决。 – Aaronaught

+0

对,这就是我在我的同步应用程序中所做的。对于NSB,我只是每次都碰到数据库,但我只有几个用户的后台应用程序。 – Ryan

端点(NSB)可以创建订阅发布的事件,并更新缓存。只有在实际更新完成后才能发布该事件,以免不同步。 Web应用程序将继续在下一个请求中从缓存中提取数据,或者可以在某种延迟中进行构建。

+0

这听起来有点模糊,当然事件不会在事务实际发生之前发布,但是在什么时候它会保证到达ASP.NET应用程序中的消息处理程序?你对我关于依赖范围的问题有任何评论吗?我试图理解一个消息处理程序是否可以将某个依赖项绑定到HTTP请求(Ninject - InRequestScope)上。 – Aaronaught

+0

假设它是交易型和耐用的,它将通过运输保证。范围将按照请求,检查AsyncPages示例。这注册了页面的回调,并且正在处理消息,这听起来好像在这种情况下足够好。在我看来,到下一次读取更新将会在那里,所以你可以做一些UI的事情来帮助。这个网站的工作方式,如果你刷新足够快的数据不存在。 –

+0

这不完全相同的情况,但我认为这是一个很好的阅读NSB /网络应用程序的一些背景:http://www.make-awesome.com/2010/10/why-not-publish-nservicebus - 从Web应用程序的消息/ –

我不知道我自己同样的事情 - 什么是耦合的,用于与NServiceBus基础设施的网络应用适当的水平?在我的域中,我遇到了类似的问题来解决涉及使用SignalR代替缓存的问题。像你一样,我还没有找到关于这种特定模式的很多文档。但是,我认为可以通过遵循它的某些含义来推理,然后决定它是否在您的环境中有意义。

总之,我认为完全有可能让web应用程序订阅NServiceBus事件。我不认为会有任何技术性障碍,尽管我必须承认我没有真正尝试过 - 如果你有时间,尽一切办法给它一个镜头。我只是强烈地感到,如果开始需要来做到这一点,那么可能有更好的整体设计等待被发现。这就是为什么我认为这是如此:

  1. 要问的相关问题与您的缓存实施有关。如果它是分布式或集中式模型(比如SQL,MongoDB,Memcached等),那么@Adam Fyles建议的方法听起来是个好主意。您不需要需要来通知每个Web应用程序 - 更新缓存可以通过单个NServiceBus端点完成,该端点的而不是 Web应用程序的一部分。换句话说,您的Web应用程序和“缓存更新”端点的每个实例都将访问相同的共享缓存。但是,如果你的缓存在进程中,比如微软的Web缓存,那么当然你需要解决一个更复杂的问题,除非你可以像建议的那样依靠最终一致性。
  2. 如果您的Web应用程序订阅特定的NServiceBus事件,那么您需要为每个Web应用程序实例分配一个唯一的输入队列。由于最佳做法是考虑使用负载均衡器扩展您的Web应用程序,这意味着您最终可能会有N个队列和至少N个订阅,这比订阅的数量更多而不必担心。再一次,不是技术性的障碍,只是会让我扬起眉毛的东西。
  3. David Boike被链接的文章提出了一个关于应用程序池以及它们的生命周期如何不确定的有趣观点。另外,如果您为服务器上的同一应用程序同时运行多个应用程序池(通常情况下),则它们都将尝试从同一个消息队列中读取,并且没有好方法可以确定哪个应用程序实际处理消息。更重要的是,这很重要。相反,发送命令不需要根据this post by Udi Dahan的输入队列。这就是为什么我认为Web应用程序发送的单向命令在实践中更常见的原因。
  4. 这里有很多要说的单一责任原则。一般来说,如果您可以尽可能将发送和接收消息的“专业知识”委派给NServiceBus主机,那么您的整体架构将变得更干净,更易于管理。通过经验,我发现如果我把我的网络农场看作是一个单独的实体,即剥夺了对个人网络服务器身份的所有确认,那我就不用担心了。让每个Web服务器成为总线上的端点类型会打破这个概念,因为现在“哪个服务器”以消息队列的形式再次出现。

这是否有助于澄清事情?