基于事件驱动的流程引擎(事件驱动与过程驱动)

来源网友投稿 1113 2022-12-26

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。
本篇文章给大家谈谈基于事件驱动的流程引擎,以及事件驱动与过程驱动对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。 今天给各位分享基于事件驱动的流程引擎的知识,其中也会对事件驱动与过程驱动进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

事件驱动机制是什么?

事件驱动架构(Event Driven Architecture,EDA)一个事件驱动框架(EDA)定义了一个设计和实现一个应用系统的方法学,在这个系统里事件可传输于松散耦合的组件和服务之间。一个事件驱动系统典型地由事件消费者和事件产生者组成。

事件消费者向事件管理器订阅事件,事件产生者向事件管理器发布事件。当事件管理器从事件产生者那接收到一个事件时,事件管理把这个事件转送给相应的事件消费者。如果这个事件消费者是不可用的,事件管理者将保留这个事件,一段间隔之后再次转送该事件消费者。这种事件传送方法在基于消息的系统里就是:储存(store)和转送(forward)。




扩展资料:

构建一个包含事件驱动构架的应用程序和系统,会使这些应用程序和系统响应更灵敏,因为事件驱动的系统更适合应用在不可预知的和异步的环境里。

事件驱动架构在具体实现中是指由一系列相关组件构成的应用,而组件之间通过事件机制完成一定的业务功能。由于在一个EDA系统中各个组件都只专注于处理输入的消息与发布输出的消息,因而EDA系统能够更有加效地对管道化(pipelined)的、由多软件模块链接而成的并发事件流(concurrent processing of events)进行处理。

参考资料来源:百度百科-事件驱动架构

参考资料来源:百度百科-事件驱动模型

事件驱动架构的事件驱动架构优势

事件驱动设计和开发所提供基于事件驱动的流程引擎的优势如下所示:
◆ EDA提高基于事件驱动的流程引擎了对不断变化的业务需求的响应基于事件驱动的流程引擎,最大限度地减少基于事件驱动的流程引擎了对现有业务应用的影响基于事件驱动的流程引擎,也常消除了对新打包应用的需要。如果采用特有的粗颗粒服务模型可以基于业务目标快速确定可控的业务变更,并直接、迅速、有效地实施变更以达到业务敏捷性和完整性。
◆ 可以更容易开发和维护大规模分布式应用程序和不可预知的服务或异步服务;
◆ 可以很容易,低成本地集成、再集成、再配置新的和已存在的应用程序和服务。
◆ 促进远程组件和服务的再使用,拥有一个更灵敏、没有Bug的开发环境。
从时间维度来看EDA的优势:
◆ 短期利益:更容易定制,因为设计对动态处理有更好的响应;
◆ 长期利益:系统和组织的状态变得更精准,对实时变化的响应接近于同步。

基于事件驱动的高性能开源网络库libevent介绍及安装

libevent是一个轻量级的基于事件驱动的高性能的开源网络库,并且支持多个平台,对多个平台的I/O复用技术进行了封装,当我们编译库的代码时,编译的脚本将会根据OS支持的处理事件机制,来编译相应的代码,从而在libevent接口上保持一致。

在当前的服务器上,面对的主要问题就是要能处理大量的连接。而通过libevent这个网络库,我们就可以调用它的API来很好的解决上面的问题。首先,可以来回顾一下,对这个问题的传统解决方法。

问题: 如何处理多个客户端连接

解决方案1: I/O复用技术

这几种方式都是同步I/O,即当读写事件就绪,他们自己需要负责进行读写,这个读写过程是阻塞的,而异步I/O则不需要自己负责读写,只需要通知负责读写的程序就可以了。

解决方案2: 多线程技术或多进程技术

多线程技术和多进程技术也可以处理高并发的数据连接,因为在服务器中可以产生大量的进程和线程和处理我们需要监视的连接。但是,这两种方式也是有很大的局限性的,比如多进程模型就不适合大量的短连接,因为进程的产生和关闭需要消耗较大的系统性能,同样,还要进程进程间的通信,在CPU性能不足的情况下不太适合。而多线程技术则不太适合处理长连接,因为当我们建立一个进程时,linux中会消耗8G的栈空间,如果我们的每个连接都杵着不断开,那么大量连接长连接后,导致的结果就是内存的大量消耗。

