写点什么

事件总线实现方式汇总

  • 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:004957
用户头像

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

关注

评论

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

python游戏开发-pgzero

AIWeker

Python python小知识 三周年连更

超级App的构建与技术驱动

没有用户名丶

内蒙农信携手星环科技建设农信大数据平台,激活金融业务创新

星环科技

数据要素流通

支持多模型数据分析探索的存算分离湖仓一体架构解析(下)

星环科技

湖仓一体

厦门等保备案平台是哪个?多久可以办好?

行云管家

等保备案 厦门

【获奖案例巡展】信创先锋之星——浙江省某市区视频能力中心

星环科技

大数据

【获奖案例巡展】信创先锋之星——中信证券基于国产图数据库构建企业图谱的应用实践

星环科技

国产数据库

iOS MachineLearning 系列(6)—— 视频中的物体轨迹分析

珲少

ShareSDK Google平台注册指南

MobTech袤博科技

灵活、快捷、低运维成本的数据集成方法:数据联邦架构

星环科技

数据集成 数据联邦结构

共建清洁能源岛!华为中国数字能源旗舰峰会海南站盛大举行

极客天地

用C++编写一个简单的发布者和订阅者

华为云开发者联盟

开发 华为云 华为云开发者联盟 企业号 4 月 PK 榜

火山引擎 DataLeap 下 Notebook 系列文章三:架构升级详解

字节跳动数据平台

大数据 架构 数据治理 运维‘ 企业号 4 月 PK 榜

c4d R2023 让您的三维动画设计更简单~~

真大的脸盆

Mac Mac 软件 三维动画设计 动画设计工具

宝塔人机识别验证:如何确保人脸识别的安全性?

百度开发者中心

人脸识别 人工智能’

面试官:HashMap线程不安全体现在哪里?

什么是存算分离架构?

星环科技

存算分离

【获奖案例巡展】信创先锋之星——甘肃省住房和城乡建设厅住建数据大脑

星环科技

数据超脑

神了!阿里P8级数据库专家手写出了这份438页数据库高效优化手册

Java 数据库 sql 性能优化

屌的一批!阿里P8推荐的Spring Cloud实战笔记

小小怪下士

Java 微服务 SpringCloud

火山引擎DataTester智能发布平台:智能化A/B实验,助力产品快速迭代

字节跳动数据平台

大数据 AB testing实战 A/B 测试 企业号 4 月 PK 榜

分析型数据库:分布式分析型数据库

星环科技

分析型数据库

支持多模型数据分析探索的存算分离湖仓一体架构解析(上)

星环科技

湖仓一体

【获奖案例巡展】科技向善之星——中航电梯5G+大数据管理平台

星环科技

大数据管理

【Python实战】Python采集大学教务系统成绩单

BROKEN

三周年连更

软件测试/测试开发丨Docker 容器技术与常用命令

测试人

Docker 软件测试 自动化测试 测试开发

临沂等级保护测评机构有几家?在哪里?

行云管家

等保 等级测评 临沂

高性能、快响应!火山引擎ByteHouse物化视图功能及入门介绍

字节跳动数据平台

大数据 数据仓库 云原生 Clickhouse 企业号 4 月 PK 榜

在高校内投放共享电单车有什么优势

共享电单车厂家

共享电动车厂家 景区共享电单车 共享电单车投放 校内共享电单车 共享电单车优势

Wallys/DR7915/MT7915/MT7975/industrial mini pcie card /support openwrt

Cindy-wallys

MT7975 MT7915

Spring Cloud Stream:打造强大的微服务事件驱动架构

Java 微服务 spring cloud stream

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