当年一穷二白搞微服务……我太难了
在我最初接触微服务的很长一段时间里,有两类问题都困扰着我和团队,这是让我印象最深的两类问题:
- 没有配合微服务理念的团队
- 没有配合微服务理念的基础设施
后来,在和一些搞了微服务的同行多次交流后,发现他们当初也面临和我类似的问题。
这次就写写我最早搞微服务遇到的问题。
有些问题放到现在来说,已经有解决办法了,已经算不上问题了。但是无论怎样,这些问题如果能提前意识到,早做准备,会为将来搞微服务的同仁们省下许多的力气。
所以,这篇文章我会着重谈下这两类问题。
一、没有配合微服务理念的团队
当年,我还是一个小开发团队的组长,组里将近 10 个程序员,维护着一个庞大的单体系统。
那时微服务刚出来不久,各种评估后,我们认为把系统拆分成微服务可以带来更大的好处。
但是,对于微服务中提到的团队自治这点,由于当时的职位和经验限制,也无法贯彻这一理念,结果,最后就是把自己折腾了底儿掉。
在谈团队自治的问题之前,我先说说拆分微服务的时候,我们当时的整体交付流程是什么样的。
整体流程很简单,业务提需求给我们开发团队,然后开发团队收到业务需求后开发、测试,最后上线。
我们上线流程也比较传统,先是开发人员把应用打包然后上传到一个运维团队规定的路径,然后才由运维团队发布到生产服务器上。
这种模式开始没什么大问题,可是随着我们拆分服务越拆越多,问题出现了。
我们负责的系统很重要,本身上线比较频繁。再搞了微服务之后,因为服务多了,服务器也多了,使得上线部署变得更繁琐。
这逐渐导致运维团队本就不富余的人手更加捉襟见肘,他们只能加班。结果就是,996 成了家常便饭,运维人员对此颇有怨言。
频繁上线不但连累了运维兄弟,还拖累了其他团队——由于运维人手不足,又导致了我们团队和其他团队项目上线经常出现冲突。
冲突发生后,因为我们的项目是公司核心项目,很自然的,优先级我们会占一些便宜。
其他团队的上线只能不断的调整去和我们错开,或者加班等我们上线后,再由运维安排他们的项目上线。
可见,在我搞微服务初期,微服务划分的快速迭代始终因为团队划分和微服务本身的理念不匹配,导致处处受挫。
如果你要全权负责一套微服务项目的时候,一定要万分注意。因为你本身的团队和微服务理念中的团队自治是不匹配的,这会导致你自己微服务项目的维护出现各种各样问题。
对于这类问题,我建议在初期你就要有所考虑。因为这个风险,或许是技术人员不可控的。
二、没有配合微服务理念的基础设施
在一开始,由于我们的微服务是从单体项目逐渐剥离开来的,所以,在这个时候,服务只有 3、4 个。
但是随着对业务理解越来越深入,开发人员也对服务落地越来越熟悉,服务划分的速度也越来越快了。在很短的时间内,服务一下子从三四个,猛增为了近二十个。
这时候,面对猛然暴增的服务,我一下子不知所措了。
除了上面说到的运维上线的问题,还出现了很多我从未经历过的问题。
1. 定位问题成了一件很奢侈的事
通过采用上线模板和其他工具,好不容易缓解了运维问题。还没轻松几天,紧接着,故障处理又出现问题了。
开始的时候,服务数量少,定位问题,大概稍微琢磨下,就能判断出来。但是,随着服务越分越多,定位问题就很麻烦了。
例如出问题后查日志,原来的服务数量少,查日志直接上服务器就查了。但是,现在服务有接近二十个,还没算集群。挨个服务器查日志定位问题,那几乎不可能。
2. 不能再这样了,不然失败就在眼前
后来,我下了决心,在解决这些问题之前,坚决不能再拆新的服务了。
我主动去和领导沟通了这些问题,得到了领导的支持。然后,又拉着领导和业务团队磨了好几次,终于也让他们同意暂时降低一段时间提需求的频率。
总算能腾出精力解决问题了。
3. 关于问题的思考
这些问题,我统统归类为基础设施的问题。其实,那时候虽然微服务生态还没有完全清晰,但是,我本身大概也总结出了一些套路。
我把需要的基础设施分成了两个类别:
- 部署发布
- 日常运维
然后,我分别对这两类基础设施的需求又做了进一步的细化。下面把当时我做的最紧急的一些基础设施需求列了出来:
4. 我控制不了这些问题……
但是,这里依然还有问题。
比如,这些工具理论上是属于基础设施,是不是需要运维团队来维护?可是运维团队已经对我们的各种上线需求不胜其烦了。
又比如,这些工具当时不成熟,我们还得自己开发改进,而这又要靠谁呢?
当时没有办法,我只能咬牙自己带了几个人,把这些额外的工作承担了下来,由我们几个人专门开发和维护这些工具。
一直到后来,市面上有了成熟的工具链,我本身也升职,可以对技术团队整体去贯彻 DevOps 理念了,才真的从这些任务中解脱开来。
5. 基础设施决定上层建筑啊,同志们
我知道很多公司是技术自己提出来微服务的,提出来的时候,你一定要清楚,微服务这套体系本身,
把以前单体系统的复杂度转移到了技术基础设施上。
很多工作其实是需要自动化的。在踏进微服务这个神坑前,一定要考虑清楚:公司有没有合适的基础设施?
三、落地需要妥协的其他的一些细节问题
微服务理论看上去是很完美的,但是,在现实落地,其实还会有许许多多不太可能马上完美贴合微服务理论的问题。
我大概列举几个重要的:
1. 数据库划分的问题
老实讲,咱们这篇文章本来就是在说一个服务一个数据库的模式。那么按理来讲,严格符合这个模式是最好的。但是,实际落地来讲,中间有太多的弯弯绕绕了。
比如,我们的服务需要划分成四五十个服务,这个时候,数据库划分成同样的四五十个库就不合适了。因为这会引入如下的三个问题:
-
数据库管理过于复杂——这个是很显然的问题,管理几个数据库和管理几十个数据库,需要投入的人力物力是完全不一样的。每一台数据库本身就是个很复杂的系统,数量越多,出问题的几率也越大,监控难度也越大。
-
分布式一致性实现太过复杂——数据库数量上来了,因为业务需要,协调数据一致性从原先需要协调几个数据库的状态变成了需要同时协调几十个。复杂度一下子上去了,这也会造成很多不必要的技术问题。
-
跨库查询相当不方便——这个问题也是一样的,当我们服务划分后,数据库如果也划分的过细,那么以前需要跨几个库查询的业务,就可能变成需要跨十几个库查询。
所以,就落地的时候来讲,还是需要有个业务域的概念。这也是为什么微服务总和领域驱动设计绑定在一起,因为人家天然有个业务域的概念。
这时候,就可以考虑某些业务域,共享一些数据库。比如,订单业务域可以每个服务对应一台数据库,但是,用户业务域可能就可以共享那么一台数据库。
2. 开发框架的问题
我搞微服务比较早,所以,开始做的时候,就是用了 Spring 的框架,然后每个 Tomcat 后面放个服务。
那时候,维护起来真麻烦。因为 Tomcat 本身多了,又和应用不是一体的,同时维护 Tomcat 和应用,非常难受。
后来有了 SpringBoot,情况好了很多。再后来,我们也尝试使用了一阵子 Dubbo。
其实各有自己的不足。
SpringBoot 的不足主要是,用了 SpringBoot,很多时候就不得不用更多的 Spring 其他组件,哪怕它的一些组件很不让人满意。感觉项目中处处 Spring,非得走 Spring 那套规则不可。
Dubbo 的不足主要是能配合的组件很少,我们用 Dubbo 其实很早,但是为了和 Dubbo 配合,有些时候还得做很多额外的开发。比如,当时 Dubbo 本身服务跟踪,也没有通过 RabbitMQ 通信的组件,我们都需要自己开发。
所以,当你要选框架的时候,要考虑清楚,因为微服务本身是一大套生态。如果框架本身选用不合适,后期就得靠自己的技术能力去做硬调整。
3. 一些关键技术何时引入的问题
有些关键技术,我们是逐渐引入的。
因为,引入一个新技术,对我们无论是开发还是维护,引入便利性的同时可能也会引入复杂性。
比如容器技术,我们就是搞了很久了才慢慢引入的。引入容器技术后,很多问题(例如网络、内存)我们就要多想一层,看看是不是因为容器导致了其他问题。
总之,对于一个正在运营的系统,我个人认为引入新技术需要谨慎评估。
最后
以上写的主要是我和团队的经历,可能你会觉得是一家之言。没关系,说的不对的,欢迎指正,虚心接受;说的对的,希望能让给大家一些借鉴
对于一个服务一个数据库说到现在,我说了为什么要分服务,以及如何落地还有带来的一些问题。
对于这种模式,它引入的问题其实非常多,一本书可能都说不完,这里只是举了一些我遇到的一些我记忆里很深刻的问题。
那么,把一套系统改造成一套微服务就需要分服务和分库就完了吗?解决分服务和分库带来的一些问题就完了吗?
那可不是,因为有些问题非得引入一些新的模式才能最好最省心的解决,只有把多种微服务的模式配合起来,才能让微服务这个生态完全的运转起来去替代以前的单体项目生态。
在后面的文章里,我会讲解该怎么用模式去解决一些棘手的性能问题,怎么用模式去平衡读写负载失衡的问题等等。只有通过模式把分服务引起的各种开发问题解决了,一套微服务系统我们才能说架构完全成功了,所以,我会以我的架构经验去把整套微服务架构通过模式去讲清楚一套微服务到底应该如何架构。