这是一篇老文章了,之前换工作的时候,我还特意留意了一下新公司的队列方案,看到他们内部 2019 年刚刚支持了 schema registry 所以在线上可能也并没有广泛的应用。只是这家新公司业务都是 java,大概没有像使用 PHP 的公司那么痛吧。

下面是正文。

MQ 对于业务系统建模非常重要,是解决分离关注点、依赖反转、CQRS、最终一致等业务问题的重要法宝。

然而企业对于 MQ 中的数据管理却并不重视。从互联网企业发展的历程来看这个问题,最初 MQ 不是很可靠,大家不会把让特别重要的业务依赖 MQ,所以接入到 MQ 的业务事件并不多。总共也就两三个 topic,开发相应的系统对这些内容进行管理看起来没什么必要,甚至可能连详尽的业务信息都要从生产者的代码注释中去寻找。公司规模不大,这些都是可以接受的。

经历过 1Mb 小水管的朋友大概还记得当初火爆的 Flashget 的 Slogan:

下载的最大问题是什么——速度,其次是什么——下载后的管理。

虽然 Flashget 命运多舛,但不妨碍我们学习这种思考方式。当下载任务较多的时候,我们会非常直觉地对下载任务进行多级类别划分(这个目录是游戏;这个目录是用来学习的,那个目录,嗯。。也是用来学习的!),甚至需要给一些任务补充相应的标注(例如这个软件是从哪里下载的;在安装的时候会有什么问题;绕过了什么样的坑才能正确地让它工作)。因为已经使用过太多的工具,受过太多相应的教育和训练,“分类”和“元信息”管理已经深深刻入了我们的思想。

除了分类和元信息管理,对于在下载工具里下载好的任务,我们肯定要试试能不能用,好不好看。如果是垃圾,那自然得删;如果是宝贝,那肯定是要留下来。这可以理解为一种人肉“校验”。

虽然分类、管理和校验是非常显见的道理,在面对同类问题时,很多企业却在此陷入困境。

通常来讲,企业中和 MQ 打交道的团队可以分为三种角色:

  1. 消息生产者,大多为业务流程系统,KPI 是给系统增加功能,加的越多越好,并希望其它部门尽量不要阻碍我们加功能。MQ 里的消息 80% 其实和他们自己的业务无关,主要提供给下游进行统计、计算、判责、场景还原等等。剩余 20% 可能涉及到业务状态流转。

  2. 消息消费者,一般是另外的团队,这里面可能有进行业务指标计算的团队;有基于数据指标做运营的团队;有基于统计接入机器学习(其实也是运营啦)的团队;还有涉及安全、antispam 等等周边支持团队。这些团队对于 MQ 中的数据是非常关注的。

  3. MQ 开发/运维团队,对于这些人来说,MQ 中的数据并不是他们关注的重点。不管你消息长什么样,对于他们来说只不过是一些 byte 数据。他们只关注 MQ 本身的技术特性和运维需求。

三方各怀鬼胎,真正关心 MQ 数据的只有整个消息流的末端团队,因为这里面的数据是真的关系到他们自己的 KPI,要是数算错了钱多发了,薅羊毛的没封了,那都是直接资损。

然而 MQ 两端的业务团队在大多数情况下却是 DDD 中讲的 conformist 关系:

追随者-Conformist 当两个开发团队具有上/下游关系时,如果上游团队没有动机来满足下游团队的需求,那么下游团队将无能为力。出于利他主义的考虑,上游开发人员可能会做出承诺,但他们可能不会履行承诺。下游团队出于良好的意愿会相信这些承诺,从而根据一些永远不会实现的特性来制定计划。下游项目只能被搁置.直到团队最终学会利用现有条件自力更生为止。下游团队不会得到根据他们的需求而量身定做的接口。这时候“客户/供应商”模式就不凑效了,那么下游系统只能去追随上游系统,下游系统严格遵从上游系统的模型,简化集成。

这些问题本质上是公司的组织架构导致的,但你非要说把安全之类的团队也合并到业务部门来比较扯。很多情况下上下游就是会分属不同部门,这会触发各种意想不到的糟糕问题。所以 DDD 中比这个 Conformist 更靠前的是 Customer/Supplier 模式:

