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

发布于 2024-12-27 16:44:00 字数 878 浏览 1 评论 0原文

大多数(如果不是全部)ASP.NET(或 MVC)的 NSB 示例都有 Web 应用程序使用 Bus.Send 发送消息,并可能注册一个简单的回调,这基本上就是我使用的方式它在我的应用程序中。

我想知道在同一个 ASP.NET 应用程序中处理消息是否可能和/或有意义。

我问的主要原因是缓存。该过程可能如下所示:

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

现在,在真正的网络应用程序中,几乎可以肯定的是,这个挂起的请求将被缓存,很可能会缓存很长一段时间,因为否则应用程序必须每次查询数据库以获取挂起的更改/em> 用户询问当前信息。

因此,当请求最终在后端完成时(可能需要一分钟或一天),Web 应用程序至少需要使该缓存条目无效并进行另一次数据库查找。

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

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

对于此类问题是否有更好/推荐的方法?

Most if not all of the NSB examples for ASP.NET (or MVC) have the web application sending a message using Bus.Send and possibly registering for a simple callback, which is essentially how I'm using it in my application.

What I'm wondering is if it's possible and/or makes any sense to handle messages in the same ASP.NET application.

The main reason I'm asking is caching. The process might go something like this:

  1. User initiates a request from the web app.
  2. Web app sends a message to a standalone app server, and logs the change in a local database.
  3. On future page requests from the same user, the web app is aware of the change and lists it in a "pending" status.
  4. A bunch of stuff happens on the back-end and eventually the requests gets approved or rejected. An event is published referencing the original request.
  5. At this point, the web app should start displaying the most recent information.

Now, in a real web app, it's almost a sure thing that this pending request is going to be cached, quite possibly for a long period of time, because otherwise the app has to query the database for pending changes every time the user asks for the current info.

So when the request finally completes on the back-end - which might take a minute or a day - the web app needs, at a minimum, to invalidate this cache entry and do another DB lookup.

Now I realize that this can be managed with SqlDependency objects and so on, but let's assume that they aren't available - perhaps it's not a SQL Server back-end or perhaps the current-info query goes to a web service, whatever. The question is, how does the web app become aware of the change in status?

If it is possible to handle NServiceBus messages in an ASP.NET application, what is the context of the handler? In other words, the IoC container is going to have to inject a bunch of dependencies, but what is their scope? Does this all execute in the context of an HTTP request? Or does everything need to be static/singleton for the message handler?

Is there a better/recommended approach to this type of problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

落墨 2025-01-03 16:44:00

我自己也想知道同样的事情 - Web 应用程序与 NServiceBus 基础设施的适当耦合级别是多少?在我的领域,我有一个类似的问题需要解决,涉及使用 SignalR 代替缓存。和你一样,我没有找到很多关于这个特定模式的文档。然而,我认为可以推理出遵循它的一些含义,然后决定它在您的环境中是否有意义。

简而言之,我想说我相信 Web 应用程序订阅 NServiceBus 事件是完全可能的。我不认为会有任何技术障碍,尽管我必须承认我还没有真正尝试过 - 如果你有时间,请务必尝试一下。我有一种强烈的感觉,如果有人开始需要这样做,那么可能会有更好的整体设计等待被发现。这就是为什么我认为是这样的:

  1. 要问的一个相关问题与您的缓存实现有关。如果它是分布式或集中式模型(例如 SQL、MongoDB、Memcached 等),那么 @Adam Fyles 建议的方法听起来是个好主意。您不需要通知每个 Web 应用程序 - 更新缓存可以通过单个 NServiceBus 端点来完成,该端点不属于您的 Web 应用程序。换句话说,Web 应用程序的每个实例和“缓存更新”端点都将访问相同的共享缓存。然而,如果您的缓存是进程内的,就像 Microsoft 的 Web 缓存一样,那么您当然会遇到一个更棘手的问题需要解决,除非您可以像建议的那样依靠最终一致性。
  2. 如果您的 Web 应用程序订阅特定的 NServiceBus 事件,那么您就需要为 Web 应用程序的每个实例拥有一个唯一的输入队列。由于最佳实践是考虑使用负载均衡器横向扩展 Web 应用程序,这意味着您最终可能会得到 N 个队列和至少 N 个订阅,这比恒定数量的订阅更值得担心。再说一遍,这不是技术障碍,只是让我感到惊讶的事情。
  3. 链接的 David Boike 文章提出了一个关于应用程序池及其生命周期如何不确定的有趣观点。此外,如果服务器上的同一个应用程序同时运行多个应用程序池(一种常见情况),它们都将尝试从同一个消息队列中读取数据,并且没有好的方法来确定哪个应用程序池将实际处理该消息。更重要的是,这很重要。相反,根据 这篇文章,发送命令不需要输入队列乌迪·达汉。这就是为什么我认为 Web 应用程序发送的单向命令在实践中更为常见。
  4. 这里有很多关于单一职责原则的内容。总的来说,我想说,如果您可以将发送和接收消息的“专业知识”尽可能委托给 NServiceBus Host,您的整体架构将更加清晰且更易于管理。通过经验,我发现,如果我将我的网络场视为一个单一实体,即取消对各个网络服务器身份的所有确认,我往往无需担心。让每个 Web 服务器成为总线上的端点有点打破了这一概念,因为现在“哪个服务器”再次以消息队列的形式出现。

