高并发系统实战课
徐长龙
前微博架构师、极客时间架构师
11663 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 30 讲
结束语&结课测试 (2讲)
高并发系统实战课
15
15
1.0x
00:00/00:00
登录|注册

多层依赖:如何避免落入数据服务接口的陷阱?

部署支持数据层和服务的动态扩容
多副本缓存高频率访问的数据
大量部署服务器分摊请求压力
避免过多写操作服务器参与分布式事务协调
保证数据一致性
使用队列做缓冲
建设类似于Raft的Proxy
需要运维配合
通过队列实现
需要运维配合更改基础组件的配置
不建议大规模使用
运维要求高
标准封装提升优化效率
灵活的扩容能力
扩大辅助数据层选择范围
提升读写数据库性能
灵活调整服务器和基础支撑服务规模
拆分成不同项目
分离应用程序中命令和查询责任的方式
Command Query Responsibility Segregation
扩容或更换数据层麻烦
代码层和数据层强绑定
性能上限受集群性能上限限制
读写服务依赖同一数据库
读优化
高并发写优化
业务依赖关系接口流程和事务拼接
划分Model层按业务领域
拼合多个实体的功能提供业务服务
领域边界即纵切边界
达成共识划分业务领域和子领域
适用场景不同
纵切拆分
同层Service服务相互调用
去掉所有服务的层级
业务依赖关系接口流程和事务拼接
划分Model层按业务领域
拼合多个实体的功能提供业务服务
依赖关系搭乐高状态
代码层级复杂
业务实体关系复杂
接口依赖关系消耗时间
大量网络损耗
业务应用通过多个Service服务实现
修改影响范围大
接口隔离性差
业务依赖底层数据结构
复杂业务接口处理
RESTful API设计思路
衡量服务灵活性的标准
读强一致需求
数据同步
代价
优势
读写拆分
CQRS概述
数据库层面缺陷
读写优化方向不一致
充血模型解决多层依赖问题
DDD按业务的视角拆分领域的技巧
大平层架构设计
充血模型解决多层依赖问题
多层项目依赖问题
接口请求耗时链路分析
在线商城服务结构
多层依赖问题
业务接口写成数据接口
CQRS的读写拆分策略
传统单体架构缺点
DDD领域拆分
微服务的平层设计
数据服务接口导致的多层依赖
读写逻辑优化

该思维导图由 AI 生成,仅供参考

你好,我是徐长龙。
在之前的课程里,我们探讨了读多写少、强一致、写多读少、读多写多这四种常见类型的系统如何优化。不过,很多复杂业务系统中,读写逻辑常常混合在一起、相互牵制,这给优化工作带来了很多挑战。
碰上这样的情况,我们不妨考虑一种更高级的拆分模式——CQRS。你可能对 CQRS 早有耳闻,但觉得太过复杂就望而却步了。不过别担心,这节课里我会结合例子,带你看看传统单体服务架构与 CQRS 的思考方式有什么不同。
学完今天的内容,你将会深入理解 CQRS 的拆分思想,找到规避数据服务接口陷阱的方法,还能理解一些反常识的设计,比如微服务里为什么要把 5 个项目拆成 200 个。

传统单体架构缺点

我们先看看熟悉的传统单体架构设计思路,重点关注一下它有什么缺点,这有助于你理解为什么会出现 CQRS 这种模式。
这里我们继续沿用前面课程里用户中心的案例,请看下图。图里面展示了单体服务状态下的用户中心,这时候高频和低频的读写服务放在了一起。
单体服务 高频、低频的读写服务放在一起
在我们的印象中,用户中心读并发流量大。但实际上用户中心里,不是所有功能都是读多写少类型的,你可以参考后面表格列出的例子。
可以看到,除了读多写少的服务功能外,还有很多其它类型的功能(事实上这取决于调用方的场景)。
传统单体架构优化方式
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了如何避免落入数据服务接口的陷阱,重点讨论了传统单体架构的缺点以及CQRS(Command Query Responsibility Segregation)的读写拆分策略。传统单体架构中,读写优化方向不一致,且数据库层面存在性能上限和强绑定的问题。相比之下,CQRS通过将读和写分别拆分成不同项目,实现了读写优化分离部署,提升了系统的灵活性和扩容能力。文章强调了CQRS的优势,包括灵活的成本投入、数据库性能提升以及标准模块的封装优势。然而,也指出了CQRS的代价较高,对运维要求较高,不建议大规模使用。最后,文章提到了一些应对CQRS带来的挑战,如数据同步和读强一致性的问题,并建议建设类似于Raft的Proxy来解决这些问题。整体而言,本文通过对比传统单体架构和CQRS的优缺点,为读者提供了对CQRS的深入理解和应用建议。 文章还介绍了微服务的平层设计和DDD领域拆分,探讨了纵切拆分与横切拆分的差异,以及DDD的业务领域划分和值对象的重要性。通过对比传统贫血模型和充血模型,以及横切服务和纵切服务的特点,文章展示了微服务和DDD的优势和适用场景。最后,文章总结了业务系统性能优化的挑战,指出了传统模式的局限性,并提出了充血模型、微服务和DDD作为更适合复杂业务系统的解决方案。 总的来说,本文深入探讨了CQRS、微服务和DDD等技术在解决业务系统性能优化和复杂性管理方面的应用,为读者提供了全面的技术视角和应用建议。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《高并发系统实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(2)

  • 最新
  • 精选
  • 若水清菡
    为什么说 CQRS 拆分数据接口很方便,却很难拆分业务接口呢? 可以从课程开头以课程里用户中心的案例看出,每个业务接口对后端数据层(数据库)的访问频次、访问类型都不一样,有多少个业务就需要拆分多少次,很难根据业务接口来做CQRS;拆分数据接口反而简单一些,对数据接口读写拆分即可。

    作者回复: 你好,感谢你的思路。很多核心业务为了更好的隔离性,很期望能够有专用基础服务集群供他使用,所以相对来说CQRS的拆分还可以做业务隔离分组提供业务服务,不过成本太高,相对的微服务的值对象更有性价比。另外,业务接口会综合调用多个服务,这些服务还会依赖不同的服务,这个依赖关系很难梳理,这些情况导致了,即使做CQRS优化,但是对于业务并没有快多少。所以单纯的优化是不够的,还要改业务实体之间的关系

    2023-12-25归属地:北京
    2
  • 黄堃健
    同层 Service 服务之间没有上下层级关系,可以相互调用(虽然不推荐) 老师, 如果我们允许同层Service服务 相互调用。 对于出现A->B B->A死循环,怎么防止

    作者回复: 你好,这里其实不用在架构上特意防护,因为最简单的结果是明显的死循环,全量自动化回归测试的时候就能发现卡死情况。如果是相互依赖不同的动作会在依赖链路跟踪上有体现,这时候如果相互较多建议合并这两个模块,并且实际上相互只是依赖但不是死循环调用情况很常见,一些标准服务之间的依赖是业务流程需要,这和数据层依赖有些不一样。

    2024-02-29归属地:广东
收起评论
显示
设置
留言
2
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部