事件溯源模式 Event Sourcing Pattern

未匹配的标注

关于事件溯源

    事件溯源是由Greg Young提出的一种架构模式,是一种以事件为中心的编写业务逻辑和持久化领域对象的方法。
  1. 它要求不存储系统的当前状态,而是存储导致该状态的事件。
  2. 共享成员在各自的界限上下文中都分别建自己的类和数据库,而不是共享。数据通过同步保持一致性。
  3. 通常整个应用程序只有一个Event Store, 不同的微服务都通过向Event Store发送和接受消息而互相通信。

描述

    存储数据变动的所有状态,而不仅仅是当前的状态,从而使存储可以被用来实现领域对象的动作事件。该模式可以提高性能,可扩展性和响应能力,提供交易数据的一致性,并且保持完整的审计跟踪和记录,可能使补偿措施。

背景和问题

    大多数应用程序只保持数据的当前状态。在 CRUD 系统直接执行更新操作会影响性能和响应能力。

解决方案

不是保存数据当前的状态,而是保存每个动作的事件。

注意事项

  1. 考虑数据之间的信息交互使用同步还是异步。
  2. 事件存储是信息是不可变的。
  3. 考虑事件存储发生并发的处理机制。
  4. 提取唯一条件作为事件流的事件标识符。
  5. 重放数据可以考虑创建特定间隔的快照。
  6. 尽管活动减少了冲突,但是应用程序仍然可能出现最终一致性和缺乏交易的不一致。
  7. 事件发布可能会导致多次消费者的事件,所以消费者消费事件必须幂等。

何时使用

  1. 数据非常重要,需要记录下数据的整个生命周期的,例如银行交易数据,Git版本管理。
  2. 需要尽量减少或完全避免更新导致冲突的数据。
  3. 能够重放它们来恢复系统的状态;
  4. 与 CQRS 一起使用和最终一致性是可以接受的情况下。

结构中包含的角色

  1. EventStore 事件仓库
  2. Event 抽象事件
  3. OrderPayEvent 订单支付事件
  4. Observer 抽象观察者
  5. OrderEntity 订单实体
  6. UserEntity 用户实体

可用到的设计模式思维

    每个事件都会引起这个事件关联数据的变动,可以用观察者模式处理,这里的观察者有可能是同步,也有可能是异步的。
    每一个动作,可以抽象成一个命令,使用命令模式, 这里不展示命令模式了。

最小可表达代码

// 事件仓库
class EventStore
{
    public function append(Event $event)
    {
        var_dump("追加事件");
    }
}

// 抽象事件
abstract class Event
{
    protected $observers = [];

    public abstract function notify();  

    public function addObserver(Observer $observer)
    {
        $this->observers[] = $observer;
    }
}

// 具体目标
class OrderPayEvent extends Event
{
    public function notify()
    {
        foreach ($this->observers as $observer) {
            $observer->update($this);
        }
    }     
}

// 观察者
interface Observer {
    public function update(Event $event);  
}

// 订单实体
class OrderEntity implements Observer
{
    public function pay()
    {
        $event = new OrderPayEvent();
        $event->addObserver($this);
        $event->addObserver(new UserEntity);
        (new EventStore())->append($event);
        $event->notify();
    }

    public function update(Event $event)
    {
        if ($event instanceof OrderPayEvent) {
            var_dump('支付成功, 订单更新');
        }
    }
}

// 用户实体
class UserEntity implements Observer
{
    public function update(Event $event)
    {
        if ($event instanceof OrderPayEvent) {
            var_dump('扣除用户的订单费用');
        }
    }
}

$orderEntity = new OrderEntity();
$orderEntity->pay();

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~