微服务跨库联合查询问题解决思路
泛域名ssl证书 239元1年送1个月、单域名39元1年,Sectigo(原Comodo证书)全球可信证书,强大的兼容性,高度安全性,如有问题7天内可退、可开发票
加微信VX 18718058521 备注SSL证书
【腾讯云】2核2G4M云服务器新老同享99元/年,续费同价
首先我说一个很实际的问题,不是任何公司都需要微服务,或者说,不要上来就搞微服务,我看过北京不少创业公司的项目,这么说吧,估值在2亿美金以下的创业公司,基本上没必要搞什么微服务,总共就二十几口程序员,还都坐在一个办公室里面,费那劲赶那时髦搞什么微服务啊,组织团队赶紧出活才是正经的。
DHH曾经写过一篇文章《The Majestic Monolith》:The Majestic Monolithm.signalvnoise.com
讲的就是,应用代码写在一起(Monolith),只要软件工程组织管理得好,人员稳定高素质,一样可以很出色。
老兵我补一句(一刀):如果软件工程管理不好,人员不稳定,素质低,搞微服务还是啥啥服务,一样做成一坨屎。
好吧,我喷完了,发泄完爽多了,现在来上干货。
如果你这样搞微服务,说明业务比较成熟,而且人员比较多,只能分而治之。
分而治之的首要原则——沿着纹路来分割。
好比砍木头,如果沿着木头的纹理来砍,很舒服,如果非要垂直于纹路来砍,砍到手软也没什么效果。
软件之间的逻辑联系,就是好比木头的纹路,如果两个联系很紧密的模块,你把他们分开到不同的微服务,那好比垂直于纹路来砍木头,费劲不说,最后维护起来也麻烦。
具体到订单和客户这两个模块来说,如果业务上这两个功能联系非常紧密,就不合适分到不同的微服务,不分开,也就没有连表查询的问题。
好吧,好吧,我承认,绝大部分公司搞微服务都会把订单和客户分成不同的微服务的,我们就看怎么解决吧。
一个最土鳖的方法,就是两个微服务都提供RESTful API,让其他服务批量获取自己的数据,相当于在API层支持搜索,这样使用API凑活着也能做出连表查询的效果,当然,这种方法笨拙而且低效。
这时候,就要退一步,根据具体场景来考虑怎么连表查询了。
这里,我假设是一个对『查询』要求最灵活的场景——你那个干什么事都是拍脑袋的老板,突然想看一个统计数据,跑到你的座位上来,要你现在就给一个复杂的查询结果,比如,『过去3个月每个周3下午有哪些客户下了了母婴、汽车、书籍这3种订单,而且订单在4个小时之内实现了发货』。
这种查询虽然复杂,但是如果所有数据都在一个DB里而不是在分散开的微服务里,用一个SQL也就搞定了。
没错,既然用一个SQL就搞定了,那么,我们把所有数据汇聚到一个DB里不就行了嘛。
一个简单的解决方法,就是把订单和客户微服务的内容汇聚到一个独立的『汇报服务』(第三个服务,嗯,你都已经微服务了,不在乎再多一个吧),要么直接聚合Database,要么用上一个应用层消息机制,订单微服务和客户微服务的每一个操作都发出一个message来,由『汇报服务』来监听这些message,从而更改自己的Database。
如此一来,就可以满足一切连表查询的需求。
当然,这不是实时的,只能做到最终一致(eventual consistency),因为只要用上message,基本上就是异步了,做不到实时一致。
对于大部分业务需求,最终一致就够用!
就像上面的例子『过去3个月每个周3下午有哪些客户下了了母婴、汽车、书籍这3种订单,而且订单在4个小时之内实现了发货』,过去三个月的信息,谁还在乎今天发生的事情呢,你的数据只要覆盖过去三个月直到昨天,足够满足需求了。
差不多就这样。