Newbe.Claptrap 框架中 State 和 Event 应该如何理解?最近整理了一下项目的术语表。今天就谈谈什么是 Event 和 State。

Newbe.Claptrap 是一个用于轻松应对并发问题的分布式开发框架。如果您是首次阅读本系列文章。建议可以先从本文末尾的入门文章开始了解。

事件 Event

Claptrap 是基于事件溯源的 Actor 模式。事件自然就起到了至关重要的作用。

想要操作 Claptrap 就需要对其传递事件。事件也是改变 Claptrap State 的唯一参数。因此,在使用 Claptrap 构建系统时,所有的系统操作都会转换为事件而传入到 Claptrap 中。事件具有以下这些特点:

事件是有序的

每个事件都包含有一个唯一的序列号。在本框架中,这个序列号被称为版本号(Version)。事件的版本号是一个从 1 开始逐 1 递增的序列。事件的有序性,确保了状态的计算不存在并发问题。这是状态数据可靠性的重要保证。

事件的有序性直接反应了 Claptrap 执行事件的先后顺序。而由于需要确保这种顺序,Claptrap 在执行事件时,必须逐个事件进行处理。这点恰好与 Actor 模式的单线程特性产生了天然的契合。

事件是不可变的

事件一旦产生,它就是不可变的。事件溯源,正由于事件的不可变性,才使得数据是可靠的。因为只要读取事件,就能够还原出任何一个事件执行之后的状态。但不可变性并不是物理上的限制。你仍然可以修改物理存储中的事件数据。但请注意,这是危险的,极为不建议的行为。

让我们联系设计模式中的 “开闭原则”,经典的可以被概括为 “对扩展开放,对修改封闭”。其中为什么要强调 “对修改封闭” 呢?就笔者看来,对修改封闭的原因其实是因为修改所带来的未知性。因为过往执行的代码,产生的数据。他们都已经形成了一定的封闭性。他们是经过已有的测试所验证的。如果尝试修改他们,势必就需要调整相应的测试,而这就更进一步加剧了修改,这可不是一件好事。事件的不可变是一种性质,更是一种要求。

那如果由于一个 BUG 导致了过往的产生事件数据不正确,现在需要修正这个 BUG,该怎么办呢?笔者的建议,不要尝试修改已有的事件。应该追加新的事件和算法来修正当前的状态。不要去调整旧的内容。笔者认为这更符合开闭原则。开发者可以自行斟酌。

事件是永久的

事件是确保 Claptrap State 正确性的重要参数。因此,需要确保事件被永久保存。但,这不是绝对的情况,如果满足以下条件,那么事件就允许被丢失:

  1. 在丢失事件之前存在一个永久的 State 快照
  2. 对应的 Claptrap 已经生命终结,永远都不会再被激活

反之,如果不满足以上的条件,那么请必须确保在生产环境中的事件被正确的保存在持久化层,并且已经有相应的容灾手段。

状态 State

State 在 Actor 模式中代表了 Actor 对象当前的数据表现。而在 Claptrap 仅仅只是在此之上增加了一个限制:“State 只能通过事件溯源的方式进行更新”。由于事件溯源的可靠性。Claptrap 中的 State 也就拥有了更好的可靠性。

State 的版本号。在 Claptrap 中的 State 中有一个名为 Version 的属性,它表示 State 当前的版本。版本号是一个从 0 开始的自增数字,会在每次处理一个事件之后进行自增。

版本号为 0 的 State 是 Claptrap 的初始状态,也可以被称为创世状态。初始状态可以根据业务需要进行定制。

Claptrap 和 Minion 对于版本号的处理也有一些区别。

对于 Claptrap 而言,Claptrap 是事件的生产者,因此,事件的版本号本身就是由 Claptrap 进行赋予的。例如,在一次事件的处理过程中,以下这些事情将会依次发生:

  1. State Version = 1000
  2. 开始处理 Event ,其 Version = State Version + 1 = 1001
  3. Event 处理完毕,更新 State Version = 1001

对于 Minion 而言,由于它是 Claptrap 事件的消费者。因此版本号的处理略有不同。例如,在一次事件的处理过程中,以下事件将会依次发生:

  1. State Version = 1000
  2. 读取到了 Event Version 为 1001 的事件
  3. Event 处理完毕,更新 State Version = 1001

