基于 Kafka 实现分布式事件驱动

本文探讨了基于 Kafka 实现事件驱动架构的方法,分析了事件驱动的优缺点,以及如何处理分布式系统中的数据一致性问题。文章详细介绍了事件的发布和消费,通过引入 DB 事件表和利用 Zookeeper 进行任务分配,确保了系统的可靠性和性能。最后,通过订单统计的例子展示了事件驱动的实际应用。
摘要由CSDN通过智能技术生成

事件驱动是一种灵活的系统设计方法,在事件驱动的系统中,当数据发生变化时系统会产生、发布一个对应的事件,其它对这个事件感兴趣的部分会接收到通知,并进行相应的处理。事件驱动设计最大的好处在我看来有两点:一是它为系统提供了很好的扩展能力,比如我们可以对某类事件增加一个订阅者来对系统进行扩展,最主要的是我们并不需要修改任何已有的代码,它完全符合开闭原则;二是它实现了模块间的低偶合,系统间各个部分不是强依赖关系,而是通过事件把整个系统串联起来。

当然,任何事务都有两面性,事件驱动也有其不好的方面。首先,实现一套这样的系统复杂度就很高,对开发人员的要求也很高;再次,对系统的整体把控会很困难,想象一下面对几百个类别的事件,并且没有一个统一的地方可以让我们看到整个业务处理流程,会是什么心情?所以当我们决定采用事件驱动实现系统中,一定要维护好相关的文档,并保持它们的有效性。

我们再来看看事件驱动架构的一些其它的优点:

  • 更好的响应性

    事件驱动中,事件的响应是异步处理的,所以它具有更好的响应性。

  • 更好的容错性

    业务主流程在发布事件之后便结束了,扩展流程的延后处理可以异步不断的失败重试,直到成功为止,系统整体容错性更强。

设计篇

首先,我们需要定义什么是事件?从业务角度看,事件包括以下属性:

事件的定义
属性 字段 类型 说明
标识 ID string 系统内部每个事件都需要一个唯一的标识。
类型 eventType string 数据发生变化产生事件,不同类型的数据变化产生不同类型的事件。比如会员下单、会员注册、用户修改手机号等等。
时间 eventTime datetime 即数据发生变化的时间。
上下文 context string 事件发生时的上下文信息。比如会员修改手机号事件,需要原号码和新号码,会员 ID 等信息。

接下来,我们看看如何设计一套基于事件驱动的系统,你知道设计模式中的观察者模式吗?

观察者模式 :定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

观察者模式天生就是事件驱动的一个实现,但是直接使用它有很多的弊端。首先,它是基于主题的,有多少类事件就需要多少个主题类,这可能会导致类爆炸;其次,观察者模式是同步实现的,这样我们可能会牺牲掉响应性和容错性等优势。

所以我们需要对观察者模式稍作改进,我们分别从事件发发布和消费两个方面来分析。

事件的发布

本文的标题是《基于 Kafka 实现事件驱动架构》,很明显,我们使用 kafka 作为消息中间件来传递事件消息。所以,像修改会员手机号码的代码可能实现如下:

@Transactional(readOnly =false, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
@Override
publicvoidchangePhoneNumber(String newNumber){
userDao.updatePhone(this.getUserId(), newNumber);// 本地数据库修改

// 发布 用户手机号码变更 事件
Event event =newEvent(...);// 创建一个事件对象,表示用户修改手机号码
ProducerRecord record =newProduce
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值