郑州三牛网站建设,个人网站怎么设计首页,wordpress 产品页 如何关联,网站开发干啥的比较官方的定义#xff1a;事件驱动是指在持续事务管理过程中#xff0c;进行决策的一种策略#xff0c;即跟随当前时间点上出现的事件#xff0c;调动可用资源#xff0c;执行相关任务#xff0c;使不断出现的问题得以解决#xff0c;防止事务堆积。在计算机编程、公共… 比较官方的定义事件驱动是指在持续事务管理过程中进行决策的一种策略即跟随当前时间点上出现的事件调动可用资源执行相关任务使不断出现的问题得以解决防止事务堆积。在计算机编程、公共关系、经济活动等领域均有应用。 事件驱动是很早作为术语出现在了 GUI 编程中比如用户在界面点击了按钮就会发送一个 “点击” 事件而相应的会有一个处理 “点击” 事件的事件处理器会来处理该事件。但实际 GUI 编程对他的定义与我们企业级的框架设计并不处于同一抽象级别。 文章目录一、三种异步通讯方式1、同步与异步2、请求响应的方式3、消息订阅的方式4、使用 Broker 的方式二、事件驱动设计1、关于事件驱动设计2、关于事件驱动与消息驱动3、事件驱动的优缺点4、事件循环器实现三、关于事件驱动架构的 Broker1、进程内 EventBus2、进程外 MQ一、三种异步通讯方式
1、同步与异步
系统间的通讯方式一般可分为同步通信和异步通信两种我们可以将将同步通讯理解为打电话需要实时响应而异步通信则可理解为发送短信不需要马上回复。我们往往会在面对超高吐吞量的场景下采取异步通讯因为这就好比一个人不可能同时接打很多电话但是他可以同时接收很多的电子邮件一样。
同步调用虽然让系统间只耦合于接口而且实时性也会比异步调用要高但是我们也需要知道同步调用会带来如下几个问题
性能和吞吐能力下降同步调用需要被调用方的吞吐不低于调用方的吞吐或者说整个同步调用链的性能会由最慢的那个服务所决定有额外的资源消耗同步调用会导致调用方一直在等待被调用方完成如果一层接一层地同步调用下去所有的参与方会有相同的等待时间。这会非常消耗调用方的资源。因为调用方需要保存现场Context等待远端返回所以对于并发比较高的场景来说这样的等待可能会极度消耗资源无法一对多同步调用只能是一对一的很难做到一对多有级联失败问题同步调用最不好的是如果被调用方有问题那么其调用方就会跟着出问题于是会出现多米诺骨牌效应故障一下就蔓延开来。
所以异步通讯相对于同步通讯来说除了可以增加系统的吞吐量之外最大的一个好处是其可以让服务间的解耦更为彻底系统的调用方和被调用方可以按照自己的速率而不是步调一致从而可以更好地保护系统让系统更有弹力。
异步通讯通常来说有三种方式请求响应的方式、消息订阅的方式、使用 Broker 的方式。
2、请求响应的方式
在同步的请求响应下发送方sender会直接请求接收方receiver被请求方接收到请求后直接返回请求方需要的数据。但是在异步的场景下对于被请求方来说收到请求后往往是需要一段相对较长的处理事件是无法直接返回的对于这种场景常见的是两种方式接口轮询、方法回调。
接口轮询发送方不断的去轮询接收方的接口问一下处理完了没有方法回调发送方注册一个回调方法也就是接收方处理完后回调请求方。这种架构模型在一部分的网上支付中会见到页面先从商家跳转到支付宝或银行商家会把回调的 URL 传给支付页面支付完后再跳转回商家的 URL。
很明显这种情况下还是有一定耦合的。是发送方依赖于接收方并且要把自己的回调发送给接收方处理完后回调。
3、消息订阅的方式
消息订阅的方式的情况下接收方receiver会来订阅发送方sender的消息发送方会把相关的消息或数据放到接收方所订阅的队列中而接收方会从队列中获取数据。
这种方式下发送方并不关心订阅方的处理结果它只是告诉订阅方有事要干收完消息后给个 ACK 就好了。
很明显在这种异步通讯的方式下我们抽出了一种“事件”并于此同时达到了无状态服务Stateless的目的请求数据、返回数据服务里面还可能需要保存调用的状态这其中有太多的好处无状态意味着我们可以非常方便地运维。
4、使用 Broker 的方式
对于“消息订阅”方式下接收方需要向发送方订阅事件所以是接收方依赖于发送方。这种方式还是有一定的耦合。所以我们可以将事件的承接方抽象出来这就是使用 Broker 的方式。
所谓 Broker就是一个中间人发送方sender和接收方receiver都互相看不到对方它们看得到的是一个 Broker发送方向 Broker 发送消息接收方向 Broker 订阅消息。如下图所示。 这是完全的解耦。所有的服务都不需要相互依赖而是依赖于一个中间件 Broker。这个 Broker 是一个像数据总线一样的东西所有的服务要接收数据和发送数据都发到这个总线上这个总线就像协议一样让服务间的通讯变得标准和可控。 二、事件驱动设计
1、关于事件驱动设计
比较官方的定义事件驱动是指在持续事务管理过程中进行决策的一种策略即跟随当前时间点上出现的事件调动可用资源执行相关任务使不断出现的问题得以解决防止事务堆积。在计算机编程、公共关系、经济活动等领域均有应用。
事件驱动是很早作为术语出现在了 GUI 编程中比如用户在界面点击了按钮就会发送一个 “点击” 事件而相应的会有一个处理 “点击” 事件的事件处理器会来处理该事件。但实际 GUI 编程对他的定义与我们企业级的框架设计并不处于同一抽象级别。
上面我们所提到的 “消息订阅” 和 “使用 Broker” 的两种方式都抽象出了事件并且二者也都是比较著名的事件驱动架构EDA – Event Driven Architecture因此事件驱动架构可以使用或不使用消息传递来实现
消息传递是以可靠、有保证的方式将生产者引发的事件传达给消费者的一种方式。特别是当生产者和消费者真正解耦并且可能托管在不同的服务器/虚拟机/环境中并且无法直接访问任何共享内存时。但是在特定情况下——当事件的消费者是在同一个应用程序本身内注册的函数/回调时或者当消费者需要同步执行时事件订阅可以在没有消息传递的情况下实现。
2、关于事件驱动与消息驱动
我们常常在提起事件驱动的同时提起消息驱动并也常将二者做比较并试图找出区别这里我借用stackoverflow 上一位答主的回答这也是我比较信服的 假设您正在为电子商务网站构建支付服务。下订单时订单服务将要求您的付款服务授权客户的信用卡。只有当信用卡被授权时订单服务才会将订单发送到仓库进行包装和运输。 您需要与处理订单服务的团队就信用卡授权请求如何从他们的服务发送到您的服务达成一致。有两种选择。 消息驱动下订单时订单服务会向您的支付服务发送授权请求。您的服务处理请求并将成功/失败返回给订单服务。初始请求和结果可以同步或异步发送。事件驱动下订单时Order 服务会发布一个 NewOrder 事件。您的支付服务订阅了该类型的事件因此它会被触发。您的服务处理请求并发布 AuthorizationAccepted 或 AuthorizationDeclined 事件。Order 服务订阅这些事件类型。所有事件都是异步的。 由此可以看出即使对二者含义加以区分时也不过可以将我们前面提到的 “消息订阅” 和 “使用 Broker” 的两种方式分别概括为事件驱动与消息驱动。因此笔者的结论是二者的本质上一致的都是抽象出了“消息“或”事件”来达到无状态异步调用的目的只是在实现方式上存在一定差别而且大部分人对二者认知也不统一所以在大的场景下二者可以当作同一回事即文中所提到的“事件驱动”
3、事件驱动的优缺点
# 事件驱动编程的优点
在大部分的应用场景中事件编程优与多线程编程相对与多线程编程来讲事件驱动编程比较容易复杂度低是开发者乐于接受的大多数的GUI框架都是使用事件驱动编程了架构的。每一个事件会绑定一个处理器这些事件通常是点击按钮选择菜单等等。处理器r来实现具体的行为逻辑事件驱动经常使用在I/O框架中可以很好的实现I/O复用。很多高性能的I/O框架都是使用事件驱动模型的例如Netty、Mina、Node.js易于调试。时间依赖只和事件有关系而不是内部调度。问题容易暴露。
# 事件驱动编程的缺点
构件削弱了自身对系统的控制能力。一个构件触笈事件时并不能确定响应该事件的其他构件及各构件的执行顺序不能很好地解决数据交换问题使系统中各构件的逻辑关系变得更加复杂。
4、事件循环器实现
事件循环器Event Loop是一个程序结构用于等待和发送消息和事件。事件驱动编程的代码核心就是事件循环器根据实现的方式不同在网络编程中基于事件驱动主要有两种设计模式 Reactor 和 Proactor。这也分别对应了我们前面提到的 “消息订阅” 和 “使用 Broker” 的两种方式。这里只做简单介绍
# Reactor 模式
首先来回想一下普通函数调用的机制
程序调用某函数-函数执行程序等待-函数将结果控制权返回给程序-程序继续处理
和普通函数调用的不同之处在于应用程序不是主动的调用某个 API 完成处理而是恰恰相反应用程序需要提供相应的接口并注册到 Reactor 上如果相应的事件发生Reactor 将主动调用应用程序注册的接口这些接口又称为“回调函数”。
# Proactor 模式
在 Proactor 模式下可以理解为当 I/O 事件触发的一瞬间I/O事件会自动进入一个队列中或者说一个容器中。当然进入容器前可能还要做一些处理比如将数据写入用户指定的缓存区等。而 Proactor 只需要主动地去该容器中取事件将 IO 完成的信息通知给用户线程。 三、关于事件驱动架构的 Broker
1、进程内 EventBus
EventBus 可以被用来在各种自定义的监听事件中使用包括不限于 Activity、Fragment、Service 等等等等需要进行数据传递的地方不过应该只局限于 app 内部。
对于 EventBus 各种编程语言中都有着自己的实现这里不做过多赘述
2、进程外 MQ
目前系统中的异步通信主要是采用消息中间件消息中间件采用的异步方式为 broker 方式。
比较常见的 MQ 实现
ActiveMQ较早推出的消息中间件功能强大社区也非常成熟有较多的文档。已经在很多公司和项目中得到应用各种协议支持较好有多个语言的成熟客户端。主要用于中小型项目的解耦和异步处理。RabbitMQ基于erlang开发所以并发能力很强性能极好延时很低。社区比较活跃版本迭代较快有比较稳定的支持。开源提供的管理界面较丰富用起来很方便有多个语言的成熟客户端。中小型公司首选对消息有顺序要求的场景除外。RocketMQ接口简单易用可以做到大规模吞吐性能也非常好分布式扩展也很方便。可以支撑大规模的topic数量支持复杂MQ业务场景经过多次阿里双11大考可靠性和可用性值得信任。源码是java我们可以自己阅读源码定制自己公司的MQ可以掌控。适合大型互联网应用。Kafkakafka的特点其实很明显就是仅仅提供较少的核心功能但是提供超高的吞吐量ms级的延迟极高的可用性以及可靠性而且分布式可以任意扩展同时kafka最好是支撑较少的topic数量即可保证其超高吞吐量。社区活动度比较高。用于大数据领域的实时计算、日志采集等场景是业内标准。