今天这篇文章我们继续说架构师大刘的故事。
故事纯属虚构,别对号入座哈。
前言大刘日子最近还不错,经常午睡醒来,就继续拿着手机看小说摸鱼。大刘对当前所在的这家公司比较满意。大部分系统已经成熟稳定,用户量也中规中矩。虽然有些项目技术陈旧,但好处是没啥幺蛾子技术问题冒出来等着解决。
只是有时候大刘心里会打鼓,公司盈利在下降,巅峰不在,也不知道这家公司能撑多久。除了偶然会冒出些对工作稳定的担忧以外,大部分时候,大刘心情都是愉快的。直到他被领导叫到办公室分派新任务的那一刻……
大刘的领导 CTO 老李,这些日子心情不是很好。他在的这家公司原本是个以传统业务为主的公司。为了跟上互联网时代,大老板拍脑袋成立了个技术部门搞互联网。虽说公司已经号称触网了,但是公司盈利基本还是靠传统业务,技术部门只是打辅助的。没有业务主动权,没有盈利点,部门员工的工资却都不低,老李的地位就可见一般了,经常受些冷言冷语的夹板气。再加上,最近公司的效益也有所下降,眼见技术部门面临着裁员的危险。老李危机意识被极大的刺激到了。
老李是个技术出身,但是离开一线编码已经快十年了,每天的工作其实就是管理加玩概念。这几年微服务的概念非常火爆,老李一直想着能搞点这种热门东西,然后再拿着这些做出来的新概念技术,给那个不懂技术的大老板展示下自己的两把刷子,同时也能打响在业界的名声,对自己的职业发展也大有好处。趁着构思部门前途这时当,老李认为这也是搞微服务的好时机,同时也想到了有微服务经验的大刘。于是,大刘就被召唤进了办公室……
经过了几个小时的讨论,大刘面带无奈的接下了这个任务。这个任务是这样的:
把公司里几套运行多年的核心系统改造成微服务。
这些个老系统当初是按照几万用户量的目标去设计开发的,虽然现在跑着没问题,但是眼光要看长远,产品和技术们将搞一套更高级的东西,目标是这套系统会被几百万人使用。
OK,微服务使用的前提出现了。
大刘来这家公司之前,在某电商大厂干了多年,对微服务在电商系统中的应用这块有实践、有经验。对微服务这块,大刘是吃过猪肉、也见过猪跑,还被猪咬过……嗯,对,还被咬过不止一口两口。所以,对改造微服务这个任务,大刘是硬着头皮接下来的。
大刘虽然无奈,但是看在工资的份上活还得干。不过槽还是要吐的,于是下班后大刘用了几小时码出了下面这堆心里话。
正文开始(以下是大刘的第一人称):
0最近,经常有同事和我聊微服务,也屡屡期望对公司已有项目进行改造,希望能把所有项目改造成微服务方式。我对此经常很无语,也屡屡对这些人进行劝阻。
我认为,劝我改造微服务的人之中,有一些人纯粹的对技术痴迷太深。更甚些,我甚至可以说这些人中的某些人就是纯粹的自私自利。搞微服务难道不是为了蹭热点,为自己的简历增色,为下一步跳槽涨薪做准备?何尝想过微服务为公司带来的各种坏处和因此而来的成本提升?另外有些人,则纯粹是被外面铺天盖地的微服务概念给打晕了头,被各种微服务成功故事洗了脑。这些人,把微服务当成了万能药,纯粹就是脑袋犯了糊涂,陷入了唯技术论。
为了说明微服务不是万能药,这里我们就先要说明下微服务的概念。同时呢,我们也需要诠释清楚微服务的优缺点,看看什么时候用微服务,什么时候不用。
什么是微服务?对于微服务的定义,网上众说纷纭,并没有一个权威的定义。但是在这些纷繁复杂,云山雾罩的各种微服务洗脑文和说明文之后,总是有一个统一的基本面在:即微服务是一种利用分治法的思想,去把一整套非常复杂的业务逻辑给切分成多个简单的业务问题,并采用模块化方法去实现组合的一种架构方法。
这么说是不是还很抽象呢?好,咱们再更深入的解释下,并顺便把微服务的优缺点也全部一并说清楚。
1首先,微服务是采用分治法思想,需要对业务逻辑做分解。做完分解后,还需要多个对应的实现模块去实现分解后的业务问题。这些模块的开发和维护,是都需要成本的。如果我们要搞微服务,考虑过开发维护成本吗?
上面这图表明了,从项目一开始,微服务的代码开发和维护每行平均成本就不少,随着项目规模和系统复杂度的上升,代码的开发和维护平均成本才会缓慢下降并逐渐收敛到某一个值左右恒定。
而单体项目正好相反,一开始,单体项目的每行代码平均成本是比较低的,随着项目规模和系统复杂度的上升,代码开发和维护成本会慢慢上涨,后续可能复杂度和开发成本会越来越高,一直冲上天际。
这时候,就不得不迫使人们去找到一种比较合适的方法,能把开发和维护成本降低到项目团队可以承受的程度。
这就是引入微服务的意义所在。
但是,所有的项目会一直发展下去吗?所有的项目会永远运行并扩展吗?
有很多的架构师或者技术人员,在一开始做架构和系统设计的时候,不考虑实际情况,在公司给出一项很紧迫的任务之后,不去考虑实现时间和开发成本,上来就搞高大上,起手就是微服务,这现实吗?
我们这些技术人员看过许多鼓吹微服务的技术书籍,也看到过很多微服务的“成功学”,但是他们的前提是什么?他们对微服务的说法统统是建立在一个只有技术存在的完美世界里,把现实世界他们认为的一切杂音都摒除在外,这合适吗?
我们在做架构师之前,第一个考虑的应该是投入和产出。固然,我们从技术角度考虑,一定会要考虑可扩展性,可维护性之类的技术指标。但是,我们也需要根据当前项目的重要程度,盈利前景,还有可用服务器资源等,作出自己的平衡来。
2第二,微服务的另一个优势是弹性化。什么意思呢?就是我们在业务逻辑改变时,那些对应业务逻辑改变的功能的增删改,开发和部署成本很低,可以像弹簧一样,自由的缩减和增加。
并且,微服务里最佳实践是每个分出的模块应该都有自己的数据库,和别的微服务并不共享任何数据库。所以微服务本身认为,每个微服务模块的数据库都可以不一样。
比如我们开发一个电商网站,如果搞成微服务,大概如下:
如果我们的业务逻辑做了一些调整,比如,我们想要增加一个积分功能,那么,我们只需要再增加一个叫做积分的微服务即可。
这就是微服务的便利之处。
但是,我们承认吧,并不是我们所做的每个系统都足够大,都大到需要分解成更多更小的服务。那些不是太复杂的系统,它们凭什么需要弹性化?凭什么需要切分业务,从而搞出一大堆的项目出来呢?
另外,微服务的弹性化带来的问题就是,我们需要管理因为弹性化所切分的许多小项目,需要搞出一套易用的自动化管理系统,需要把公司的底层基础设置打造好,请问,这些成本,你准备付出了吗?
在这个现实的世界里,并不是一切围绕着技术打转的。固然,技术欠债会让我们这些技术从业者感到分外的困扰和难受。可是,假如我们超前超度的使用了我们可能并不需要的超前概念和超前架构,同样会使我们感到痛苦。
如果我们控制住了自己的技术欲望,我们是不是从自身也控制了一部分技术欠债呢?这是一个架构师应该要思考的地方,也是我们不应该滥用微服务的原因之一。
3第三,微服务起手就是分布式。分布式我承认有各种各样的优点,但是,分布式引发的各种问题和因此需要引入的各种技术解决方案本身也有自身的问题。
比如,分布式事务。在引入微服务前,我们作为架构师,一定要思考后续是不是可能出现跨服务的事务。兄弟,分布式事务大家都知道有多困难的。
按照微服务的标准,服务之间的通讯应该尽量采用简单的 RESTFUL 协议。那么,根据这种规范,如果我们采用了微服务方式架构,我们的每个项目都应该搞成 REST 服务。REST 服务本身就是无状态的,现在,如果业务里出现了严重依赖状态的跨服务事务,想想吧,你会面临什么:
分布式锁方案你是不是要考虑下?分布式互锁后,出现了死锁,你的追踪策略是什么?如果出现了竞争资源,导致服务状态不一致了,你怎么去快速恢复?数据腐蚀你有办法吗?
什么?你告诉我我说市面上有很多成熟的分布式事务解决方案?别自欺欺人了,咱们都是搞技术的,请问,你说的是两阶段提交(2PC)吗?好吧,大家都知道 2PC 那可怜兮兮的性能。
好吧,那三阶段提交(3PC)呢?它的不一致问题曾经让我们彻夜难眠。
搞 TCC 或者 SAGA 呢?对不起,因为最终一致性所添加的业务紧耦合的各种消息和通知,会直接犹如 24 小时的梦魇,可能会是压垮你的最后一根稻草。
微服务的提倡者老马丁自己也说,微服务引入了最终一致性问题。
对于原来单体项目很简单的事务问题,在微服务中,是一个令人皱眉的困难问题。所有微服务的开发者,在开发微服务代码之前,都需要考虑怎么能探测到数据不一致的问题。否则,一定会万分后悔。
那么,分布式事务会不会一定会出现在微服务中呢?从目前来看,几乎无法避免。为了搞定这些问题,微服务实现往往还需要伴随着实现一整套构建在无状态服务之上的调用链。
对于这些额外的开发成本,我们有必要吗?是所有项目都需要的吗?不是吧。这就是我们架构师需要考虑的问题,也是我们需要谨慎和妥协的地方。
4第四,微服务互相之间是通过网络通信配合起来来对外提供服务的。这就会带来一个依赖性问题,即微服务非常依赖底层网络的健康。
如果网络通信之间出了问题,整体对外的服务质量就会降低到极其让人难以接受的程度。
并且,网络通信天然就一定会带来延迟。本来单体项目我们好好的,大家都是在内部互相通信,延迟基本可以忽略不计。
现在,大家分开了,互相得远距离打招呼,延迟动不动就来个几十毫秒几百毫秒延迟。这些延迟,我们也需要考虑在内,必须经过严格的测试才可以。
另外,网络通信出现问题后的各种容错方案,也必须考虑完善。以上说的这些,也都是一个合格的架构师必须在微服务引入之前,所要进行的综合的考量。