WCF 服务内部火灾/忘记队列

发布于 2024-11-30 07:39:09 字数 443 浏览 1 评论 0原文

我目前正在使用 WCF 实现一项服务,该服务控制对 CRM 数据库的操作。我已经实现了 CQRS 的多个方面,将所有操作分为不同的命令和查询。

问题 1:

一些命令操作执行相对简单的操作,但会触发辅助的、通常更昂贵的操作。我已经分离了这些触发器,但它们仍然在原始操作线程中执行。

我正在考虑将它们分离到第二个 WCF 服务中,并进行单向操作。这样原始操作可以立即返回,并且“触发器”服务可以处理所有这些辅助操作。目前可靠性不是主要问题,因此问题记录就足够了 - 但将来可能会扩展。

这是处理这种情况的典型方法吗?或者有没有一种方法可以在不使用辅助服务的情况下完成此操作?

问题2:

在同一台服务器上这样划分WCF服务是否会带来显着的性能提升?

我的想法是,核心 WCF 服务的应用程序池将被更快地释放(尽管新的池将相互竞争),并且可以将附加服务分离到单独的服务器上。

I'm currently implementing a service using WCF, which controls operations to a CRM database. I've implemented several aspects of CQRS to separate all operations into distinct Command and Queries.

Question 1:

Several of the Command Operations perform a relatively simple operation, but trigger a secondary, often more expensive operation. I've separated these triggers, but they still execute within the original operation thread.

I was thinking of separating these into a second WCF service, with one-way operations. That way the original operation can return immediately, and the "Trigger" service can handle all of these secondary operations. Currently reliability is not a major issue, so issue logging would suffice - but could be extended in the future.

Is this the typical way for handling such a scenario? Or is there a way this could be completed without using a secondary service?

Question 2:

Are there significant performance improvements from dividing WCF services like this on the same server?

My thinking is that core WCF Service's application pool will be freed up quicker (although the new pools will be competing), with the possibility of separating additional services onto separate servers.

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

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

发布评论

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

评论(3

踏雪无痕 2024-12-07 07:39:09

我同意 oleksii 的观点,如果您希望扩展,队列可能是比 WCF 服务更好的选择。它还允许您将命令移动为单向,实际上只是向用户返回一个基本的 ack/nack,表明命令已收到并正在处理(而不是已处理)。

我建议您查看 Greg Young 在他的 CQRS Info 网站上对 CQRS 的介绍文档,特别是在命令侧部分(大约向下一半)。

回答您的问题:

  1. 通过转移到单向队列或 WCF 服务,我认为这可以解决您的问题。您的单向服务接收来自客户端的命令,然后将其交给您的域来处理。然后,您的域将根据需要执行的操作触发 0 个、1 个或多个事件 - 这些事件可能是对应用程序中其他 WCF 服务的调用,也可能是丢弃在由事件处理程序拾取的队列中的消息。关键是您让业务规则(域)确定要引发哪些事件。具体如何处理它们是一个实现细节(但我会使用队列或事件存储)。请查看Jonathan Oliver 的活动商店
  2. 我认为释放 IIS 线程(或一般线程)的速度越快是一件好事;因此,如果您将服务分为同步和异步,那可能会很好。我认为,如果您要采用 CQRS 路线,那么在服务上单向返回 ack/nack 消息可能是一件好事,并且从性能角度来看可能会有所帮助,因为您可能会更快地释放线程来处理更多线程请求。

我希望这有帮助。祝你好运!!

I agree with oleksii that a queue may be a better option than a WCF service if you're looking to scale. It will also allow you to move your commands to be one-way and really just return to the user a basic ack/nack that the command was received and is being processed (not that it was processed).

I'd suggest you look at Greg Young's intro to CQRS document on his CQRS Info site, specifically in the Command Side section (about half-way down).

Getting to your questions:

  1. By moving to a queue or a WCF service that is all one-way, I think this solves your problem. Your one-way service receives the command from the client and then hands it to your domain to process it. Your domain would then fire off 0, 1 or many events based on what needs to be done -- these events could be calls to other WCF services in your application or they could be messages dropped on a queue picked up by your event handler. The key is that you're letting the business rules (domain) determine what events to raise. How they get handled specifically is an implementation detail (but I'd go with a queue or event store). Check out Jonathan Oliver's Event Store.
  2. I think the faster you can free up IIS threads (or threads in general) is a good thing; so if you divide your services up into synchronous and asynch, that may be good. I think if you're going the CQRS route, going one-way on your services to just return ack/nack messages is probably a good thing and may help you from a performance perspective since you'll probably free up threads faster to handle more requests.

