Go 事件驱动编程:实现一个简单的事件总线

前言

在当今微服务和分布式系统盛行的背景下,事件驱动架构(Event-Driven Architecture,EDA)扮演着一个至关重要的角色,此架构的设计使得服务间可以通过事件进行同步或异步通信,替代了传统的直接接口调用。基于事件的交互方式,促进了服务之间的松耦合,提高系统的可扩展性。

发布-订阅模式是实现事件驱动架构的模式之一,它允许系统的不同组件或服务发布事件,而其他组件或服务可以订阅这些事件并根据事件内容进行响应。相信大部分开发者都接触过这一模式,常见的技术实现有消息队列(MQ)和 Redis 发布/订阅(PUB/SUB)功能等。

在 Go 语言中,我们可以利用其强大的 channel 和并发机制来实现发布-订阅模式。本文将深入探讨如何在 Go 中实现一个简单的事件总线,这是发布-订阅模式的具体实现。

准备好了吗?准备一杯你最喜欢的咖啡或茶,随着本文一探究竟吧。

事件总线

事件总线是发布-订阅模式的具体实现,它作为发布者和订阅者的中间件,管理着事件传递与分发,确保事件从发布者顺利地传达到订阅者。

图片[1]-Go 事件驱动编程:实现一个简单的事件总线-趣考网图片

事件总线的优势主要包括:

  • 解耦:服务间不需要直接通信,而是通过时间进行交互,减少服务间的依赖。
  • 异步处理:事件可以被异步处理,提高系统的响应性和性能。
  • 可扩展性:新的订阅者可以轻松订阅事件,不需要修改现有的发布者代码。
  • 错误隔离:事件处理的失败不会直接影响其他服务的正常运行。

事件总线的代码实现

接下来将介绍如何在 Go 语言中实现一个简单的事件总线,它包含以下关键功能:

  • 发布:允许系统的各个服务发送事件。
  • 订阅:允许感兴趣的服务订阅接收特定类型的事件。
  • 取消订阅:允许各个服务将本身已订阅的事件删除。

项目源码地址:https://github.com/chenmingyong0423/go-eventbus

事件数据结构定义

type Event struct {    Payload any}

Event 是一个封装事件的结构体,其中 Payload 为事件的上下文信息,类型是 any。

事件总线定义

type (    EventChan chan Event)type EventBus struct {    mu    sync.RWMutex    subscribers map[string][]EventChan}func NewEventBus() *EventBus {    return &EventBus{        subscribers: make(map[string][]EventChan),    }}

EventChan 是一个类型别名,定义为传递 Event 结构体的通道 chan Event。

EventBus 为事件总线的定义,它包含两个属性:

  • mu:一个读写互斥锁(sync.RWMutex),用于保证下面 subscribers 的并发读写安全。
  • subscribers:一个映射,键为字符串类型,表示订阅的主题;值为 EventChan 切片类型。该属性用于存储各个主体的所有订阅者,每个订阅者通过 EventChan 接收事件。

NewEventBus 函数用于创建一个新的 EventBus 事件总线。

事件总线的方法实现

事件总线实现了三个方法,分别为发布事件(Publish)和订阅事件(Subscribe)以及取消订阅事件(Unsubscribe)。

Publish 发布事件

func (eb *EventBus) Publish(topic string, event Event) {
eb.mu.RLock()
defer eb.mu.RUnlock()
// 复制一个新的订阅者列表,避免在发布事件时修改订阅者列表
subscribers := append([]EventChan{}, eb.subscribers[topic]...)
gofunc() {
for _, subscriber := range subscribers {
subscriber
© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享