← 返回目录

CQRS

第 118 / 119 卷日期:

我们就可以结合两者的优势,解耦出更好的架构模式。然而,这其中还有一个让人不爽的问题,即数据库。如果我们使用多个数据库,那么维护成本也随着上升。而如果我们

可以在后台使用类似于微服务的Django MTV架构,并且它可以支持异步请求的话,并在前台使用 Reactive 来编程,是不是就会更爽一点?

CQRS

对于复杂的系统来说,上面的做法做确实很不错。但是对于一个简单地系统来说,这样做是不是玩过火了?如果我们要设计一个博客系统的话,那么我们是不是可以考虑

将 Write/Read 分离就可以了?

命令和查询责任分离 Command Query Responsibility Segregation(CQRS)

是一种将系统的读写操作分离为两种独立模型的架构模式。

CQS对于这个架构的深入思考是起源于之前在理解 DDD。据说在 DDD 领域中被广泛使用。理解 CQRS 可以用分离 Model 和 API 集合来处理读取和写入请求开始,即

CQS(Command Query Separation,命令查询分离)模式。CQS 模式最早由软件大师 Bertrand Meyer(Eiffel语言之父,面向对象开-闭原则OCP提出者)提出。他认为,对

象的行为仅有两种:命令和查询。

这个类型的架构如下图所示:

图 198-1
图 198-1

图 107: CQS Basic

除了编写优化的查询类型,它可以让我们轻松换API的一部分读一些缓存机制,甚至移动读取 API 的请求到另一台服务器。

存在一个瓶颈问题,使用同一个 RDBMS。对于写入多、读取少的应用来说,这种架构还是存在着不合理性。

为了解决这个问题,人们自然是使用缓存来解决这个问题了。我们在我们的应用服务外有一个HTTP服务器,而在HTTP服务器之外有一个缓存服务器,用于缓存用户常

驻的一些资源。如下图所示:

图 199-1
图 199-1

图 108: 带缓存的 Web 架构

而实际上这样的服务器可能是多余的——我们为什么不直接生成 HTML 就好了?

编辑-发布分离或许你听过 Martin Folwer 提出的编辑-发布分享式架构:即文章在编辑时是一个形式,而发表时是另一个形式,比如用Markdown 编辑,而用 HTML发表。

图 199-2
图 199-2

图 109: 编辑-发布分离

而最典型的应用就是流行于 GitHub 的 Hexo、Jekyll 框架之类的静态网站。如下图所示的是 Hexo 的工作流:

图 200-1
图 200-1

图 110: Hexo 站点工作流

我们在本地生成我们的项目,然后可以创建一个新的博客、开始编写内容等等。接着,我们可以在本地运行起这个服务,除了查看博客的内容,还可以修改样式等等。完

成上面的工作后,我们就可以生成静态内容,然后部署我们的应用到 GitHub Page 上。

这一切看上去都完美,我们有两个不同的数据源——一个是 md 格式的文本,一个是最后生成的 HTML。它们已经实现了读写/分离:

但是作为一个前端开发人员,没有 JSON,用不了 Ajax请求,我怎么把我的博客做成一个单页面应用?

编辑-发布-开发分离因为我们需要交我们的博客转为JSON,而不是一个hexo之类的格式。有了这些 JSON 文件的存在,我们就可以把 Git 当成一个 NoSQL 数据库。同时

这些 JSON 文件也可以直接当成 API 来

其次,这些博客还需要 hexo 一样生成 HTML。

并且,开发人员在开发的时候不会影响到编辑的使用,于是就有了下面的架构:

在这其中我们有两种不同的数据形式,即存储着Markdown数据的JSON文件和最后生成的 HTML。

对博客数量不是很大的网站,或者说一般的网站来说,用上面的技术都不是问题。

图 201-1
图 201-1

图 111: CQRS进阶

图 201-2
图 201-2

图 112: Git As NoSQL DB

图 202-1
图 202-1

图 113: 基于 Git 的编辑-发布分离

全站分卷索引 · 119 卷
  1. 1Growth: 全栈增长工程师指南
  2. 2软件开发的核心难题:沟通
  3. 3大公司的专家与小公司的全栈
  4. 4全栈工程师的未来:无栈
  5. 5基础知识篇
  6. 6工具只是辅助
  7. 7语言也是一种工具
  8. 8提高效率的工具
  9. 9IDE
  10. 10终端或命令提示符
  11. 11包管理
  12. 12环境搭建
  13. 13Windows
  14. 14GNU/Linux
  15. 15学好一门语言的艺术
  16. 16输出是最好的输入
  17. 17如何应用一门新的技术
  18. 18Web 编程基础
  19. 19从 HTML 到页面显示
  20. 20HTML
  21. 21中文?
  22. 22其他 HTML 标记
  23. 23小结
  24. 24CSS
  25. 25简介
  26. 26样式与目标
  27. 27更有趣的 CSS
  28. 28JavaScript
  29. 29JavaScriptFul
  30. 30面向对象
  31. 31其他
  32. 32前端与后台
  33. 33后台语言选择
  34. 34PHP
  35. 35Model
  36. 36View
  37. 37Controller
  38. 38后台即服务
  39. 39后台即服务
  40. 40数据库
  41. 41搜索引擎
  42. 42前端框架选择
  43. 43前台与后台交互
  44. 44JSON
  45. 45WebSocket
  46. 46编码过程
  47. 47Web 应用的构建系统
  48. 48Web 应用的构建过程
  49. 49Web 应用的构建实战
  50. 50Git 与版本控制
  51. 51Tasking
  52. 52Tasking 开发任务
  53. 53写代码只是在码字
  54. 54内置索引与外置引擎
  55. 55内置索引与外置引擎
  56. 56如何测试
  57. 57测试替身
  58. 58Mock
  59. 59测试先行
  60. 60可读的代码
  61. 61命名
  62. 62函数长度
  63. 63代码重构
  64. 64提炼函数
  65. 65内联函数
  66. 66查询取代临时变量
  67. 67重构到设计模式
  68. 68上线
  69. 69隔离硬件:虚拟机
  70. 70隔离操作系统:容器虚拟化
  71. 71隔离底层:Servlet 容器
  72. 72隔离依赖版本:虚拟环境
  73. 73隔离语言:DSL
  74. 74GNU/Linux
  75. 75HTTP 服务器
  76. 76数据库端缓存
  77. 77前端缓存
  78. 78运行机制
  79. 79自动化部署
  80. 80依赖与包仓库
  81. 81构建软件包
  82. 82数据分析
  83. 83想法-构建
  84. 84产品-衡量
  85. 85数据分析
  86. 86分析数据
  87. 87用户数据分析:Google Analytics
  88. 88流量获取
  89. 89移动应用
  90. 90网站性能
  91. 91SEO
  92. 92什么样的网站需要 SEO?
  93. 93内容
  94. 94UX 入门
  95. 95什么是简单?
  96. 96进阶
  97. 97认知设计
  98. 98持续交付
  99. 99持续集成系统
  100. 100持续交付
  101. 101持续部署
  102. 102持续阅读
  103. 103遗留系统与修改代码
  104. 104遗留代码
  105. 105修改遗留代码
  106. 106速度优化
  107. 107模块重构
  108. 108Retro
  109. 109三个维度
  110. 110架构模式
  111. 111预设计式架构
  112. 112演进式架构:拥抱变化
  113. 113意图导向
  114. 114重构
  115. 115模式与演进
  116. 116相关阅读资料
  117. 117架构解耦
  118. 118CQRS
  119. 119CQRS 结合微服务