所谓事件驱动,简单地说就是你点什么按钮(即产生什么事件),电脑执行什么操作(即调用什么函数)
当然事件不仅限于用户的操作事件驱动的核心自然是事件。而事件本质上就是状态的运动或变化
非事件驱动 vs 事件驱动
事件驱动组件
事件驱动架构是软件架构和应用设计的一种,常见于分布式异步架构模式。
事件驱动的从事件的不同可以划分为3种模式
事件驱动架构从架构拓扑角度可以分为2种类型拓扑模型
1.Mediator模式:Mediator模式适合有多个步骤的事件,需要安排处理层次和顺序。Mediator会将初始事件编排成处理事件。它没有具体的业务逻辑,只是一个协调者,负责将初始事件转化成一个或者多个处理事件。
2.Broker模式:Broker不同于上面的结构,它没有中心的Mediator。所有的事件串联起来通过一个轻量级的消息broker来分配具体的消费对象, broker中的event channel可以是消息队列,消息topic。如RabbitMQ,ActiveMQ都是实现这种模式。
事件驱动编程模型 VS 其他编程模型
事件驱动编程通常只是用一个执行过程,CPU之间不是并发的,在处理多任务的时候,事件驱动编程是使用协作式处理任务,而不是多线程的抢占式。事件驱动简洁易用,只需要注册感兴趣的事件,在回调中设计逻辑,就可以了。在调用的过程中,事件循环在等待事件的发生,跟着调用Handler,事件Handler不是抢占式的,Handler一般只有很短的生命周期。
Event Loop(事件循环器)
事件驱动之浏览器JS
事件驱动之网络编程模型(Reactor)
A) 单Reactor 单线程: Reactor模式工作原理:使用一个单线程的event-loop 以blocking的方式等待事件,然后把所有的事件分发给相应的处理器和回调
1.应用在Dispatcher上注册Event Handler,这样Dispatcher就能够知道在什么事件发生的时候调用什么Handler. 每个EventHandler都有关联的底层handle。
2.Dispatcher会把所有的关联的handles都交给事件分离器来进行监听。
3.当有事件发生时,事件分离器会把事件通知给Dispatcher,后者调用回调处理器进行处理B) 单Reactor 多线程: Reactor 线程负责多路分离套接字, Accept 新连接, 并分派请求到处理器链中, 处理器链多线程来完成
C) 主从Reactor 多线程: Reactor 分成两部分, mainReactor 负责监听 server socket, accept 新连接, 并将建立的 socket 分派给 subReactor。subReactor 负责多路分离已连接的 socket, 读写网络数据, 对业务处理功能,其扔给 worker 线程池完成
事件驱动之生产者消费者模型
购吖供应链体系问题
业务订单系统(OMS)
购吖OMS系统承担的责任
设计思考一
Q1.1:OMS作为调度核心,关联的TMS(配送端)和WMS(仓储端)是比较标准的业务流程和场景,所以他们和OMS间交互的模型和输入输出是不是能够统一标准?
Q1.2:OMS故障时最好不要影响TMS(配送端),所以TMS各个完成步骤提交并通知OMS时是不是可以采用异步的方式?
思考结论A1:
设计思考二
Q2.1: 将TMS和WMS和配送相关的请求事件化之后,其对应具体执行的业务逻辑能不能也包含在其事件模型中,类似充血模型
Q2.2:OMS作为TMS和WMS的协调者,往往其调用模式是有固定套路的,那么最好是将发起请求方和通知调用方分开到不同的模块
TMS发起请求-->OMS 执行业务-->通知WMS
WMS发起请求-->OMS 执行业务-->通知TMS
Q2.3:事件模型和事件处理方在进程内是否也能尽量解耦,同时他们间最好能有一个统一的中间层进行管理和方便扩展,以便实现诸如异步、嵌套冒泡等能力。
思考结论A2
设计思考三
Q3.1:OMS系统的执行主要就是操作4张表,请求命令日志表,订单商品锁定表,订单表,订单明细表,每次写类型的操作都会依次更新或插入,涉及的如记业务日志,如开闭事务,如给商品加锁解锁能否采用一种公共的机制抽象出来, 同时不同的表操作让不同的代码块负责,这样代码组织既按单个功能隔离又能按整体业务形成依赖?
Q3.2:通过命令模式,我们把请求方和最终处理方解耦了,但是这这个过程中,我们还有可能需要对请求数据做上下文的扩展,不可能把这部分统统都放到命令模式的处理器中,那么要怎么做才能为以后的扩展留出足够的灵活度?
思考结论A3
设计思考四
Q4.1:通过责任链模式,每个拦截器做各司其职,一些功能类的拦截器如日志拦截器,事务管理拦截器命令调用器等职责比较单一,预计未来改动性也不大,而一些比如业务类的订单拦截器,订单明细拦截器,商品锁定拦截器等会根据不同的事件类型有不同的操作逻辑,如何更好的解耦,避免一堆的if-else硬写在拦截器中?
思考结论A4
OMS总体架构(类似Mediator模式)
购吖为什么要用事件驱动?
购吖处在智能零售这样一个高速增长和变化的赛道,原来的单体架构耦合度太高已经无法适应快速迭代和响应的开发节奏,服务拆分势在必行,而事件驱动是一个很好的切入方式:
解决耦合(A模块->直接调用->B模块,A 需要明确知道 B 的存在,那么它们之间是耦合的,A 依赖于 B,这使得系统难以维护和迭代)
让系统更变得有组织性(A团队开发A模块 ,B团队开发B模块,互相开发内部功能互不影响,各个组件可以单独迭代)
OMS系统架构设计中运用了很多设计模式,那我们为什强调OMS是基于事件驱动思想的?
在OMS中使用了责任链模式,而事件驱动模型其实也可以是一种典型的“责任链”模型(Mediator模式):
1.接收者之间可以动态组合搭配,可增可减并改变组合顺序
2.每个接收者都有机会响应事件,而每个事件由可以被多个接收者同时处理
3.对于已经处理过的事件,接收对象可以选择停止派发,也可以选择继续派发
4.每个接收者只处理自己职责范围内的事件或事件中的信息,其他忽略以减少外部耦合
在OMS中使用了命令模式,而事件驱动天生就是符合命令模式设计的最大初衷:将命令发送方和命令执行方分离
在OMS中外部交互中,TMS交互事件大量采用消息异步通知的模式
在OMS内部广泛采用进程内事件EventBus进行解耦和模块间通信
xshn, 信也科技技术架构资深专家,目前主要负责智能零售相关业务购吖各平台的设计和研发工作。
http://www.mrdear.cn/posts/design-patterns-event_design.html https://copyfuture.com/blogs-details/20200317182850084nlebdqpsdo4gr13 https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ https://zhuanlan.zhihu.com/p/328886142