跨微服务的分页查询
问题描述
假设有一个列表查询页面,查询的数据是多个数据源的聚合,数据源由不同的微服务管理,如何实现分页查询?
解决方案
为了表述方便,把涉及到的微服务分为主微服务和辅微服务。提供主体数据的微服务称为主微服务,提供关联数据的微服务称为辅微服务。这里根据查询条件的不同又分为三种情况
查询条件字段在主微服务中
查询条件字段在主微服务中,则查询过程为:从数据库中根据条件查询出分页结果,将辅微服务的关联主键字段提取成列表,再用此列表到辅微服务中查询,再聚合。
查询条件字段在辅微服务中
查询条件字段在辅微服务中,则查询过程为:先从辅微服务中根据条件查询出分页结果,再将关联主键字段提取成列表,再用此列表到数据库中查询,再聚合。
查询条件字段有的在主微服务中,有的在辅微服务中
数据冗余
我们还可以在主微服务的数据库中冗余相关字段,这样查询的时候,只是一个简单的单库查询。如果这个字段的数据是不变的,或者说它的改变无所谓,并不需要它的最新值,则这样做没有任何问题。但是如果在业务上要求字段的值必须是最新的,那么如何更新保证一致性就是最大的问题。通常有两种做法:
- 如果需要强一致性,那么就需要两阶段提交等强一致性的分布式事务,当然这种情况并不多见。
- 如果不需要强一致性,只要最终一致性,那么就可以采用消息队列之类的柔性事务。
宽表
这是一张包含了全部数据的表,一次性查询即可。与三不同的是,这张宽表通常存储在第三方数据库中,比如常见的使用ElasticSearch
。各个微服务在新增和更新的时候都同时更新这张宽表,通常只要保证最终一致性即可。这种做法还有一个显而易见的好处,就是可以利用第三方数据库独立扩展,提高查询性能。
本文由作者按照 CC BY 4.0 进行授权