写点什么

事件总线实现方式汇总

  • 2017-08-07
  • 本文字数:1744 字

    阅读完需:约 6 分钟

基于事件驱动的分布式异步架构模式多用于构建高可伸缩的反应式应用程序,适用于各种从简单到复杂的应用场景。它的核心思想是去耦合,将消息的发送和接收分开,实现异步处理消息事件。架构师 Mustafa Turan 在 Hackernoon 上分享了事件总线的几种实现方式,并总结了每一种实现方式的优缺点。

事件总线是实现基于事件驱动模式的方式之一,或者可以将其称为“Broker Topology”。事件发送者将事件消息发送到一个中心broker 上,事件订阅者向中心broker 订阅和接收事件,然后再处理接收到的事件。当然,订阅者不仅可以接收和消费事件,它们本身也可以创建事件,并将它们发送到事件总线上。下面列出了4 种事件总线的实现方式,并对它们的优缺点进行了总结。

事件总线和多个订阅者(绿色箭头)和通知发送者(红色箭头)

1. 向所有的订阅者发送事件

事件总线直接将输入事件(红色箭头)发送给订阅者(蓝色方块)

参与者

事件总线、订阅者(事件处理器)、事件创建者

实现

事件创建者向事件总线发送事件,事件总线将收到的事件发送给所有的订阅者。订阅者既可以处理接收到的事件,也可以创建新事件,然后把它们发送给事件总线。事件总线不关心订阅者是否成功接收到消息。

功能需求

通知、订阅、退订。

优势

实现起来很简单。

不足

事件总线需要将每一个事件消息复制一份给订阅者,也就是说,如果有 1000 个订阅者,每一个事件都会有 1000 份拷贝,这样会占用大量的内存。

事件总线不保证消息传递的可靠性,它会尝试给订阅者发送消息,而且只会尝试一次,如果出现错误,比如网络连接错误,订阅者可能就会收不到消息。
另外,事件总线不负责过滤消息,所以订阅者需要自己实现过滤逻辑。

Elixir 的参考实现

2. 向所有订阅者发送事件影子


事件总线和事件存储及事件观察者

参与者

事件总线、事件创建者、订阅者、事件存储(Event Store)、事件观察者(Event Watcher)

实现

事件总线在收到事件创建者发送过来的事件后,把事件保存到事件存储里,然后将事件影子(Event Shadow,也就是对原始事件的引用)发送给所有的订阅者。订阅者根据事件影子从事件存储里获取事件数据,再对数据进行处理。

事件总线为每一个事件创建一个事件观察者,观察者持有订阅者列表,当所有的订阅者都接收到消息后,观察者负责把事件从事件存储里删除。

事件总线仍然不保证订阅者一定会收到所有事件影子。如果有订阅者接收消息失败,相应的观察者就会被标记为“skipped”。

功能需求

通知、订阅、退订、保存 / 删除 / 获取、标记完成 / 跳过

优势

因为事件消息被保存在事件存储里,发送给订阅者的只是事件引用,所以占用内存会小很多。

不足

订阅者需要调用额外的方法,比如在收到事件影子之后要调用方法去获取事件数据,在处理完事件后还要调用方法通知事件总线已完成处理,或者通知事件总线跳过某个事件。另外,在事件总线端还要实现事件存储和事件观察者。这个对事件存储的实现要求比较高,如果订阅者数量很多,事件存储的读负载会很重,而且在写入事件时是阻塞式的。

这种实现方式仍然不会为订阅者过滤事件,所以订阅者还是需要自己实现事件过滤。

Elixir 的参考实现

3. 向经过过滤的订阅者发送事件影子

第三种实现方式与第二种是一样的,只不过不是将事件影子发送给所有订阅者,而是发送给经过过滤的订阅者,也就是说只发送给其中的一部分订阅者。事件总线需要记录订阅者感兴趣的主题,在这里可以使用正则过滤器为订阅者过滤主题。

这种方式的优势与不足和第二种也是一样的,只是多了事件过滤功能。

Elixir 的参考实现

4. 按顺序传递

