CQRS
我们就可以结合两者的优势,解耦出更好的架构模式。然而,这其中还有一个让人不爽的问题,即数据库。如果我们使用多个数据库,那么维护成本也随着上升。而如果我们
可以在后台使用类似于微服务的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提出者)提出。他认为,对
象的行为仅有两种:命令和查询。
这个类型的架构如下图所示:

图 107: CQS Basic
除了编写优化的查询类型,它可以让我们轻松换API的一部分读一些缓存机制,甚至移动读取 API 的请求到另一台服务器。
存在一个瓶颈问题,使用同一个 RDBMS。对于写入多、读取少的应用来说,这种架构还是存在着不合理性。
为了解决这个问题,人们自然是使用缓存来解决这个问题了。我们在我们的应用服务外有一个HTTP服务器,而在HTTP服务器之外有一个缓存服务器,用于缓存用户常
驻的一些资源。如下图所示:

图 108: 带缓存的 Web 架构
而实际上这样的服务器可能是多余的——我们为什么不直接生成 HTML 就好了?
编辑-发布分离或许你听过 Martin Folwer 提出的编辑-发布分享式架构:即文章在编辑时是一个形式,而发表时是另一个形式,比如用Markdown 编辑,而用 HTML发表。

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

图 110: Hexo 站点工作流
我们在本地生成我们的项目,然后可以创建一个新的博客、开始编写内容等等。接着,我们可以在本地运行起这个服务,除了查看博客的内容,还可以修改样式等等。完
成上面的工作后,我们就可以生成静态内容,然后部署我们的应用到 GitHub Page 上。
这一切看上去都完美,我们有两个不同的数据源——一个是 md 格式的文本,一个是最后生成的 HTML。它们已经实现了读写/分离:
但是作为一个前端开发人员,没有 JSON,用不了 Ajax请求,我怎么把我的博客做成一个单页面应用?
编辑-发布-开发分离因为我们需要交我们的博客转为JSON,而不是一个hexo之类的格式。有了这些 JSON 文件的存在,我们就可以把 Git 当成一个 NoSQL 数据库。同时
这些 JSON 文件也可以直接当成 API 来
其次,这些博客还需要 hexo 一样生成 HTML。
并且,开发人员在开发的时候不会影响到编辑的使用,于是就有了下面的架构:
在这其中我们有两种不同的数据形式,即存储着Markdown数据的JSON文件和最后生成的 HTML。
对博客数量不是很大的网站,或者说一般的网站来说,用上面的技术都不是问题。

图 111: CQRS进阶

图 112: Git As NoSQL DB

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