I hope this helps. Good luck!!

信仰 2024-12-07 07:39:09

没有什么可以阻止您使用同步命令,然后仅异步运行部分执行代码,而无需分离服务。

你提到你已经分离了你的“触发器”。我认为这意味着它们作为单独的方法运行?既然如此,您可以轻松地在后台运行它们并让您的主 WCF 线程返回,而无需分离服务。 (下面的代码不假设事件源。)

public class MyCommandHandler
{
    public string Do(MyCommand1 command)
    {
        var myCrmObject = ... ; // load some object
        string message = myCrmObject.CriticalWork(command); // synchronous
        ThreadPool.QueueUserWorkItem(x => myCrmObject.OtherWork(command)); // async
        // async alternative 1
        //Action<MyCommand1> action = myCrmObject.OtherWork; // make into action delegate
        //action.BeginInvoke(null, command); // start action async, no callback
        // async alternative 1a - custom delegate instead of Action. same BeginInvoke call
        // async alternative 2 - Background Worker
        // async alternative 3 - new System.Threading.Thread(...).Start(command);
        return message; // will be here before OtherWork finishes (or maybe even starts)
    }
}

如果您使用事件流和事件处理程序来执行数据库写入并与其他系统集成,那么这可以构造得更好一些。您可以让您的个人事件处理程序担心它是否应该同步执行。

There's nothing stopping you from having synchronous commands and then having only some of the execution code run asynchronously without having to separate services.

You mentioned that you have separated your "triggers". I assume that means they run as separate methods? That being the case, you can easily run them in the background and let your main WCF thread return, without having to separate services. (The code below is NOT assuming event sourcing.)

public class MyCommandHandler
{
    public string Do(MyCommand1 command)
    {
        var myCrmObject = ... ; // load some object
        string message = myCrmObject.CriticalWork(command); // synchronous
        ThreadPool.QueueUserWorkItem(x => myCrmObject.OtherWork(command)); // async
        // async alternative 1
        //Action<MyCommand1> action = myCrmObject.OtherWork; // make into action delegate
        //action.BeginInvoke(null, command); // start action async, no callback
        // async alternative 1a - custom delegate instead of Action. same BeginInvoke call
        // async alternative 2 - Background Worker
        // async alternative 3 - new System.Threading.Thread(...).Start(command);
        return message; // will be here before OtherWork finishes (or maybe even starts)
    }
}

If you were using an event stream and event handlers to perform database writes and integrate with other systems, then this could be structured a bit better. You could have your individual event handlers worry about whether it should execute synchronously or not.

扮仙女 2024-12-07 07:39:09

只是一个建议

  1. 你可以尝试一个工作队列,前端的一些服务异步添加项目。后端的其他服务使项目出列并处理工作。工作状态保存到可查询的持久存储中。

  2. 队列两侧最好都有多个工作人员,但对于任何改进,您的服务器需要是多核(多处理器)的,这样它将能够真正并行工作。您可能需要实际尝试不同的选项,看看什么是最好的。

Just a suggestion

  1. You can try a working queue, some services on the front end asynchronously add items. Other services on the back end dequeue items and process the work. State of the work is saved to the persistent storage where it can be queried.

  2. It's better to have several workers on both sides of the queue, but for any improvements, your server needs to be multi-core (multi-processor), so it will be able to truly parallelise work. You may need to actually try different options and see what's best.

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