CRQ:排队命令的好处



我无法真正理解命令串中排队命令的好处。

这是我非常简单的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;
      }
  }
}

此实现实际上是在持续使用的登录数据库中持续存在的TransactionnalCommandBus中装饰的,但是由于这不是我问题的重点,所以我不会在这里显示。

现在让我们专注于排队命令串:

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或错误以使客户知道命令失败或成功。但是,拥有更健壮的系统的好处通常超过这种不便的不便。

在大多数情况下,您不需要命令的总线。我建议您仅出于某种原因需要命令异步,仅使用命令总线。如果您不使用公共汽车,那么对命令的处理将不那么复杂。

关于CQRS的任何内容都没有说您需要使用总线进行命令或事件。在CQRS中指出,您的命令和事件必须异步。

如果您使用总线,则需要在发送命令之前验证命令。正如您所说,如果他们失败了,将其交流给客户会更加困难。您可以通过提出一些事件来做到这一点,说命令失败了,但是直接将某些东西直接返回给客户会要容易得多。

最新更新