当前位置: 首页 > 科技观察

为什么互联网架构要面向服务?

时间:2023-03-14 18:58:53 科技观察

《微服务架构》的话题很火。很多朋友问我服务化怎么做?在回答“怎么做”之前,首先要明白“为什么要做”。画外音:做技术一定不能是这种思维方式,“别人都在做,我们也应该做”。并不是所有的业务都适合“服务化”。互联网高可用架构,为什么要面向服务?在面向服务之前,高可用架构是什么样的?在面向服务之前,典型的互联网高可用架构如下:Client、APP、H5、小程序、PC浏览器;后端入口,高可用反向代理nginx集群;网站应用程序,高可用性网络服务器集群;后端存储,高可用数据库集群;更典型的是,web-server集群通过DAO/ORM等技术访问数据库。可以看到一开始是没有service层的。此时架构会遇到哪些典型痛点?架构痛点一:到处复制代码举个最常见的业务例子,用户数据访问,大部分公司都有数据库来存储用户数据,每个业务都有访问用户数据的需求。在没有用户服务之前,各个业务线访问用户数据库都是通过DAO写SQL访问用户数据,无形中导致了代码拷贝。架构痛点二:复杂度扩散随着并发量的增加,用户数据访问数据库成为瓶颈,需要加入缓存来降低数据库的读取压力。因此在架构中引入了缓存。如果没有统一的服务层,各业务线需要注意引入缓存带来的复杂性。对于写请求,所有业务线都需要升级代码:首先剔除缓存;然后写分贝;对于读请求,各业务线也需要升级代码:先读缓存,命中返回;放入缓存;这种复杂度是典型的“业务无关”的复杂度,需要业务方强制升级。随着数据量的增长,需要对数据库进行水平拆分,因此架构中引入了分库分表。如果没有统一的服务层,各业务线需要注意引入分库分表带来的复杂性。性别。这种复杂度也是典型的“业务无关”的复杂度,需要业务方强制升级。典型的耦合还包括错误修改。如果发现bug,需要修改多个地方。架构痛点3:库重用和耦合服务并不是以上两个痛点的唯一解决方案。抽象出一个统一的“库”是第一个容易想到的解决方案(1)代码拷贝;(2)复杂度扩散;方法。抽象出一个user.so,负责整个用户数据的访问,从而避免了代码拷贝。至于复杂度,只有user.so需要注意。解决老问题会引入新问题,库版本维护会导致业务线耦合。A业务线将user.so从1版本升级到2版本,如果不兼容B业务线的代码,会导致B业务出现问题。如果A业务线通知B业务线升级,那么B业务线就会莫名其妙的做一些“与自身业务无关”的升级,非常郁闷。当然,如果每个业务线都复制一份代码,就不存在这个问题。画外音:有时候抄代码也挺好的。架构痛点四:SQL质量无法保证,业务交互相互影响。业务线通过DAO访问数据库。SQL语句本质上是由各个业务线组装而成的。高级工程师写出高质量的SQL,经验少的工程师可能会写出一些低效的SQL。如果A业务线写了一条全表扫描SQL,导致数据库CPU占用100%,那么受影响的不仅仅是一条业务线,而是所有业务线都会受到影响。画外音:临时程序员要背锅。架构痛点5:疯狂的DB耦合业务线不仅访问用户数据,还会结合自身业务访问自己的数据。画外音: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来访问业务线响应使用的用户数据。引入服务层有什么好处,会解决什么问题?(1)好处一:在调用方没有服务层之前,业务方需要通过DAO组装SQL访问来访问用户数据。服务层之后,业务端通过RPC访问用户数据,就像调用本地函数一样,非常爽:User=UserService::GetUserById(uid);传入一个uid得到一个User实体,就像调用本地函数一样,不需要关心序列化、网络传输、后端执行、网络传输、标准序列化的复杂性。(2)好处二:复用性,防止代码拷贝。所有用户数据访问都是通过用户服务执行的。代码只有一份,没有复制。升级一升级,bug修改一修改。(3)好处三:集中,屏蔽底层复杂性在没有服务层之前,所有业务线都需要关注缓存、分库分表等细节。有了服务层,只有服务层需要关注底层的复杂性,屏蔽上游的细节。(4)好处四:SQL的质量有保证。原来是业务直接拼接SQL访问上游数据库。有了服务层,所有的SQL都由服务层提供,业务线不能再为所欲为了。如果底层服务对稳定性有更好的要求,可以由更有经验的工程师来维护,而不是像原来的SQL一样难以关闭和控制。(5)好处五:数据库解耦各个业务原有的数据库混合在一个大数据库中,相互连接,难以拆分。面向服务后,底层数据库隔离,可以方便的拆分扩展。(6)好处六:提供有限的接口和无限的性能。在服务之前,上游的每个业务线都可以随心所欲地操作数据库。遇到性能瓶颈时,各个业务线很容易发生争执,相互指责。服务化后,服务只提供有限的通用接口。理论上,服务集群可以提供无限的性能。如果存在性能瓶颈,可以在一个地方优化服务层。(7)好处七:……服务化并不能解决所有问题。如果没有遇到这些问题,架构可能不需要面向服务。一切倒闭的建筑设计都是耍流氓。希望大家有所收获。【本文为专栏作者《58神剑》原创稿件,转载请联系原作者】点此阅读更多该作者好文