最近小编一直在接微服务转型的咨询 Case, 有些企业已经开始着手了, 但中途发现从各个微服务的数据库中做跨表查询是个大问题, 尤其当数据库自动分表存储之后. 其实从数据库设计的角度, 独立的数据库固然可以更好地解耦微服务架构, 但很难保证数据的一致性, 而且每个微服务治理团队需要维护各自的数据库, 例如备份, 升级等等. 相较而言, 共享数据库可以统一所有微服务的录入标准, 不会带来数据一致性问题.
今天我们讨论的不是这个, 回到我们设计数据库的初衷, 由于没法记录每一笔交易, 我们需要一个数据库来记录数据的当前状态, 但现在我们有了大数据平台和分布式的消息总线, 我们已经有能力记录每条交易, 通过简单的统计算法也可以得到实时的统计数据, 那我们还需要数据库么?
小编认为伴随着微服务的应用思维, 微服务的数据思维也应该有一个质的提升, 作为松耦合的服务, 微服务具有以下三个特点:
独立部署
有自己的数据架构(Schema)
数据只能通过自己的微服务 API 接口访问
回到最初的话题: 如果可以将服务的事件全部记录下来, 那我们只需要存储事件就行了.
上图是一个微服务的数据存储模型, 首先用户通过服务接口 (一般是一个 web 图形界面) 从前台交互操作; 然后前台将操作 (比如按钮或文字输入) 转化为指令传到数据写入端; 写入端检查指令是否符合业务逻辑, 然后生成事件 (包括时间戳, 事件 ID, 再加上原始指令) 并以键值对将事件计入事件存储; 最后事件存储将键值对事件持久化保存到 NoSQL 的数据库 (比如 MongoDB,Cassandra) 中, 以备读取请求的调用.
在数据读取时, 用户同样与 UI 界面交互, 一般 UI 界面上会预定义一些常用的查询也可以接收用户的自定义查询; 然后请求被转换成标准的查询语句 / 命令; 最后下发到 NoSQL 数据库获取事件的统计信息.
以事件驱动来设计微服务的数据库有五个好处:
更易将领域驱动设计 (Domain Driven Design, 或 DDD) 付诸实施;
DDD 是 2004 年由著名建模专家 Eric Evans 提出的: 任何软件开发都不应只关注技术, 业务领域才是软件开发更应关注的重点. 由于每条事件都被记录下来了, 所以业务之间的关联就能一目了然. 比如一家医院的库房从数据库看有 200 箱止痛药和 800 箱消炎药, 但不关注事件的话永远不知道 80% 的消炎药是伴随止痛药一起出售的.
降低服务耦合度;
当微服务间有调用或依赖关系的时候, 某一个服务的失效会影响到子微服务. 例如服务 1 是一个订单系统, 服务 3 是客户征信系统, 当用户下单时, 服务 1 会检查服务 3 该用户的征信标志位, 但是当服务 3 的 API 不可用时就会影响到服务 1 的下单.
在这种情况下, 可以将服务 1 的订单事件日志关联到服务 3 的征信日志, 从事件存储中获取该标志位, 或者使用消息总线做事件的关联, 就完全解耦了应用层面的依赖项.
在实际应用中, 一个单体购物系统可以拆解为客户, 订单, 运输, 退货, 货品目录等多个微服务. 每个微服务都与客户信息有关联, 当客户系统的微服务有事件记录时, 通过侦听 (Reader) 更新其余微服务各自的关联库就可以了, 这样即便客户系统断了, 其余系统也依然可以从现有关联库中获得客户信息, 等客户系统上线了再恢复更新就行了.
来源: https://yq.aliyun.com/articles/697436