Php CRQ:排队命令的好处
我不能真正理解在CommandBus中排队命令的好处 下面是我对CommandBus的非常简单的实现:Php CRQ:排队命令的好处,php,message-queue,cqrs,Php,Message Queue,Cqrs,我不能真正理解在CommandBus中排队命令的好处 下面是我对CommandBus的非常简单的实现: class CommandBus implements ICommandBus { private $handlerLocator; public function __construct(ICommandHandlerLocator $handlerLocator) { $this->handlerLocator = $handlerLocator; }
class CommandBus implements ICommandBus
{
private $handlerLocator;
public function __construct(ICommandHandlerLocator $handlerLocator)
{
$this->handlerLocator = $handlerLocator;
}
public function handle(ICommand $command)
{
$handler = $this->handlerLocator->getHandlerInChargeFor($command);
try{
$handler->handle($command);
}
catch(\Exception $e) {
throw $e;
}
}
}
class QueuingCommandBus implements ICommandBus
{
private $innerCommandBus;
private $commandQueue = array();
private $isHandling = false;
public function __construct(CommandBus $commandBus)
{
$this->innerCommandBus = $commandBus;
}
public function handle(ICommand $command)
{
$this->commandQueue[] = $command;
if($this->isHandling)
{
return;
}
while($command = array_shift($this->commandQueue))
{
$this->isHandling = true;
$this->innerCommandBus->handle($command);
}
$this->isHandling = false;
}
}
这个实现实际上是在TransactionnalCommandBus中修饰的,TransactionnalCommandBus将命令持久化到日志数据库中,但由于这不是我问题的重点,我将不在这里展示它
现在,让我们重点关注排队CommandBus:
class CommandBus implements ICommandBus
{
private $handlerLocator;
public function __construct(ICommandHandlerLocator $handlerLocator)
{
$this->handlerLocator = $handlerLocator;
}
public function handle(ICommand $command)
{
$handler = $this->handlerLocator->getHandlerInChargeFor($command);
try{
$handler->handle($command);
}
catch(\Exception $e) {
throw $e;
}
}
}
class QueuingCommandBus implements ICommandBus
{
private $innerCommandBus;
private $commandQueue = array();
private $isHandling = false;
public function __construct(CommandBus $commandBus)
{
$this->innerCommandBus = $commandBus;
}
public function handle(ICommand $command)
{
$this->commandQueue[] = $command;
if($this->isHandling)
{
return;
}
while($command = array_shift($this->commandQueue))
{
$this->isHandling = true;
$this->innerCommandBus->handle($command);
}
$this->isHandling = false;
}
}
除了现在抛出异常要困难得多之外,我真的没有看到消息队列的好处…
有人能告诉我吗?在罕见的特殊情况下,您需要以先进先出的方式连续处理命令,队列是实现这一点的简单方法。除此之外,我看不到使用内存队列处理命令的真正好处 在SOA场景中,使用队列技术(MSMQ、RabbitMQ等)可能非常有益,因为它允许持久的消息传递并增强系统可靠性。即使接收端点已关闭,该命令仍可以排队等待系统重新联机
您的评论现在抛出我的异常要困难得多,这在这些情况下是绝对正确的,因为端点现在需要发送ack或错误以让客户端知道命令失败或成功。然而,拥有一个更健壮的系统的好处通常超过了这个小小的不便。在罕见的特定情况下,您需要以先进先出的方式串行处理命令,队列是实现这一点的简单方法。除此之外,我看不到使用内存队列处理命令的真正好处 在SOA场景中,使用队列技术(MSMQ、RabbitMQ等)可能非常有益,因为它允许持久的消息传递并增强系统可靠性。即使接收端点已关闭,该命令仍可以排队等待系统重新联机
您的评论现在抛出我的异常要困难得多,这在这些情况下是绝对正确的,因为端点现在需要发送ack或错误以让客户端知道命令失败或成功。然而,拥有一个更健壮的系统所带来的好处通常超过了这个小小的不便。在大多数情况下,您的命令不需要总线。如果出于某种原因需要命令是异步的,我建议您只使用命令总线。如果不使用总线,那么命令的处理就不那么复杂了 关于CQR,并没有说您需要使用总线来执行命令或事件。CQRS中指出,您的命令和事件需要是异步的
如果使用总线,则需要在发送命令之前验证命令。如你所说,如果他们失败了,就很难将其反馈给客户。您可以通过引发一些表示命令失败的事件来实现这一点,但直接将某些内容返回到客户端会容易得多。在大多数情况下,您的命令不需要总线。如果出于某种原因需要命令是异步的,我建议您只使用命令总线。如果不使用总线,那么命令的处理就不那么复杂了 关于CQR,并没有说您需要使用总线来执行命令或事件。CQRS中指出,您的命令和事件需要是异步的
如果使用总线,则需要在发送命令之前验证命令。如你所说,如果他们失败了,就很难将其反馈给客户。您可以通过引发一些事件来说明命令失败,但直接将某些内容返回给客户端要容易得多。我不同意您的假设
首先,如果您不需要使用总线,请不要使用总线,因为总线允许将事情与装饰器模式紧密耦合(例如QueuingCommandBus、TransactionnalCommandBus、两者都是修饰的BaseComandBus…)|如果你使用总线,那么你需要在发送命令之前验证命令
我让CommandHandler验证命令本身的优点,然后验证业务不变量的集合。我表达了我的观点,你不应该像我的规则那样使用命令总线。我已经更改了措辞,但我仍然支持它,命令本身是有效的s不应该是默认选择。我不同意您的假设,首先,如果您不需要使用总线,请不要使用总线,因为总线允许将事物与装饰器模式(例如QueuingCommandBus、TransactionnalCommandBus,两者都是装饰过的BaseComandBus…)|如果你使用总线,那么你需要在发送命令之前验证命令
我让CommandHandler验证命令本身的优点,然后验证业务不变量的集合。我表达了我的观点,你不应该像我的规则那样使用命令总线。我已经更改了措辞,但我仍然支持它,命令本身是有效的s不应是默认选择。