互联网架构,究竟为啥要作服务化?

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

“微服务架构”的话题很是之火,不少朋友都在小窗我,说怎么作服务化?解答“怎么作”以前,先得了解“为何作”。
画外音:作技术千万不能是这种思路,“别人都在作,因此咱们也要搞”。程序员

并非全部的业务都适合“服务化”,互联网高可用架构,到底为何要服务化?web

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

在服务化以前,互联网的典型高可用架构以下:
互联网架构,究竟为啥要作服务化?
(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语句仍是各个业务线拼装的,资深的工程师写出高质量的SQL,经验没有这么丰富的工程师可能会写出一些低效的SQL。

假如业务线A写了一个全表扫描的SQL,致使数据库的CPU100%,影响的不仅是一个业务线,而是全部的业务线都会受影响。
画外音:临时工程序员要背锅了。

架构痛点五:疯狂的DB耦合

互联网架构,究竟为啥要作服务化?
业务线不仅访问user数据,还会结合本身的业务访问本身的数据。
画外音:user_biz表,也是用uid作主键。

典型的,经过join数据表来实现各自业务线的一些业务逻辑。

业务线A的table-user与table-A耦合在了一块儿,业务线B的table-user与table-B耦合在了一块儿,业务线C的table-user与table-C耦合在了一块儿,结果就是:table-user,table-A,table-B,table-C都耦合在了一块儿。

随着数据量的愈来愈大,业务线ABC的数据库是没法垂直拆分开的,必须使用一个大库(疯了,一个大库300多个业务表 =_=)。

架构痛点六:…

服务化后,高可用架构如何?

互联网高可用分层架构演进的过程当中,引入了“服务层”。
互联网架构,究竟为啥要作服务化?
以上文中的用户业务为例,引入了高可用user-service,对业务线响应所用用户数据的存取。

引入服务层有什么好处,到底解决什么问题呢?

好处一:调用方爽

有服务层以前,业务方访问用户数据,须要经过DAO拼装SQL访问。

有服务层以后,业务方经过RPC访问用户数据,就像调用一个本地函数同样,很是之爽:
User = UserService::GetUserById(uid);
传入一个uid,获得一个User实体,就像调用本地函数同样,不须要关心序列化,网络传输,后端执行,网络传输,范序列化等复杂性。

好处二:复用性,防止代码拷贝

全部user数据的存取,都经过user-service来进行,代码只此一份,不存在拷贝。

升级一处升级,bug修改一处修改。

好处三:专一性,屏蔽底层复杂度

互联网架构,究竟为啥要作服务化?
在没有服务层以前,全部业务线都须要关注缓存、分库分表这些细节。
互联网架构,究竟为啥要作服务化?

在有了服务层以后,只有服务层须要专一关注底层的复杂性了,向上游屏蔽了细节。

好处四:SQL质量获得保障

互联网架构,究竟为啥要作服务化?
原来是业务向上游直接拼接SQL访问数据库。
互联网架构,究竟为啥要作服务化?

有了服务层以后,全部的SQL都是服务层提供的,业务线不能再随心所欲了。底层服务对于稳定性的要求更好的话,能够由更资深的工程师维护,而不是像原来SQL难以收口,难以控制。

好处五:数据库解耦

互联网架构,究竟为啥要作服务化?
原来各个业务的数据库都混在一个大库里,相互join,难以拆分。
互联网架构,究竟为啥要作服务化?

服务化以后,底层的数据库被隔离开了,能够很方便的拆分出来,进行扩容。

好处六:提供有限接口,无限性能

在服务化以前,各业务线上游想怎么操纵数据库都行,遇到了性能瓶颈,各业务线容易扯皮,相互推诿。

服务化以后,服务只提供有限的通用接口,理论上服务集群可以提供无限性能,性能出现瓶颈,服务层一处集中优化。

好处七:…

服务化不能解决全部问题,若是没有碰到这些问题,架构未必须要服务化。

一切脱离业务的架构设计,都是耍流氓。

但愿你们有收获。
互联网架构,究竟为啥要作服务化?
架构师之路-分享可落地的技术文章

推荐阅读:《近期好文汇总》