站在不同的角度看待同一个问题,会得出不同的结论。对于程序的实现也一样。

一、查询功能实现的罗生门

不久前公司遇到一个场景,也是微服务状态下肯定会遇到的一个场景(以下对比真实情况有所抽象和改编):

  • 某一个服务A,需要实现一个较为边缘的功能;

  • 这个边缘功能需要用到另外一个服务B管控的大量数据用于展示;

  • 同时对于展示的数据需要打一个标志(更新),该标志后续需要用于过滤显示的数据。

对于这个功能需求,实现无非包含三个大方向:

  • 实现一、服务A直接利用服务B的数据库进行查询及更新;

  • 实现二、服务A的数据库导入服务B里所有需要的数据,然后服务A在其自身的数据库中对数据进行更新;

  • 实现三、服务A自行存储打标志信息(更新),需要B的数据时直接向服务B实时查询,服务A在应用代码中合并多方数据得出结果后,向用户反馈。

对于不同的实现,各方有不同的态度(自行瞎编)。

对于实现一:

  • 服务A开发人员:这个实现极好,最简单、最省事;

  • 服务B开发人员:为啥我们的数据库要存跟我们服务职责无关的数据?这会导致我们的代码腐化。

对于实现二:

  • 服务A开发人员:实现这么个简单功能,还要导入维护这么大量的数据,太麻烦;

  • 服务B开发人员:嗯,数据给你,你爱怎么折腾就怎么折腾。

对于实现三:

  • 服务A开发人员:数据分布在不同的库,在应用中合并处理得到对应结果的过程的开发复杂度高且代码不够优雅;

  • 服务B开发人员:要给你提供查询接口,不是不可以,但是如果每个服务有相关查询需求我们都要协助改这也很烦。

二、如何破局?

服务A、服务B开发人员站在他们自己的角度分析这些实现得出的这些想法都是正确的。但如果只站在自己的立场,互不让步的话,事情是无法推进的。

个人认为这个问题应该

跳出自身立场,站在更高角度,选出全局收益最高的实现全局收益 = Σ局部收益 - Σ局部代价

对于上述具体场景,站在全局得失角度的考虑,个人觉得应该是这样的:

  • 这是一个边缘功能,使用的人数和频率不高,我们实现该功能的代价一定不能高于其产生的收益;

  • 方案一在服务B的数据库中存储与其无关的数据,违反单一职责原则,虽然该实现整体很简单,但其会导致服务B代码/数据腐化,不利于服务B的后续演化;

    • 有人或许会说,只是一个简单的标志,不至于;

    • 但如果每个其他服务都要求服务B为其进行改造,存储服务B不应该存储的数据,那服务B还怎么重构演化?这不就变回单体应用了么?

  • 方案二将所需数据从服务B全部导入服务A的话,除却存储服务B数据所需的物理资源消耗外,无论是全量批量导入、增量批量导入还是流式导入我们都需要关心其导入到服务A中数据的正确性。尤其是跑批,我相信是无数开发和运维的噩梦。因此个人觉得方案二的投入可能已大于其能获得的收入;

  • 对于方案三。

    • 要求服务B提供对其自身数据的查询接口,只要其查询接口是一个较为通用的,而并非对服务A专门定制的话,其本应属于服务B的职责,不存在代码腐化;

    • 要求服务A在内存中合并数据进行展示,由于服务B提供通用接口的能力的限制、拼装筛选数据逻辑复杂,复杂的查询确实需要很大开发量;

    • 但因为该功能确实较为边缘,产出价值并不是特别巨大,因此我们可以要求业务对相关查询进行简化,不要想着面面俱到,以减少开发成本,将人力投入到更有需要的地方。

综上,个人觉得针对该场景应该选择方案三。

三、何时选用方案二

方案一是单体应用的老路,不再讨论及考虑。以下分析下方案二的使用场景。

我们上面提到方案二需要存储数据、同步数据、维护数据准确性需要给到不少的代价,那何时选用方案二?

当然是获得的收益远大于付出的代价的时候,例如服务A需要为客户提供一个高频复杂的查询计算、并因此能获得一个很高的收益,此时我们就可以将B的数据导入到服务A,这样我们可以更方便的处理数据,提供更简洁高效的服务。

这里扩展一下,我们要如何同步服务B的数据呢?因批处理不实时、binlog等手段直接暴露底层数据结构增加服务间耦合,个人觉得利用队列实现的事件溯源模式是一个不错的选择,后续会写文章介绍相关实现。

四、总结

对于微服务场景下的数据查询,对于原始数据提供方:

  • 不应该接受非本服务的任何逻辑及数据;

  • 提供通用(非定制)的查询接口,以满足其他服务基础查询需求;

  • 提供获取全量业务层级数据的方式,如事务溯源模式,发布业务层级的每一次状态变化(状态变化的形态要像API一样保持兼容性)。

对于使用数据方:

  • 尽可能地使用对方通用的查询接口;

  • 综合考虑收益及代价后,可在本地数据库导入其他服务的数据,以实现更高效灵活的业务逻辑。

(对于不使用上述总结规则的微服务容易陷入一个怪圈,如下,大家看看就好)

五、最后

