基于业务表 Binlog 的事件驱动设计

我们的订单事件服务是事件驱动设计在订单领域的一个实践。订单系统将订单表 Binlog 作为事件源,通过基于 Canal 的 Binlog 服务转换为 MQ 消息,然后我们的订单事件服务将消息转换为订单业务事件,驱动后续业务流程。

接下来给大家介绍一下此设计方案的优点和在实践过程中需要注意的细节。

一、优点

这么设计好处有以下几点:

  1. 简化事件设计,集中事件生成规则
  2. 简化数据一致性设计
  3. 提高前台业务服务稳定性

接下来分别介绍一下。

简化事件设计,集中事件生成规则

在之前的设计中,订单事件是由前台系统直接在订单数据更新成功后发出。通过业务代码判断订单事件类型,不同的接口,不同的系统都会耦合不同的事件生成规则。这导致底层的订单事件生成规则不统一,存在重复的问题。这些问题在引入订单事件服务,通过 MySQL Binlog 消息生成订单事件后得以解决。订单事件生成规则集中到了订单事件服务中,可维护性和规则清晰度都有明显提升。

简化数据一致性设计

如果让业务在更新数据后直接发消息,需要考虑如何保证数据库和 MQ 的数据一致。如果数据库事务提交成功,MQ 发送失败,怎么办?通常的方法是重试,实现最大努力通知。但重试也有细节问题,同步重试容易导致服务线程挂起时间过程,异步重试又需要考虑如何保持重试任务。当然这些都有办法解决,但通常代价都是严重增加了业务系统设计的复杂度。

因此,通过使用使用 Binlog 驱动的事件设计,可以降低前台业务系统在这些方面的设计难度,将技术细节和优化工作下沉至底层。

提高前台业务系统稳定性

前台业务系统直接依赖 MQ 在当时使用 ActiveMQ 时更为明显,ActiveMQ 服务不稳定,抗消息积压能力差。前台业务系统直接作为消息 Producer 依赖 MQ Broker 势必会降低系统整体的可用性和稳定性。

二、需要注意的细节

但使用订单表的 Binlog 作为事件源的设计方法有几个技术细节需要注意。这些细节不注意就很容易引起线上问题(别问是怎么知道的)。

第一,数据库运维所带来的影响

第二,注意 Binlog 写入和事务生效时机

第三,注意链路上各服务的稳定性和可用性

接下来详细介绍这三点

数据库运维带来的影响

直接使用业务数据表作为事件表虽然简化了业务系统开发工作,但是增加了运维工作潜在影响的可能。当数据库需要增加字段、增加索引时。传统的 MySQL alter 语句显然不能使用,因为这个会导致锁表,影响线上服务。常用的方法是使用如 GitHub 开源的 gh-ost 工具、Percona 开源的工具,将整个数据表拆分为小块进行运维工作。但这样会导致每条数据都会产生一条 Binlog 数据,最终导致巨量 Binlog。具体来说,在做分库分表之后,最近一段时间内,每个表依然有百万级的热数据,如果短时间内完成运维工作,将导致大量 Binlog,从而加重 Binlog 消息系统负载,使得真正的业务 Binlog 消息无法及时处理,导致业务延迟。因为会员订单业务要求用户支付成功后秒级完成权益开通,所以这样的延迟极易导致线上保障。

解决的方法是数据库运维平台增加了数据表分块运维的间隔,降低了速度,减缓 Binlog 产生速度。同时,Binlog 消息平台做出相应优化,加快处理速度。目前新版的 Binlog 消息平台速度比过去提高了两倍。

但降低运维速度又产生新的问题,那就是加索引加字段可能需要一天的时间才能完成,有时对业务还是不容忽视。

解决这个问题有两种方法,控制业务表数据量和使用专门的事件表。此外在大厂自研的数据库也有一些解决方法,不过细节我暂时不清楚,了解的同学可以给我留言。

Binlog 写入和事务生效的时机

这个问题之前专门写文章介绍过,这里在重复一下。订单事件发出后,后续业务系统通常会再次检查订单状态,保证业务逻辑的严谨。但在事件中,我们发现过订单事件发出后,当后续系统检查订单状态时,发现主库中订单状态还是之前的,导致业务处理被跳过。

这个问题的原因是 MySQL 写 Binlog 和 InnoDB 引起更新数据页是整个事务提交动作中的两步,有前后关系。所以实际当 Binlog 发出后,数据页的内容有可能尚未变更,导致后续系统查到的数据依旧是旧的。

这可以通过在业务状态检查上适当增加重试解决。

注意链路上各服务的稳定性和可用性

在使用基于业务表 Binlog 的事件驱动设计后,整个业务链路增加了一个 Binlog 平台和一个 MQ,整个链路更加复杂。理论上依赖越多,可靠性越差,因为整体可靠性是每个分部可靠性的乘积。

为了解决这个问题,我们又为关键的订单业务处理增加了不依赖订单事件的备份通路,保证当订单事件机制出现技术问题时,核心流程依旧可使用备份通路完成。为保证备份通路和正常通路的可用性和业务逻辑与基于订单事件的处理保持一致,两者都是基于相同的系统,只是接受数据的方式存在不同。

三、如果重新设计

如果重新设计订单事件驱动设计,我会考虑将订单创建、更新操作从业务系统下沉至订单平台中的订单核心服务。在其中引入订单事件表,使用 JSON 存储数据,引入基于订单号的局部消息顺序设计,加强数据一致性。具体设计这里就不详细介绍了,欢迎大家交流讨论。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352