这有助于澄清事情吗?

I've wondered the same thing myself - what's an appropriate level of coupling for a web app with the NServiceBus infrastructure? In my domain, I have a similar problem to solve involving the use of SignalR in place of a cache. Like you, I've not found a lot of documentation about this particular pattern. However, I think it's possible to reason through some of the implications of following it, then decide if it makes sense in your environment.

In short, I would say that I believe it is entirely possible to have a web application subscribe to NServiceBus events. I don't think there would be any technical roadblocks, though I have to confess I have not actually tried it - if you have the time, by all means give it a shot. I just get the strong feeling that if one starts needing to do this, then there is probably a better overall design waiting to be discovered. Here's why I think this is so:

  1. A relevant question to ask relates to your cache implementation. If it's a distributed or centralized model (think SQL, MongoDB, Memcached, etc), then the approach that @Adam Fyles suggests sounds like a good idea. You wouldn't need to notify every web application - updating your cache can be done by a single NServiceBus endpoint that's not part of your web application. In other words, every instance of your web application and the "cache-update" endpoint would access the same shared cache. If your cache is in-process however, like Microsoft's Web Cache, then of course you are left with a much trickier problem to solve unless you can lean on Eventual Consistency as was suggested.
  2. If your web app subscribes to a particular NServiceBus event, then it becomes necessary for you to have a unique input queue for each instance of your web app. Since it's best practice to consider scale-out of your web app using a load balancer, that means that you could end up with N queues and at least N subscriptions, which is more to worry about than a constant number of subscriptions. Again, not a technical roadblock, just something that would make me raise an eyebrow.
  3. The David Boike article that was linked raises an interesting point about app pools and how their lifetimes might be uncertain. Also, if you have multiple app pools running simultaneously for the same application on a server (a common scenario), they will all be trying to read from the same message queue, and there's no good way to determine which one will actually handle the message. More of then than not, that will matter. Sending commands, in contrast, does not require an input queue according to this post by Udi Dahan. This is why I think one-way commands sent by web apps are much more commonly seen in practice.
  4. There's a lot to be said for the Single Responsibility Principle here. In general, I would say that if you can delegate the "expertise" of sending and receiving messages to an NServiceBus Host as much as possible, your overall architecture will be cleaner and more manageable. Through experience, I've found that if I treat my web farm as a single entity, i.e. strip away all acknowledgement of individual web server identity, that I tend to have less to worry about. Having each web server be an endpoint on the bus kind of breaks that notion, because now "which server" comes up again in the form of message queues.

Does this help clarify things?

不必了 2025-01-03 16:44:00

可以创建一个端点(NSB)来订阅已发布的事件并更新缓存。在实际更新完成之前不应发布该活动,这样您就不会失去同步。 Web 应用程序将在下一个请求时继续从缓存中提取数据,或者您可以构建某种延迟。

An endpoint(NSB) can be created to subscribe to the published event and update the cache. The event shouldn't be published until the actual update is made so you don't get out of sync. The web app would continue to pull data from the cache on the next request, or you can build in some kind of delay.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文