微服务最难的部分是你的数据

该文认为实现微服务最难的部分是业务数据,对于复杂业务的微服务系统必须结合领域驱动设计、事件驱动和EventSourcing等。

微服务中数据状态一般是放在数据库中,微服务是根据分离关注然后封装的设计原理,因此,每个微服务应该拥有和控制自己的数据库,并没有两个微服务共享一个数据库。不共享一个数据库,你就没有竞争读写模式,数据锁模型冲突与协调等问题,一个微服务一个单独数据库确实提供我们安全与便利。

对于一个企业建立微服务,需要考虑以下几种情况:
1.你的业务领域是什么?
2.事务边界在哪里?
3.微服务之间如何跨边界通讯?
4.数据库共享?

互联网公司的微服务实践和传统企业实现微服务巨大差别也许就在这里,传统企业的业务领域会比互联网公司的业务复杂得多。应对这样复杂领域,DDD能够帮助我们划分上下文边界,什么是微服务?就是一个上下文边界,什么是上下文边界?就是一个微服务。

所谓事务边界,是一种代表业务不变量的最小原子单位,无论你使用数据库ACID或两段事务实现,这些都不重要,重要的是我们要使得事务边界越来越小,比如一个事务在一个聚合对象中。这样我们才能扩展,当我们使用领域模型 实体值对象和聚合根这些概念时,实际上,存在一个有界上下文边界内(前提条件),一个包含实体和值对象的聚合就是代表了业务不变量的最小原子单位。而这种原子事务是不应该跨越有界上下文的。也就是说,我们将原子事务限定在了一个微服务之内。

那么微服务之间如何通讯?微服务之间通讯实际是跨越有界上下文,为什么会有跨越这种事情发生?因为我们需要维持多个聚合体之间的数据一致性,也就是说,一个复杂业务流程是可能跨多个有界上下文,通过多个聚合体操作才能实现。

这里就涉及到了分布式系统问题,CAP理论是我们的理论指导武器,我们跨多个聚合体操作,实际是保证多个聚合体内部的状态保持一致,如同数据库中操作多个关联表,数据库ACID会保证多个关联表的数据一致性,因为微服务(内含聚合体)是分布部署的,因此,我们需要一种机制也能保证数据一致性,这就是通过事件的最终一致性实现。

事件是一个不变数据,能够及时截获当时业务操作动作,然后广播给其他微服务,其他微服务会接受这个广播事件,更新自己的聚合内内部状态。

这种EventSourcing和CQRS的好处是:
1.你可以将你的数据库看成是记录的当前状态,而不是真正记录。
2.你能引入新的应用后,重新读取过去事件,检查这个应用行为是否与预期一致?可测试或发现隐藏很深的Bug.
3.可以实现完美的审计日志,任何业务操作都会被记录,容易追溯,对于银行 保险等行业极其重要,否则发生金额错误以后,很难追踪重现当时现场。

当然,缺点是带来复杂性,但是因为业务复杂,必然需要用复杂的解决方案解决复杂问题。

在微服务实战中,虽然大型解决方案商帮助我们解决了中间件或SOA的基础设施产品,但是剩余最难的部分还是需要我们自己面对解决。

以上是意译和掺和我本人并不违背原文宗旨的一些观点,原文见:
The Hardest Part About Microservices: Your Data –

[该贴被banq于2016-07-25 10:58修改过]

在实践中,上下文界定和分布部署后,如何保持事务一致性很难解决