EDA, Event-Driven Architecture
What is an event?
Event, something that happens at a given place and time.
Simply put, the event is a significant change in state, which is triggered when a user takes an action.
事件,本质上就是运动,变化,跟“函数”、“消息”、“操作”、“调用”、“算子”、“映射”等概念全息。
For example:
When a customer buys a car and its state changes from For Sale to Sold is an event.
After a successful transaction, when an amount gets deducted from your account is an event.
Once clicking on the book cab button, when a cab is booked from your account is an event.
Every event may trigger one or more than one options in response.
事件,在计算机领域里指:可以被控件识别的操作,如按下确定按钮,选择某个单选按钮或者复选框。每一种控件有自己可以识别的事件,如窗体的加载、单击、双击等事件,编辑框(文本框)的文本改变事件,等等。
事件有系统事件和用户事件。系统事件由系统激发,如时间每隔24小时,银行储户的存款日期增加一天。用户事件由用户激发,如用户点击按钮,在文本框中显示特定的文本。事件驱动控件执行某项功能。
触发事件的对象称为事件发送者;接收事件的对象称为事件接收者。
事件就是用户对窗口上各种组件的操作。
使用事件机制可以实现:当类对象的某个状态发生变化时,系统将会通过某种途径调用类中的有关处理这个事件的方法或者触发控件事件的对象就会调用该控件所有已注册的事件处理程序等。
在.net框架中,事件是将事件发送者(触发事件的对象)与事件接受者(处理事件的方法)相关联的一种代理类,即事件机制是通过代理类来实现的。当一个事件被触发时,由该事件的代理来通知(调用)处理该事件的相应方法。
C#中事件机制的工作过程如下:
(1)将实际应用中需通过事件机制解决的问题对象注册到相应的事件处理程序上,表示今后当该对象的状态发生变化时,该对象有权使用它注册的事件处理程序。
(2)当事件发生时,触发事件的对象就会调用该对象所有已注册的事件处理程序。
什么是事件驱动?
By the end of 2020, Gartner projects that over 50% of applications will be on EDA.
The Internet of Things, real-time applications, and the sharing economy require “super” distributed processing. This means that cloud servers and edge computing are united seamlessly by an architecture that enables event-driven computing. The existing database architecture has two shortcomings for the Internet of Things systems. First, storage is inflated with endless log data and 99% of data is not used. And second, high latency in data look-up makes real-time computing impossible. Event-Driven Architecture (EDA) addresses these issues.
物联网、实时应用和共享经济需要“超级”分布式处理。这意味着云服务器和边缘计算通过一个支持事件驱动计算的架构无缝地结合在一起。物联网系统现有的数据库体系结构存在两个缺陷。首先,无限的日志数据膨胀了存储空间,99%的数据没有被使用。其次,数据查找的高延迟使实时计算变得不可能。事件驱动的体系结构(EDA)解决了这些问题。
What is EDA? EDA is a software architecture that promotes production, detection, processing, and reaction to events. Events can be as varied as a driver picking up a package, a machine measurement hitting a threshold, or a specific customer arriving at a retail outlet. EDA is defined by three properties. First, it selectively transfers relevant events from incoming data to the database. Second, it processes complex events from multiple sources that can impact each other in real-time. And third, it simplifies real-time services with push-type operations. Examples of use cases for event-driven architecture include asset sharing solutions such as DiDi and Uber, prescriptive maintenance systems that allocate maintenance personnel and spare parts, or dynamic customer service applications.
EDA是什么?EDA是一种软件体系结构,用于促进事件的生产、检测、处理和响应。事件可以是多种多样的,比如一个司机拿起一个包,一个机器测量达到一个阈值,或者一个特定的客户到达一个零售店。EDA由三个属性定义。首先,它有选择地将相关事件从传入数据传输到数据库。其次,它处理来自多个源的复杂事件,这些事件可以实时地相互影响。第三,它通过推式操作简化了实时服务。事件驱动架构的用例示例包括滴滴和Uber等资产共享解决方案、分配维护人员和备件的规定维护系统或动态客户服务应用程序。
说白了,“if A then B”语句中的A 就是 ‘事件’,B就是“响应”。
事件驱动跟消息驱动机制相比
事件驱动和异步IO
通常,我们写服务器处理模型的程序时,有以下几种模型:
(1)每收到一个请求,创建一个新的进程,来处理该请求;
(2)每收到一个请求,创建一个新的线程,来处理该请求;
(3)每收到一个请求,放入一个事件列表,让主进程通过非阻塞I/O方式来处理请求
上面的几种方式,各有千秋,
第(1)中方法,由于创建新的进程的开销比较大,所以,会导致服务器性能比较差,但实现比较简单。
第(2)种方式,由于要涉及到线程的同步,有可能会面临死锁等问题。
第(3)种方式,在写应用程序代码时,逻辑比前面两种都复杂。
综合考虑各方面因素,一般普遍认为第(3)种方式是大多数网络服务器采用的方式
在UI编程中,常常要对鼠标点击进行相应,首先如何获得鼠标点击呢?
方式一:创建一个线程,该线程一直循环检测是否有鼠标点击,那么这个方式有以下几个缺点:
- CPU资源浪费,可能鼠标点击的频率非常小,但是扫描线程还是会一直循环检测,这会造成很多的CPU资源浪费;如果扫描鼠标点击的接口是阻塞的呢?
- 如果是堵塞的,又会出现下面这样的问题,如果我们不但要扫描鼠标点击,还要扫描键盘是否按下,由于扫描鼠标时被堵塞了,那么可能永远不会去扫描键盘;
- 如果一个循环需要扫描的设备非常多,这又会引来响应时间的问题;
所以,该方式是非常不好的。
方式二:就是事件驱动模型
目前大部分的UI编程都是事件驱动模型,如很多UI平台都会提供onClick()事件,这个事件就代表鼠标按下事件。事件驱动模型大体思路如下:
- 有一个事件(消息)队列;
- 鼠标按下时,往这个队列中增加一个点击事件(消息);
- 有个循环,不断从队列取出事件,根据不同的事件,调用不同的函数,如onClick()、onKeyDown()等;
- 事件(消息)一般都各自保存各自的处理函数指针,这样,每个消息都有独立的处理函数;
事件驱动架构
事件驱动架构模式是一种非常流行的分布式异步架构模式,经常被用与构建高可伸缩性的应用程序。当然它也适合小型应用,复杂应用和规模比较大的应用。这种架构模式由一系列高度解耦的、异步接收和处理事件的单一职责的组件所组成。
事件驱动架构由两个主要的拓扑组成,分别是调停者拓扑和代理者拓扑。调停者拓扑通过一个中央的调停者来编排各种处理步骤。然而代理者拓扑适用于那些当你想将事件链式的聚在一起但不使用中央调停者的情况。由于这两种模式特性以及实现均不一样,所以理解哪一个模式最适合你的实际情况是非常重要的。
调停者拓扑
调停者拓扑适合那些有很多步骤需要处理,并且需要按照某种程度的编排来处理的事件。举个例子,一个处理股票交易的事件首先需要你首先验证交易的本身合法性,然后检查这个股票交易是否合规,然后把股票交给股票代理商,计算佣金,然后通过代理商将股票移送给客户。这些步骤都需要一个编排中心来决定这些步骤的顺序,并且决定哪些能是串行的,哪些是并行的。
调停者拓扑主要有4个主要的架构组件组成:事件队列(Event Queue)、调停者(Mediator)、事件通道(Event Channel)和事件处理器(Event Processor)。
事件流通过客户端发送到消息队列,事件队则传递消息到调停者。调停者接收到队列传递过来的原始消息,然后编排成异步的消息发送到事件通道,事件通道则通过事件处理器执行处理过程的每一步。事件处理器则监听事件通道,根据自身不同的业务逻辑来处理从调停者接受的事件。
If event Then handler,实际上包含三个元素:
1.事件(event);
2.响应(handler);
3.事件与响应的“逻辑关系”
其中的'事件'常常是固定的;而“逻辑关系”往往体现的是业务规则或者核心逻辑,也常常是固定不变的。
只有'响应'是可变的,或者说是可以配置或者需要改变的。
软件开发的OCP原则告诉我们:“软件应该对修改关闭,但要对扩展开放”。而事件驱动就是在保持了事件和核心逻辑的稳定性和不被修改的前提下,通过定义不同的“响应”从而达到了对“扩展的开放”。
Event-driven architecture components
An event-driven architecture typically consists of four components:
Event
The significant change in the state of an object that occurs when users take action.Event Handler
A software routine, which handles the occurrence of an event.Event Loop
Event loop handles the flow of interaction between an event and the event handler.Event Flow Layers
The event flow layer is built on three logical layers: Event Producer, Event Consumer, and Event Channel (also called Event Bus).
Producer which is responsible for detecting and generating events.
Consumer which consumes the events produced by the event producer.
Event Channel which transfers events from the event generator to the event consumer.
关于最终一致性
响应事件而不是“及时”查询权限系统会让我们更具有自主性,更有容错能力和弹性,但也有一点其他影响,会影响自治事件驱动系统的是“延迟”。
如果你立即注意到某一事件,你可以立即做出反应。例如,如果一辆车转弯进入你的车道,你看到这个,你可以很快刹车或者调整驾驶避免不发生碰撞。但是,如果有一些延迟,在观察到这个事件后,你的反应可能是缓慢的(也许有驾驶障碍?或者你在玩手机?或是在你的孩子们做某事,等等)。
这也可能发生在IT系统。比如在亚马逊订购商品。这会对其他自主服务(如订单处理,帐单,库存等)发布一个事件或事实。这些系统可以观察到这一事件,但如果此时库存系统从网络断开几分钟/小时?当他们重新恢复正常运行后,他们最终会看到这个事件并继续检查库存,发布任何它认为必要的事件(即反应)像“inventoryreserved事件”或“inadequateinventory”事件。这是一组自主系统“最终”变得一致的一个简单例子。
最后一件事是关于事件,延迟和自主权。如果我们能够捕捉到它们并观察它们的顺序,事件就是有用的。也就是说,在我们的系统中必须保留一组事件的总排序,这样我们才能如何对它们做出反应有信心。
现在你已经明白:事件的顺序在分布式系统中构建事务是如何的重要,如果事件变得无序,那么我们就无从获得最终一致性,除非再次需要人工介入。
小结
Event-Driven Architecture
Domain Events 领域事件
Event Sourcing
Command and Query Responsibility CQRS
Segregation (CQRS) pattern
Event Stream Processing 简称ESP
Messaging 消息系统
Enterprise Service Bus ESB总线
Actors
Enterprise Integration Architecture (EIA)
Event Sourcing事件溯源
每个状态的改变都可以表达为事件。事件触发状态改变。
所有的事件被发往EventProcessor
EventProcessor 将所有事件保存在 Event Log
系统能够被复位,这样Event Log 会重播。
不再需要ORM, 只要持久化Events。
很多不同的EventListeners被加到EventProcessor,对其监听(or listen directly on the Event log)
CQRS特点
所有状态改变由Domain Events驱动
聚合根接受 Commands,然后发布 Events
报表系统 (数据库查询) 将作为一个发布后事件published Events的结果
所有来自表现层查询直接走报表系统。
CQRS优点
充分封装了业务领域,只暴露行为。
查询不使用 domain model
没有对象和关系不匹配问题。
易于跟踪审计和历史
易于和外部系统整合。
性能与可伸缩性。
参考资料
https://www.softobiz.com/understanding-the-event-driven-architecture/
https://medium.com/@prashunjaveri/architectural-patterns-for-iot-event-driven-architectures-557be35fa626
https://www.eda-consortium.cn/abouteventdrivenarchitecture
https://www.jdon.com/artichect/scalable8.html
Kotlin开发者社区
专注分享 Java、 Kotlin、Spring/Spring Boot、MySQL、redis、neo4j、NoSQL、Android、JavaScript、React、Node、函数式编程、编程思想、"高可用,高性能,高实时"大型分布式系统架构设计主题。
High availability, high performance, high real-time large-scale distributed system architecture design。
分布式框架:Zookeeper、分布式中间件框架等
分布式存储:GridFS、FastDFS、TFS、MemCache、redis等
分布式数据库:Cobar、tddl、Amoeba、Mycat
云计算、大数据、AI算法
虚拟化、云原生技术
分布式计算框架:MapReduce、Hadoop、Storm、Flink等
分布式通信机制:Dubbo、RPC调用、共享远程数据、消息队列等
消息队列MQ:Kafka、MetaQ,RocketMQ
怎样打造高可用系统:基于硬件、软件中间件、系统架构等一些典型方案的实现:HAProxy、基于Corosync+Pacemaker的高可用集群套件中间件系统
Mycat架构分布式演进
大数据Join背后的难题:数据、网络、内存和计算能力的矛盾和调和
Java分布式系统中的高性能难题:AIO,NIO,Netty还是自己开发框架?
高性能事件派发机制:线程池模型、Disruptor模型等等。。。
合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。不积跬步,无以至千里;不积小流,无以成江河。