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

时间:2011-08-19 11:31:56

标签: c# wcf cqrs

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

问题1:

一些命令操作执行相对简单的操作,但触发次要的,通常更昂贵的操作。我已将这些触发器分开,但它们仍在原始操作线程中执行。

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

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

问题2:

在同一台服务器上划分这样的WCF服务会有显着的性能提升吗?

我的想法是核心WCF服务的应用程序池将更快地释放(尽管新池将竞争),可以将其他服务分离到不同的服务器上。

3 个答案:

答案 0 :(得分:1)

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

我建议你看一下Greg Young在他的CQRS Info网站上对CQRS文件的介绍,特别是在命令方面的部分(大约一半)。

回答你的问题:

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

答案 1 :(得分:1)

没有什么可以阻止你使用同步命令,然后只有一些执行代码异步运行,而不必分开服务。

你提到你已经分开了你的“触发器”。我认为这意味着它们作为单独的方法运行?既然如此,您可以在后台轻松运行它们,让主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)
    }
}

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

答案 2 :(得分:0)

只是一个建议

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

  2. 最好在队列的两边都有几个工作人员,但是为了进行任何改进,你的服务器需要是多核的(多处理器),因此它能够真正实现工作的并行化。您可能需要尝试不同的选项并查看最佳选择。