解决方案3: 常用的上述二者复合使用
上述的两种方法各具有优缺点,因此,我们可以将上述的方法结合起来,这也是目前使用较多的处理高并发的方法。多进程+I/O复用或者多线程+I/O复用。而在具体的实现上,又可以分为很多的方式。比如多线程+I/O复用技术,我们使用使用一个主线程负责监听一个端口和接受的描述符是否有读写事件产生,如果有,则将事件分发给其他的工作进程去完成,这也是进程池的理念。

在说完上述的高并发的处理方法之后,我们可以来介绍一个libevent的主要特色了。

同样,lievent也是采用的上述系统提供的select,poll和epoll方法来进行I/O复用,但是针对于多个系统平台上的不同的I/O复用实现方式,libevent进行了重新的封装,并提供了统一的API接口。libevent在实现上使用了事件驱动这种机制,其本质上是一种Reactor模式。

在Libevent中也是一样,向Libevent框架注册相应的事件和回调函数;当这些事件发生时,Libevent会调用这些回调函数处理相应的事件。

lbevent的事件支持三种,分别是网络IO、定时器和信号。定时器的数据结构使用最小堆(Min Heap),以提高效率。网络IO和信号的数据结构采用了双向链表(TAILQ)。

更多linux内核视频教程文本资料免费获取后台私信【内核】。

libevent的安装很简单,我是直接从github上clone下一个源码,然后进行编译安装的。

具体的命令是(假设你已经安装了git):

现在的libevent版本已经到达libevent2了,其增加了多线程的支持,API函数也发生了一些微小的变化。

如果你想知道更多的API使用情况,请点击这里。

下面,就基于libevent2编写一个聊天室服务器。

设计思想: 首先创建一个套接字,进而创建一个事件对此端口进行监听,将所请求的用户组成一个队列,并监听所有的用户事件,当某个用户说话了,产生了读事件,就将该用户的发言发送给队列中的其他用户。

程序分析

需要包含的libevent函数头:

创建一个client结构体,接受连接后存放数据:

先来看下mian函数的处理:

首先,函数初始化了一个用户队列tailq,接着创建了一个socket套接字,并将套接字设定为非阻塞模式,接着对一个全局的evbase事件集合,注册了事件,事件源是listen_fd,回调函数是on_accept,事件发生的情况是EV_READ,而且标志EV_PESIST表明该事件一直存在,而后开启事件扫描循环event_base_dispatch(evbase)。

再看一下回调函数on_accpet实现:

这个回调函数的作用很显然,就是接受了一个客户端的请求,并申请好了一个client信息,将需要的内容填写好,在填写中需要注意的是,又向上述的事件集evbase中注册了一个bufferevent事件client-buf_ev,并注册了回调函数buffered_on_read,buffered_on_error,这三个函数分别是当接受后的连接发生了读或者错误事件后的执行函数。接着,将用户的client结构放入了用户的队列tailq中去。

用户的buffer可读后的执行函数:

执行函数的作用很明显,将libevent管理中的buffer数据读取出,存入本地的data数组内,然后对队列中的client进行检索,如果不是发数据的client,则将数据写入该client的buffer中,发送给该用户。这里注意的是需要反复读取buffer中的数据,防止一个读取并没有读取干净,直到读取不到数据为止。

buffer出错处理函数和上述函数差不多,功能就是出错后,结束掉保存的client结构,详细就不说了。

编译的时候记得修改Makefile中Libevent文件夹的位置

设计思想: 所谓回显服务器就是将客户端发过来的数据再发回去,这里主要也就是说明libevent的纯IO复用实现。实现方法和上面的差不多,甚至可以说更加简单。

程序和上面的聊天服务器差不多,只是在buffer可读的事件函数中,不是将用户的数据发送给其他用户,而是直接发送给用户本身。