本文为个人的一些思考,仅为抛砖引玉,欢迎各位提出自己的一件。

如本文对你有所启发及帮助,请转发以帮助更多的人,谢谢!

六、引用

  • 百度百科——罗生门

    • https://baike.baidu.com/item/罗生门/52523?fr=aladdin

  • data-dichotomy-rethinking-the-way-we-treat-data-and-services

    • https://www.confluent.io/blog/data-dichotomy-rethinking-the-way-we-treat-data-and-services/

罗生门:一个简单查询实现引发的思考相关推荐

  1. 一个HBase查询问题引发的思考,作为HBase使用者这个问题你知道答案吗?

    前言 讲解HBase事务的文章很多,这里就不过多赘述了,大家应该都知道是通过MVCC实现的.但是今天这篇文章的背景是一个同事和我讨论一个问题引发的,这个问题使我重新梳理下这块内容并作为记录和大家分享. ...

  2. 一个知乎提问引发的(思考)[https://www.zhihu.com/question/263431508/answer/574084280]

    表示很喜欢这个问题,深有同感!这个问题也让我这种杂家谈谈想法吧,看题主应该是骨骼精奇的奇才,我假想读者是"小学生",所以,觉得我啰嗦的大大,忍忍吧,欢迎讨论. 先说回答,再说废话. ...

  3. 一个简单的缓冲区溢出的思考

    从大二开始真正接触技术开始,从最早的HTML,PHP,WEB开发.一直以为以后可能会从事开发的工作,碰巧大三上的时候和同专业的郭子,邹豪参加了南京的一个信息安全技能大赛,才真正找到了兴趣的方向,也从懵 ...

  4. 前置++与后置++之一道简单的题目引发的思考

    引言 昨晚一时兴起,我脑子就问自己下面的代码会输出什么,也不知道我脑子为什么有这个代码模型,只是模糊的有些印象: #include <stdio.h> #include <stdli ...

  5. 一个简单CI/CD流程的思考

    因为公司有两地研发团队,在统一CI/CD上难度不亚于两家公司合并后的新流程建立,并非不可攻克,简单描述下心得. 首先,代码管理使用gerrit -> 因其强大的 codereview 功能被选中 ...

  6. 一个日常 Excel 公式引发的思考

    偶尔有朋友咨询我EXCEL公式问题,其实平日用得不多,就熟悉几个简单的函数.只是多数问题通过分解,是可以通过简单的函数实现的. 实际问题 以有效投标人平均价为基准价,每超出基准价1%扣0.5分,低于基 ...

  7. c 与mysql连接_c与mysql连接和一个简单查询的例子

    今天给新来的同事做mysql培训,用到的一个例子: 连接数据库test 用户名root密码abc 在里面有一个username的表,describe username结果如下 mysql> de ...

  8. mysql group by笔试题_[PBN笔试题]mysql 一个简单查询中的group by 和 order by 的使用

    具体我忘记了,大概内容差不多如下. 两张表,内容如下: +--------+-------+------+ | z_code | mgr | pigs | +--------+-------+---- ...

  9. 一个分组查询引发的思考

    一个分组查询引发的思考 我们在看项目代码或者SQL语句时, 往往会看到很多非常复杂的业务或者SQL 那么问题来了. 复杂SQL是如何写成的? 下面通过一个数据展示的需求来体会到复杂的SQL是如何书写的 ...

最新文章

  1. 沃尔沃投资两家以色列科技创企 布局人工智能
  2. 转移地址在内存中的jmp指令 检测点9.1
  3. 教你用Python提取Chrome浏览器保存的密码
  4. 创建数据库指定编码集
  5. [NOTE] XMLHttpRequest
  6. 从初恋到生子,聊聊我的十年爱情。
  7. 【转】php中XML、XSLT的结合运用
  8. Sass基础——Rem与Px的转换
  9. Java引用多个jar包的写法
  10. 【Multisim仿真】直流稳压电源设计报告
  11. Redis RU330课程 Redis Security 第3周学习笔记
  12. 高中免费套卷博客_博客卷
  13. OpenCV-RGB转HSV
  14. Multisim基础 共阴极数码管是com_k,共阳极数码管是com_a
  15. 计算机应用基础全解,第三章习题-ddg全解.doc
  16. 再见了,我的黄色文件夹(内置福利)
  17. PHP 八羊闪电本地相册图片查看器V1 PHP极简代码直接查看本地文件夹图片 源码下载!
  18. Google翻译API的使用
  19. Elasticsearch基础
  20. Java面试题日积月累(JavaSE40道)

热门文章

  1. 杰理AC692X 软开关机的实现
  2. 广州租房提取住房公积金攻略
  3. 电池_电池容量的测试——手机、电池、充电器三件套之电池篇3
  4. 关于Chrome和Firefox
  5. smtp gmail_如何使用Gmail SMTP服务器在WordPress中发送电子邮件
  6. win服务器上的虚拟机反应慢,Win10系统打开VMware虚拟机特别慢的解决方法
  7. 错误 “Avoided redundant navigation to current location...” 的解决方案
  8. C# + PHP RSA保密通讯
  9. 李开复:长尾效应带给媒体的不是威胁
  10. python怎么在图片上写字的软件_python 实现PIL模块在图片画线写字