本文转载自 架构师之路 公众号

最近留言问“微服务”的朋友颇多,找历史文章又找不到,故重新优化发布,希望大家有收获,不要被“微服务大潮”误导。

“微服务架构”的话题非常之火,很多朋友都在小窗我,说怎么做服务化?解答“怎么做”之前,先得了解“为什么做”。

画外音:做技术千万不能是这种思路,“别人都在做,所以我们也要搞”。

并不是所有的业务都适合“服务化”,互联网高可用架构,到底为什么要服务化?

服务化之前,高可用架构是什么样的?

在服务化之前,互联网的典型高可用架构如下:

(1) 客户端,APP,H5,小程序,PC浏览器;

(2) 后端入口,高可用的反向代理nginx集群;

(3) 站点应用,高可用的web-server集群;

(4) 后端存储,高可用db集群;

更典型的,web-server集群通过DAO/ORM等技术来访问数据库。

可以看到,最初是没有服务层的, 此时架构会碰到什么典型痛点呢?

架构痛点一:代码到处拷贝

举一个最常见的业务例子,用户数据访问,绝大部分公司都有一个数据库存储用户数据,各个业务都有访问用户数据的需求。

在有用户服务之前,各个业务线都是自己通过DAO写SQL访问user库来存取用户数据,这无形中就导致了代码的拷贝。

架构痛点二:复杂性扩散

随着并发量的越来越高,用户数据的访问数据库成了瓶颈,需要加入缓存来降低数据库的读压力,于是架构中引入了缓存,如果没有统一的服务层,各个业务线都需要关注缓存的引入导致的复杂性。

对于写请求,所有业务线都要升级代码:

(1)先淘汰cache;

(2)再写db;

对于读请求,所有业务线也都要升级代码:

(1)先读cache,命中则返回;

(2)没命中则读db;

(3)再把数据放入cache;

这个复杂性是典型的“业务无关”的复杂性,业务方需要被迫升级。

随着数据量的越来越大,数据库需要进行水平拆分,于是架构中又引入了分库分表,如果没有统一的服务层,各个业务线都需要关注分库分表的引入导致的复杂性。

这个复杂性也是典型的“业务无关”的复杂性,业务方需要被迫升级。

典型的耦合,还包括bug的修改,发现一个bug,多个地方都需要修改。

架构痛点三:库的复用与耦合

服务化并不是唯一的解决上述两痛点的方法,抽象出统一的“库”是最先容易想到的解决(1)代码拷贝;(2)复杂性扩散;的方法。

抽象出一个user.so,负责整个用户数据的存取,从而避免代码的拷贝。至于复杂性,也只有user.so这一个地方需要关注了。

解决了旧的问题,会引入新的问题,库的版本维护会导致业务线之间的耦合。

业务线A将user.so由版本1升级至版本2,如果不兼容业务线B的代码,会导致B业务出现问题。

业务线A如果通知了业务线B升级,则是的业务线B会无故做一些“自身业务无关”的升级,非常郁闷。当然,如果各个业务线都是拷贝了一份代码则不存在这个问题。

画外音:有时候拷贝代码也是有好处的。

架构痛点四:SQL质量无法保障,业务相互影响

业务线通过DAO访问数据库,本质上SQL