设计思想: 上面的方法单纯使用libevent的简单函数来实现服务,但是这里,我们假设我们需要处理的客户端很少,于是我们可以使用对于每个连接我们分配一个线程这样的方式来实现对用户的服务。这种方式简单有效,一对一服务,就算业务逻辑出现阻塞也不怕。

程序分析

首先定义了一些数据结构,worker数据结构定义的是一个工作者,它包含有一个工作线程,和结束标志,需要获取的工作队列,和建立链表需要的指针。job数据结构定义的是操作一个job的方法和对象,这回到程序中,实际上就是指的是事件发生后,封装好的client结构体和处理这个结构体的方法。workqueue数据结构指的是当前的工作队列中的工作者,以及工作队列中的待完成的工作,以及互斥锁和条件变量(因为多个工作进程需要访问这些资源)。

具体的流程就是,用一个主线程监听一个套接字,并将套接字接受到的连接accept,并创建一个client数据结构保存该连接的信息,在这个client结构中注册一个bufferevent事件,注册到client-evbase上(这时候这是向client中的evbase注册了一个事件还没有进行循环这个事件集)。

接着,当监听到某个client有bufferevent事件发生,主线程就把该client结构体和需要进行的工作方法包装成一个job结构,然后把这个job扔到workqueue上去,并通知各个工作者。而后,各个工作者开着的线程就被激活了,疯狂地去workqueue上去抢工作做,某个worker拿到工作后,就可以解包job,根据job的工作说明书(job_function)操作工作对象(client)了。这里,job的工作说明有是循环client中的client-evbase,于是这样线程就会一直去监视这个连接的状态,如果有数据就这会调用回调函数进行处理。同时,这个线程也就是阻塞在这里,这对这一个连接负责。

建立workqueue需要的结构体和函数有:

主线程的on_accept函数为:

job中的工作指南为:

设计思想: 假设我们的用户很多,高并发,长连接,那么我们还是来用I/O复用和线程池实现吧,用一个控制线程通过I/O复用负责监听和分发事件,用一组线程池来进行处理事件,这样就可以灵活地将控制逻辑和业务逻辑分开了,见下述讲解。

程序分析
具体的流程和上面的差不多,用一个主线程监听一个套接字,并将套接字接受到的连接accept,并创建一个client数据结构保存该连接的信息,在这个client结构中注册一个bufferevent事件,但是这里,将事件注册到accept_evbase中,仍然用主线程进行监听。

而面对监听后出现的事件,将client和操作client的方法打包成一个job,放到上述的workqueue中去,让工作进程来完成。这样的操作和上述的差别在于上述方法将bufferevent注册到client中的evbase中,用工作线程监听,而本方法用主线程监听,工作线程负责处理监听产生的事件。

这要的差别在于两个函数 on_accept函数:

在buffered_on_read中,提交job。

在job工作指南server_job_function中就可以做你工作该做的事儿了,根据发来的信息进行数据库处理,http返回等等。

事件驱动微服务体系架构

如果您是一名企业架构师,您可能听说过微服务架构,并使用过它。虽然您过去可能使用REST作为服务通信层,但是越来越多的项目正在转向事件驱动的体系结构。让我们深入了解这种流行架构的优缺点、它所包含的一些关键设计选择以及常见的反模式。

什么是事件驱动的微服务体系结构?

在事件驱动的体系结构中,当服务执行其他服务可能感兴趣的某些工作时,该服务将生成一个事件—执行操作的记录。其他服务使用这些事件,以便它们能够执行由于该事件而需要的任何自己的任务。与REST不同,创建请求的服务不需要知道使用请求的服务的详细信息。

这里有一个简单的例子:当一个订单被放置在一个电子商务网站,一个单一的“订单放置”事件产生,然后被几个微服务消费:

1.order服务,它可以向数据库写入一个order记录。

2.客户服务,它可以创建客户记录。

3.支付服务,它可以处理支付。

事件可以以多种方式发布。例如,可以将它们发布到保证将事件交付给适当使用者的队列中,也可以将它们发布到发布事件并允许访问所有相关方的“发布/订阅”模型流中。在这两种情况下,生产者发布事件,消费者接收该事件,并做出相应的反应。注意,在某些情况下,这两个角色还可以称为发布者(生产者)和订阅者(消费者)。

