微服务架构是分层架构演进过程中非常重要的一环。那么微服务是不是越早越好?今天就和大家聊聊这个问题。DAO层什么时候分层抽象?一开始,分层架构是什么样子的?一个业务系统的初始分层架构如下:web-server层从db层获取数据并进行处理;db层存储数据;,web-server层如何获取底层数据?一段web-server层获取数据的伪代码如上,不纠结代码细节,也不纠结不同编程语言、不同数据库驱动的区别。获取数据的过程大致为:与数据库建立连接并初始化资源;根据业务拼装SQL语句;通过连接执行SQL语句,获取结果集;通过游标遍历结果集,从每行数据中取出每一行数据和属性Data;关闭数据库连接,回收资源;如果业务不复杂的话,这段代码写一两次还好,但是如果业务越来越复杂,每次都这样获取数据效率稍低,而且有很多冗余额外的,重复的,每次都必须编写的代码。如何让数据获取更高效、更快捷?可以通过技术手段来实现:表与类之间的映射;属性和成员之间的映射;SQL和函数之间的映射;大多数公司正在使用的ORM、DAO等技术是一种分层抽象,可以提高数据获取的效率,屏蔽连接、游标、结果集的复杂性。因此,分层架构得到了发展。当手写代码从DB获取数据成为普遍痛点时,DAO层应该分层抽象,简化数据获取流程,提高数据获取效率,向上游屏蔽底层复杂性。然后?DAO层抽象后,系统架构不会保持不变:随着业务越来越复杂,业务系统会不断垂直拆分;随着数据量越来越大,数据库会被水平拆分;随着读并发的增加,会增加缓存,减轻数据库的压力;于是系统架构就变成了这样:业务系统垂直拆分,数据库水平拆分,缓存是常见的架构优化手段。这时,web-server层如何获取底层数据呢?根据楼主的经验,以用户数据为例,大致流程如下:先查缓存:先用uid尝试从缓存中获取数据。如果缓存命中,则获取数据Success,返回User实体,流程结束;判断路由:如果cachemiss,先查询路由配置,判断uid落在数据库实例的哪个库;查询DB:通过DAO从对应库中获取uid对应的数据实体User;insertCache:将kv(uid,User)放入缓存中,以便下次缓存查询数据命中缓存;如果业务不复杂,这段代码写一两次还好,但是如果业务越来越复杂,每次都这样获取数据,效率略低,而且有很多冗余,重复,和每次都要写的代码。尤其是业务垂直拆分成多个子系统后:一旦底层稍有变化,就需要对上游所有系统进行升级改造;子系统之间很可能发生代码复制;一旦复制代码,出现bug,多个子系统需要升级修改;你不相信业务会垂直拆分成多个子系统吗?举两个例子:58同城有招聘、房产、二手、二手车、黄页五大业务,都需要接入用户数据;集团旗下有月嫂、保姆、快狗打车、揽福等多项业务,也都需要接入用户数据;如果每个子系统都需要关注缓存、分库、读写分离的复杂性,调用层就会抓狂。如何让数据获取更高效、更快捷?服务化,数据服务层的抽象势在必行。通过抽象数据服务层:web-server层可以像本地函数一样通过RPC接口调用远程数据;数据服务层,只有这部分需要注意缓存、分库、读写分离的复杂性;因此,分层架构再次进化。当业务越来越复杂,垂直拆分的系统越来越多,数据库实现水平拆分,数据层实现缓存加速,当底层数据获取的复杂性成为普遍痛点时,数据服务层应该是抽象化,简化数据获取流程,提高数据获取效率,屏蔽上游底层复杂性。微服务是不是越早越好?Internet分层架构是一个很有趣的问题。服务的引入并不是越快越好:请求处理时间可能会增加;操作和维护可能更复杂;定位问题可能比较麻烦;不要在“微服务”的趋势下鲁莽行事,仓促进行微服务改造。看似“高大上的建筑”背后,隐藏着更多以前没摸过的“大坑”。还是那句话,架构和业务的特点和阶段是相关的:凡是没业务的架构设计都是耍流氓。【本文为专栏作者《58神剑》原创稿件,转载请联系原作者】点此阅读更多该作者好文
