我目前正在使用WCF实现一项服务,该服务控制对CRM数据库的操作。我已经实现了CQRS的几个方面,将所有操作分成不同的命令和查询。
一些命令操作执行相对简单的操作,但触发次要的,通常更昂贵的操作。我已将这些触发器分开,但它们仍在原始操作线程中执行。
我正在考虑通过单向操作将它们分成第二个WCF服务。这样原始操作可以立即返回,“触发器”服务可以处理所有这些二次操作。目前可靠性不是主要问题,因此问题记录就足够了 - 但将来可以扩展。
这是处理这种情况的典型方式吗?或者有没有办法可以在不使用辅助服务的情况下完成?
在同一台服务器上划分这样的WCF服务会有显着的性能提升吗?
我的想法是核心WCF服务的应用程序池将更快地释放(尽管新池将竞争),可以将其他服务分离到不同的服务器上。
答案 0 :(得分:1)
我同意oleksii如果您希望扩展,那么队列可能是比WCF服务更好的选择。它还允许您将命令移动到单向,并且只是向用户返回一个基本的ack / nack,该命令已被接收并正在处理(而不是它已被处理)。
我建议你看一下Greg Young在他的CQRS Info网站上对CQRS文件的介绍,特别是在命令方面的部分(大约一半)。
回答你的问题:
我希望这会有所帮助。祝你好运!!
答案 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)
只是一个建议
您可以尝试工作队列,前端的某些服务异步添加项目。后端的其他服务将项目排队并处理工作。工作状态保存到可以查询的持久存储中。
最好在队列的两边都有几个工作人员,但是为了进行任何改进,你的服务器需要是多核的(多处理器),因此它能够真正实现工作的并行化。您可能需要尝试不同的选项并查看最佳选择。