为什么使用事件驱动的体系结构

与REST相比,事件驱动架构提供了以下几个优点:

异步——基于事件的架构是异步的,没有阻塞。这使得资源可以在他们的工作单元完成后自由地转移到下一个任务,而不用担心之前发生了什么或者接下来会发生什么。它们还允许对事件进行排队或缓冲,从而防止使用者向生产者施加压力或阻塞它们。

•松耦合——服务不需要(也不应该)知道或依赖于其他服务。在使用事件时,服务独立运行,不了解其他服务,包括其实现细节和传输协议。事件模型下的服务可以独立地、更容易地更新、测试和部署。

•易于扩展——由于服务在事件驱动的体系结构下解耦,而且服务通常只执行一项任务,因此跟踪特定服务的瓶颈,并对该服务(且仅对该服务)进行扩展变得很容易。

•恢复支持——带有队列的事件驱动架构可以通过“重播”过去的事件来恢复丢失的工作。当用户需要恢复时,这对于防止数据丢失非常有用。

当然,事件驱动的架构也有缺点。通过分离紧密耦合时可能更简单的关注点,它们很容易过度设计;它们可能需要大量的前期投资;而且常常导致基础设施、服务契约或模式、多语言构建系统和依赖关系图的额外复杂性。

也许最大的缺点和挑战是数据和事务管理。由于事件驱动模型的异步性,它们必须小心处理服务之间不一致的数据、不兼容的版本、监视重复的事件,并且通常不支持ACID事务,而不支持最终的一致性,因为后者更难以跟踪或调试。

即使有这些缺点,事件驱动的体系结构通常也是企业级微服务系统的更好选择。主要的优点是可伸缩的、松散耦合的、开发人员操作友好的。

何时使用REST

然而,有时REST/web接口可能仍然更可取:

•您需要一个异步请求/应答接口。

•您需要对强事务的支持。

•您的API对公众可用。

•您的项目很小(REST的设置和部署要简单得多)。

您最重要的设计选择—消息传递框架

一旦决定了事件驱动的体系结构,就该选择事件框架了。事件生成和使用的方式是系统中的一个关键因素。目前已有数十种经过验证的框架和选择,选择正确的框架需要时间和研究。

分俩个大类: 消息处理或流处理。

消息处理

在传统的消息处理中,组件创建消息,然后将其发送到特定的(通常是单个的)目的地。一直处于空闲状态并等待的接收组件接收消息并相应地执行操作。通常,当消息到达时,接收组件执行单个流程。然后,删除消息。

消息处理体系结构的一个典型例子是消息队列。尽管大多数较新的项目使用流处理(如下所述),但是使用消息(或事件)队列的体系结构仍然很流行。消息队列通常使用代理的“存储和转发”系统,事件在此系统中从一个代理传递到另一个代理,直到它们到达适当的使用者。ActiveMQ和RabbitMQ是消息队列框架的两个流行示例。这些项目都有多年的实践经验和成熟的技术社区。

流处理

另一方面,在流内处理中,组件在达到某个状态时发出事件。其他感兴趣的组件在事件流中侦听这些事件并作出相应的反应。事件不针对特定的收件人,而是对所有感兴趣的组件可用。

在流内处理中,组件可以同时对多个事件作出反应,并对多个流和事件应用复杂的操作。有些流包括持久性,即事件在流上停留的时间可以根据需要延长。

通过流处理,系统可以重现事件的 历史 ,在事件发生后联机并仍然对其作出反应,甚至执行滑动窗口计算。例如,它可以从每秒的事件流计算每分钟的平均CPU使用量。

最流行的流处理框架之一是Apache Kafka。Kafka是许多项目使用的成熟和稳定的解决方案。它可以被认为是一种工业强度的流处理解决方案。Kafka有一个庞大的用户群、一个有用的社区和一个改进的工具集。

其他的选择

还有其他框架提供流和消息处理的组合,或者提供它们自己独特的解决方案。例如,Apache的最新产品Pulsar是一个开源的发布/订阅消息系统,它支持流和事件队列,所有这些都具有极高的性能。Pulsar的特点是丰富的-它提供多租户和地理复制-因此复杂。据说Kafka的目标是高吞吐量,而脉冲星的目标是低延迟。