State 的版本号和 Event 的版本号相互依存,相互验证,是事件有序性的关键。如果在处理过程中,出现 State 的版本号和 Event 的版本号不匹配的情况,将会是严重的问题。通常来说,出现版本号不匹配,只有两种情况:

  1. 持久化层中的事件出现了丢失
  2. 框架恶性 BUG

最后但是最重要!

最近作者正在构建以反应式Actor模式事件溯源为理论基础的一套服务端开发框架。希望为开发者提供能够便于开发出 “分布式”、“可水平扩展”、“可测试性高” 的应用系统 ——Newbe.Claptrap

本篇文章是该框架的一篇技术选文,属于技术构成的一部分。如果读者对该内容感兴趣,欢迎转发、评论、收藏文章以及项目。您的支持是促进项目成功的关键。

联系方式:

您还可以查阅本系列的其他选文:

理论入门篇

  1. Newbe.Claptrap - 一套以 “事件溯源” 和 “Actor 模式” 作为基本理论的服务端开发框架
  2. Newbe.Claptrap 项目周报 1 - 还没轮影,先用轮跑
  3. Newbe.Claptrap 框架中为什么用 Claptrap 和 Minion 两个词?

实现入门篇

  1. Newbe.Claptrap 框架入门,第一步 —— 创建项目,实现简易购物车
  2. Newbe.Claptrap 框架入门,第二步 —— 简单业务,清空购物车

样例实践篇

  1. 构建一个简易的火车票售票系统,Newbe.Claptrap 框架用例,第一步 —— 业务分析

其他番外篇

  1. 谈反应式编程在服务端中的应用,数据库操作优化,从 20 秒到 0.5 秒
  2. 谈反应式编程在服务端中的应用,数据库操作优化,提速 Upsert
  3. 十万同时在线用户,需要多少内存?——Newbe.Claptrap 框架水平扩展实验
  4. docker-mcr 助您全速下载 dotnet 镜像

术语介绍篇

  1. Actor 模式
  2. 事件溯源(Event Sourcing)
  3. Claptrap
  4. Minion
  5. 事件 (Event)
  6. 状态 (State)

GitHub 项目地址:https://github.com/newbe36524/Newbe.Claptrap

Gitee 项目地址:https://gitee.com/yks/Newbe.Claptrap

您当前查看的是先行发布于 www.newbe.pro 上的博客文章,实际开发文档随版本而迭代。若要查看最新的开发文档,需要移步 claptrap.newbe.pro

轻松应对并发问题,Newbe.Claptrap 框架中 State 和 Event 应该如何理解?的更多相关文章

  1. 轻松应对并发,Newbe.Claptrap 框架入门,第四步 —— 利用 Minion,商品下单

    接上一篇 Newbe.Claptrap 框架入门,第三步 —— 定义 Claptrap,管理商品库存 ,我们继续要了解一下如何使用 Newbe.Claptrap 框架开发业务.通过本篇阅读,您便可以开 ...

  2. Newbe.Claptrap 框架中为什么用 Claptrap 和 Minion 两个词?

    Newbe.Claptrap 框架中为什么用 Claptrap 和 Minion 两个词?最近整理了一下项目的术语表.今天就谈谈为什么起了 Claptrap 和 Minion 两个名字. Claptr ...

  3. 轻松应对并发问题,简易的火车票售票系统,Newbe.Claptrap 框架用例,第一步 —— 业务分析

    Newbe.Claptrap 框架非常适合于解决具有并发问题的业务系统.火车票售票系统,就是一个非常典型的场景用例. 本系列我们将逐步从业务.代码.测试和部署多方面来介绍,如何使用 Newbe.Cla ...

  4. Newbe.Claptrap 框架如何实现多级生命周期控制?

    Newbe.Claptrap 框架如何实现多级生命周期控制?最近整理了一下项目的术语表.今天就谈谈什么是 Claptrap Lifetime Scope. 特别感谢 kotone 为本文提供的校对建议 ...

  5. Newbe.Claptrap 框架入门,第二步 —— 简单业务,清空购物车

    接上一篇 Newbe.Claptrap 框架入门,第一步 —— 创建项目,实现简易购物车 ,我们继续要了解一下如何使用 Newbe.Claptrap 框架开发业务.通过本篇阅读,您便可以开始尝试使用 ...

  6. Newbe.Claptrap 框架如何实现 Claptrap 的多样性?

    Newbe.Claptrap 框架如何实现 Claptrap 的多样性?最近整理了一下项目的术语表.今天就谈谈什么是 Claptrap Design 和 Claptrap Factory. 特别感谢  ...

  7. Newbe.Claptrap 框架如何实现在多种框架之上运行?

    Newbe.Claptrap 框架如何实现在多种框架之上运行?最近整理了一下项目的术语表.今天就谈谈什么是 Claptrap Box. 特别感谢 kotone 为本文提供的校对建议! Newbe.Cl ...

  8. Newbe.Claptrap 框架入门,第三步 —— 定义 Claptrap,管理商品库存

    接上一篇 Newbe.Claptrap 框架入门,第二步 —— 简单业务,清空购物车 ,我们继续要了解一下如何使用 Newbe.Claptrap 框架开发业务.通过本篇阅读,您便可以开始学会添加一个全 ...

  9. Newbe.Claptrap 框架入门,第一步 —— 开发环境准备

    Newbe.Claptrap 框架依托于一些关键性的基础组件和一些可选的辅助组件.本篇我们来介绍一下如何准备一个开发环境. Newbe.Claptrap 是一个用于轻松应对并发问题的分布式开发框架.如 ...