客户/供应商-Customer/Supplier 不同系统之间存在依赖关系时,下游系统依赖上游系统,下游系统是客户,上游系统是供应商,双方协定好需求,由上游系统完成模型的构建和开发,并交付给下游系统使用,之后进行联调、测试。这种模式建立在团队之间友好合作和支持的情况下。当两个具有上游/下游关系的团队不归同一个管理者指挥时,Customer/Supplier这样的合作模式就不会奏效。勉强应用这种模式会给下游团队带来麻烦。

而所谓的 Customer/Supplier 模式又是一种纯粹的理想,是不现实的。部门都拆了,老板总归是不能尿到一个壶里的。虽然现状有点令人绝望,作为技术人员还是希望能有一点曙光。来分析一下这个问题:

无论企业实际使用了上述两种模式的哪一种,消息总还是上游发出的。要求上游系统成为其发出的业务消息的 owner 是一件比较自然的事情。

只有 owner 机制也不够,企业里所谓的业务 owner 所能提供给你的帮助,也就只限于对接的时候负责在工作 IM 上陪你聊天,告诉你这个 topic 里有哪些字段,你需要的字段要用什么样的 jpath 去找。再稍微自觉一点的团队会维护一个文档,介绍领域消息内包含什么内容,做过哪些需求。当文档不是 KPI 的时候,慢慢地也就不再更新了。

这种工作方式把业务信息的维护和上游消息的数据稳定性全部押注在了上游 RD 的良心上,显然是不靠谱的。更好的方式还是用技术手段解决这里的技术问题,可以有以下一些考量:

  1. 由特定团队提供专门的消息生产 SDK,对所有业务消息进行 schema 管理。消息生产环节的代码要求必须提供带特定格式的注释,如:@name 表示字段名,@type 表示数据类型,@enum 提供可能的枚举值。从结构体可以推断出最终序列化后的数据长什么样。并且在代码修改上线时,对代码进行扫描,提取所有相关的业务消息字段注释,自动生成相应文档。

  2. 如果团队技术实力实在不行,做不出自动生成文档的能力。也可以提供一个 schema 管理和异步数据校验的 validation 系统,在系统外部对数据 schema 进行管理,并不断消费上游的消息,以判断新来到的消息是否符合其 schema 定义。若有不符合期望的数据,则对上游值班人进行 on-call 报警,要求修复 schema 描述。

如果实现的是方案 2,理论上还可以开更大的脑洞。除了对 schema 管理外,还可以做一些复杂的逻辑校验,包括对数据的内容,逻辑,连续性,分布进行校验。并由所有下游业务方来配置其期望的校验规则。

后记

虽然本文现在才发,但几年前已经有了相关的想法。期间因为种种原因,这样的平台一直没有办法立项。中间某司断断续续也遇到了无数和上游系统重构导致的下游系统故障的问题,还是没有看到任何改进的迹象。

直到最近看到 Google 的工程论文:data-validation-for-machine-learning[1]。其出发点是为了避免上游的错误数据影响到下游的模型训练结果。但本身 schema 管理,数据 validation 系统是可以泛用的,既然有很多系统依赖上游系统的 schema 和数据正确性,那就应该对这些 schema 和正确性进行管理。

遗憾的是 Google 可以有这样的项目,而我们却依然只能靠人肉去为这些无聊的故障做兜底。

如果各位读者的公司有类似的场景和项目,欢迎在留言区留下你的想法~

[1]

data-validation-for-machine-learning: https://blog.acolyer.org/2019/06/05/data-validation-for-machine-learning/

欢迎关注 TechPaper 和码农桃花源:

