知识卡片

消息、事件、命令的层次区分:Kafka记录混淆与"伪装命令"反模式

普通读书笔记卡

内容

[[命令与事件的语义区别推文与订餐邮件的类比]]谈的是语义层面的区分,而消息是承载这层语义的技术层面的通信负载——命令和事件都可能是某条消息的负载内容,二者的不同在于语义而非技术协议:命令既可以走REST,也可以通过异步消息放进队列发给专门的接收者;事件既可以理论上走REST feed(现实中很少这样做),也可以通过主题分发给任意数量的接收者。随着Apache Kafka等事件代理技术的兴起,术语混淆变得普遍——Kafka本身没有”消息”的概念,它存储的是”记录”(record),因为记录是持久化存储的,而传统消息系统传递完就会遗忘消息;但很多开发者习惯用”事件”来指代Kafka里的记录,因为默认认为Kafka是”事件总线”,这导致”事件”这个词在不同公司口中可能指两种不同的东西:负载里真正语义上的事件,或者只是”包含事件的一条消息(记录)”,容易引发误解,也让人误以为Kafka只能承载事件、无法承载命令——事实上完全可以把命令当作一条记录写进Kafka。这种混淆还催生了一个具体反模式:”伪装命令”(commands in disguise):如果开发者认定”所有要发送的东西都该当成事件”,就会把本质是命令的内容硬塞进事件的外壳里——比如”用户需要收到他们订单相关事件的通知”这句话本身就暴露了发送方有明确意图(希望用户被通知到),这不是事件而是命令,应该直接说”发送通知消息”,语义会清晰得多。

参考来源

- 位置:《流程自动化实战:系统架构和软件开发视角》第8章《平衡编排与编制》"8.2.2 消息、事件和命令"(源文件:_epub-src/EPUB/xhtml/Section0001_0012.xhtml) - 结论依据:原文说明消息是事件/命令共同的技术负载载体,Kafka用"记录"而非"消息"导致开发者混用"事件"指代记录的现象,并用"用户需要收到订单相关事件通知"的具体例子说明"伪装命令"反模式,直接支撑本卡片结论。 - 原始内容:这种情况之所以发生,是因为在Kafka中没有消息的概念。Kafka存储的是记录……如果开发者认为所有需要发送的内容都应该当成事件,那命令就被硬塞进(伪装成)事件了……这显然不是事件,因为发送方希望发生一些事情。