随机推荐

  1. 入门大数据---Spark部署模式与作业提交

    一.作业提交 1.1 spark-submit Spark 所有模式均使用 spark-submit 命令提交作业,其格式如下: ./bin/spark-submit \ --class <ma ...

  2. dubbo源码解析之负载均衡

    在分布式系统中,负载均衡是必不可少的一个模块,dubbo 中提供了五种负载均衡的实现,在阅读这块源码之前,建议先学习负载均衡的基础知识.把看源码当做一个印证自己心中所想的过程,这样会得到事半功倍的效果 ...

  3. 栈的顺序存储和链式存储c语言实现

    一. 栈 栈的定义:栈是只允许在一端进行插入或删除操作的线性表. 1.栈的顺序存储 栈顶指针:S.top,初始设为-1 栈顶元素:S.data[S.top] 进栈操作:栈不满时,栈顶指针先加1,再到栈 ...

  4. 《算法笔记》6.6小节 问题 A: 任务调度

    这道题我一开始看到的时候,想到的是拓补排序,可是这么菜又这么懒的我怎么可能用呢,既然出现在优先队列里面,那么久一定和他有关了 可是并没有使用优先队列 思路: 对于这道题,我们肯定是对他们定义优先级,然 ...

  5. Ribbon软负载 (F版)

    Spring Cloud 为开发者提供了在分布式系统中的一些常用的组件(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁定,决策竞选,分布式会话集群状态).使用Sprin ...

  6. bootstrap悬停下拉菜单显示

    使用Bootstrap导航条组件时,如果你的导航条带有下拉菜单,那么这个带下拉菜单的导航在点击时只会浮出下拉菜单,它本身的href属性会失效,也就是失去了超链接功能,这并不是我想要的,我希望导航条的链 ...

  7. java 包装类的使用

    1.为什么要有包装类(或封装类) 为了使基本数据类型的变量具有类的特征,引入包装类. 2.基本数据类型与对应的包装类: 3.需要掌握的类型间的转换:(基本数据类型.包装类.String) 应用场景举例 ...

  8. CF55D Beautiful numbers 题解

    题目 Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer n ...

  9. 《Spring全局异常处理》从零掌握@ControllerAdvice注解

    一.开门见山 在前后端分离框架的大趋势下,前后端基本的职责已经确定. 前端主要负责界面的处理以及基本的判空检验.数据来源则通过vue调用后端发布的接口. 后端的原型还是mvc的模式: controll ...

  10. redis(十):Redis 列表(List)

    Redis 列表(List) Redis列表是简单的字符串列表,按照插入顺序排序.你可以添加一个元素到列表的头部(左边)或者尾部(右边) 一个列表最多可以包含 232 - 1 个元素 (4294967 ...