MQ 正在变成臭水沟相关推荐

  1. 《微服务架构设计模式》总结,文末送书

    经常翻阅微服务材料的话,总会碰到 microservices.io 这个网站,总结了微服务方方面面的设计模式.网站的作者是 Chris Richardson. 这些相关的经验在 2018 年成为了&l ...

  2. 在公司的微服务上搞破坏真是太开心了

    这是四年前伦敦一个技术大会上的一场非常独特的分享,没想到一场技术大会上能有这么幽默的另类架构师,作者以反讽的形式举出了 10 个微服务环境下对系统搞破坏的 tips.我看了很多遍,其中的案例其实日常研 ...

  3. 「Go 实战营系列」微服务架构设计模式

    经常翻阅微服务材料的话,总会碰到 microservices.io 这个网站,总结了微服务方方面面的设计模式.网站的作者是 Chris Richardson. 这些相关的经验在 2018 年成为了&l ...

  4. 曹大:2020 年我学到了什么

    最近在面试的时候,和面试官说 A 家有比较先进的业务架构和基础设施,被人要求一一列举,一时语塞(这么多东西,我半小时实在给你说不完),才想起来去年本来答应老东家的同事要总结一些两家的业务和基础设施之间 ...

  5. 企业新站上线应注意的几个问题

    在随着互联网的发展,越来越多的中小型企业都会建设一个网站来支撑门面,但是很多公司人员在看到别人的网站如何如何漂亮,就二话不说,直接照搬过来.可等网站上线的时候,发现这里不对那里不对,又将网站改着一塌糊 ...

  6. 机器人学习--卡尔曼滤波及各种滤波解析

    什么是滤波?举个最直观的简单例子:臭水沟里舀一大勺水,需要过滤成干净水怎么办?,,,用滤网(网孔可根据需要选择大小孔)过滤. 在电路方面波形的高低通滤波原理类似: 图像上的噪声点各种中值滤波等类似的滤 ...

  7. 温柔得叫人想死:日本电影《火宅之人》手记

    <火宅之人>是日本导演深作欣二在八十年代监督的情感伦理片.女主角之一由后来出演<桃色>的松坂庆子主演.<桃色>中的她虽然魅力犹存,但已经失去了年轻时的青春.活力和性 ...

  8. 吃PHP小孩智力好,这7种鱼千万不能给孩子吃,会影响孩子的智力!

    所以,给宝宝添加鱼类时一定要注意,有7种鱼含有大量金属元素,是千万不能给宝宝吃的! 1罗非鱼 罗非鱼深青色的外表有几分像鲫鱼.由于罗非鱼的成长周期较长,它们体内汞的含量也就相比其他鱼偏高,小朋友吃罗非 ...

  9. 蓝牙耳机声音一顿一顿的_线控耳机党阵地转移成功,OPPO这款TWS耳机体验满分...

    "你看到我手机里3.5mm的耳机孔了吗",这可能是许多线控耳机党最想说的话了.确实,如今手机在做"减法",而厂商们首先就拿3.5mm耳机孔"开刀&qu ...

最新文章

  1. Oracle 11gR2构建RAC之(3)--安装grid前环境检测
  2. 99% 的新移动恶意程序是针对 Android
  3. 移动master 数据库
  4. 插播面试题:海量数据求最大值Topk或者是最小值Topk
  5. javafx 项目_JavaFX,Jigsaw项目和JEP 253
  6. Java 获取集合元素的值
  7. WebHeaderCollection 类
  8. 个性化新闻文章推荐的上下文Bandit方法
  9. SVN使用过程中出现“工作副本已经锁定”的解决办法
  10. abb机器人离线编程软件叫做_Robotstudio软件:ABB机器人机器视觉位姿引导虚拟仿真...
  11. c语言自动生成邻接矩阵,01邻接矩阵的创建C语言实现
  12. UAV进阶论文和书籍
  13. 前端面试题精编2020(js、html、小程序、React、ES6、Vue、算法、全栈热门视频资源)持续更新
  14. python源代码制作星空_用python画星空源代码是什么?
  15. 大数据学习——克隆虚拟机
  16. 计算机网络重要知识点总结(期末复习笔记)
  17. 实现同网段不同vlan通信有几种方式?纯二层网络下又是如何实现的?
  18. SVN 具体某一行代码是谁添加的
  19. Socket/Tcp游戏通信(一)-IP和端口号
  20. android 类似按键精灵脚本_Android拓展 lua实现类似按键精灵效果

热门文章

  1. WIN10安装ubuntu全过程
  2. 深度学习原理与框架-卷积网络细节-数据增强策略 1.翻转 2.随机裁剪 3.平移 4.旋转角度...
  3. 65.4. Other GUI - phpOraAdmin
  4. C语言之从内存角度理解不同类型的变量
  5. web.xml中相关标签的加载顺序
  6. uedit富文本编辑器
  7. 让一个python源文件也能像bat批处理文件那样运行[转]
  8. 接口隔离原则(设计模式4)
  9. Tmux : GNU Screen 的替代品
  10. 超简单JS实现把鼠标选中文字发送到新浪微博