Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php CRQ:排队命令的好处_Php_Message Queue_Cqrs - Fatal编程技术网

Php CRQ:排队命令的好处

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; }

我不能真正理解在CommandBus中排队命令的好处

下面是我对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;
    }
}
这个实现实际上是在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不应是默认选择。