NATS是另一种具有“合成”队列的发布/订阅消息系统。NATS是为发送小而频繁的信息而设计的。它提供了高性能和低延迟;然而,NATS认为某种程度的数据丢失是可以接受的,优先考虑性能而不是交付保证。

其他的设计考虑

一旦你选择了你的事件框架,这里有几个其他的挑战需要考虑:

•Event Sourcing

很难实现松耦合服务、不同的数据存储和原子事务的组合。一个可能有所帮助的模式是事件源。在事件源中,从来不直接对数据执行更新和删除;相反,实体的状态更改被保存为一系列事件。

•CQRS

上面的事件来源引入了另一个问题:由于需要从一系列事件构建状态,查询可能会很慢,而且很复杂。命令查询责任隔离(CQRS)是一种设计解决方案,它为插入操作和读取操作调用单独的模型。

•事件发现

事件驱动体系结构中最大的挑战之一是对服务和事件进行编目。在哪里可以找到事件描述和详细信息?事件发生的原因是什么?是哪个团队创造了这个活动?他们在积极地工作吗?

•应对变化

事件模式会改变吗?如何在不破坏其他服务的情况下更改事件模式?随着服务和事件数量的增长,如何回答这些问题变得至关重要。

成为一个好的事件消费者意味着要为变化的模式编码。成为一个好的事件生产者意味着要认识到模式更改如何影响其他服务,并创建经过良好设计的事件,这些事件被清楚地记录下来。

•内部部署vs.托管部署

无论您的事件框架是什么,您还需要在自行部署框架(消息代理的操作并不简单,特别是在高可用性的情况下),还是使用托管服务(如Heroku上的Apache Kafka)之间做出选择。

反模式

与大多数体系结构一样,事件驱动的体系结构具有自己的一组反模式。以下是一些需要注意的地方:

设计过多的事件

注意不要对创建事件过于兴奋。创建太多的事件将在服务之间创建不必要的复杂性,增加开发人员的认知负担,增加部署和测试的难度,并导致事件使用者的拥塞。不是每个方法都需要是一个事件。

通用的事件

不要使用通用事件,无论是在名称中还是在目的上。您希望其他团队了解您的事件为何存在、应该用于什么以及应该在什么时候使用。事件应该有特定的目的,并相应地命名。事件与通用名称或通用事件与混乱的旗帜,导致问题。

复杂的依赖关系图

注意那些相互依赖的服务,并创建复杂的依赖关系图或反馈循环。每个网络跳都会给原始请求增加额外的延迟,特别是离开数据中心的南北网络流量。

这取决于保证的订单、交付或副作用

事件是异步的;因此,包含顺序或重复的假设不仅会增加复杂性,而且会抵消基于事件的体系结构的许多关键优点。如果使用者有副作用,例如在数据库中添加值,则可能无法通过重播事件进行恢复。

过早优化

大多数产品一开始很小,然后随着时间的推移而增长。虽然您可能梦想将来需要扩展到大型复杂组织,但是如果您的团队很小,那么事件驱动架构的额外复杂性实际上可能会降低您的速度。相反,考虑使用简单的体系结构来设计系统,但是要包含必要的关注点分离,以便您可以随着需求的增长将其替换掉。

期望事件驱动来修复所有问题

在较低的技术级别上,不要期望事件驱动的体系结构能够修复所有的问题。虽然这种体系结构肯定可以改进许多技术功能障碍的领域,但它不能解决核心问题,比如缺乏自动化测试、缺乏团队沟通或过时的开发-ops实践。

理解事件驱动架构的优缺点,以及它们最常见的一些设计决策和挑战,是创建尽可能好的设计的重要部分。 关于基于事件驱动的流程引擎和事件驱动与过程驱动的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。 基于事件驱动的流程引擎的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于事件驱动与过程驱动、基于事件驱动的流程引擎的信息别忘了在本站进行查找喔。
上一篇:索尔维向赛峰供应高性能热塑性膜
下一篇:资产智能运维平台(数据资产运营平台)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~