为了保证顺序传递,可以对事件进行分区。关于如何通过分区来保证顺序传递,可以参考 Kafka 的论文,基本原理是让消费者消费属于自己的分区。

不足

动态增加分区或减少分区会变得很困难,而且需要自己实现分区器,消费者的实现也很复杂。

在实现订阅者时要注意的一些问题

对于第一种和第二种方式,需要通过阻塞的方式进行事件类型(也就是主题)匹配,避免进行不必要的事件拷贝,浪费了内存。

对于第三种和第四种方式,需要通过非阻塞的方式进行事件类型(也就是主题)匹配,因为订阅者只接收感兴趣的事件。


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-08-07 19:004517
用户头像

发布了 322 篇内容, 共 143.1 次阅读, 收获喜欢 148 次。

关注

评论

发布
暂无评论
发现更多内容

TikTok海外直播专线:提供稳定、高效直播体验

Ogcloud

海外直播专线 海外直播 tiktok直播专线 海外直播网络 tiktok直播网络

VMware Workstation 17.6 Pro Unlocker & OEM BIOS 2.7 for Windows & Linux

sysin

macos vmware OEM BIOS Workstation

SD-WAN解决企业远程服务难题

Ogcloud

SD-WAN 企业组网 SD-WAN组网 SD-WAN服务商 SDWAN

通义灵码最全使用指南,一键收藏

阿里巴巴云原生

阿里云 云原生 通义灵码

飞书发布最强业务工具:新一代多维表格、低代码平台、飞书项目

ToB行业头条

从Milvus迁移DashVector

DashVector

数据库 向量检索 大模型 #人工智能

基于 TiDB 资源管控 + TiCDC 实现多业务融合容灾测试

PingCAP

零一万物开源 Yi-Coder 模型;原 OpenAI 首席科学家新公司 SSI 融资 10 亿美元丨 RTE 开发者日报

声网

低代码平台这么多,JNPF凭什么能火?

高端章鱼哥

通义灵码最全使用指南,一键收藏

阿里云云效

阿里云 云原生 通义灵码

天翼云,AI取经路上的逐梦人

脑极体

AI

AV-Comparatives确定2024年夏季的主要网络安全威胁

财见

电商创新策略:深度挖掘亚马逊国际商品详情API返回值

代码忍者

深入理解 Babel - 微内核架构与 ECMAScript 标准化|得物技术

得物技术

web前端 企业号2024年8月PK榜

JNPF低代码开发平台,一切尽在掌握

秃头小帅oi

Databend 产品月报(2024年8月)

Databend

淘宝商品详情API返回值中的优惠券与红包信息

技术冰糖葫芦

api 网关 API Explorer API 策略 pinduoduo API

分布式数据库系统环境的“无感”升级

PingCAP

Java核心知识体系-并发与多线程:线程基础

EquatorCoco

Java Python

高基数 GroupBy 在 SLS SQL 中的查询加速

阿里巴巴云原生

阿里云 云原生 sls

2024世界消费电子展览会

AIOTE智博会

消费电子展

使用Redis时不可原谅的几个低级错误

江南一点雨

网络管理方法及软件选择指南

Geek_a83400

淘宝商品详情API:优惠券与红包信息的深度解析

代码忍者

api 网关 API 策略

Redis 主从复制、切片集群

不在线第一只蜗牛

数据库 redis

听书APP创业者的救命稻草:源码在手,开发公司倒闭都不慌!

软件开发-梦幻运营部

面试场景题:一次关于线程池使用场景的讨论。

快乐非自愿限量之名

程序员 面试 线程池

进出口银行重庆分行支持航空飞机整机进口

科技热闻

探索魔乐社区:GLM-4V-9B模型微调之旅

天翼云开发者社区

人工智能 大模型

活动在即,不容错过丨亚信安慧AntDB诚邀您参加“PostgreSQL数据库技术峰会”

亚信AntDB数据库

AntDB 月PK

如何处理 MySQL 主从延迟?

伤感汤姆布利柏

事件总线实现方式汇总_架构_Mustafa Turan_InfoQ精选文章