为什么需要微服务

在今后的三个月内我将陆续推出一个有关微服务设计与落地的专栏,专栏将分为微服务思想和理论基础、微服务编程指南、微服务案例教学三个部分。本专栏的设想是使用最朴素的概念和语言帮助一个没有后端开发经验的人通过循序渐进的学习逐渐掌握微服务架构思想,并能获得一定的后端编程技能。——此为前言!


著名的软件项目经理、“IBM 360系统之父”、图灵奖获得者布鲁克斯曾在他的著作《人月神话》中谈到过编程职业的乐趣和苦恼。他指出编程之所以有趣,是因为编程的快乐不仅满足了我们内心深处进行创造的渴望,而且还唤醒了每个人内心的情感。而编程之所以让人苦恼,是因为编程的过程附带着琐碎的bug、重复性的劳动、复杂的业务逻辑等等难以解决的问题,困难会很快磨灭人们的热情。

这,就是编程,一个许多人痛苦挣扎的焦油坑以及一种乐趣和苦恼共存的创造性活动。

—— 引自《人月神话》,焦油坑

《人月神话》已经问世了近三十年,书中的焦油坑现象是否依旧存在呢?答案是肯定的!从移动互联网普及之前就进入这个行业的我,最直接的感受就是《人月神话》中提及的焦油坑现象或与再过三十年依旧会存在,但总体趋势会往好的方向发展。随着编程行业内各种系统工具和编程框架的一次又一次革新,编程所带来的苦恼正在逐渐减少,尤其是近些年来随着云计算和微服务思想的普及使得人们实施大型编程项目变得更加容易。

如何编写程序

如果你对编程还一无所知,那么请容我用一点点时间来向你解释我朴素的编程理论。编程就是通过计算机的能力帮助我们解决问题。如果你需要管理自己的公司,那么你有几个员工,那就利用计算机的抽象能力在虚拟世界里创建几个员工。利用计算机的存储能力记录下他们上下班的时间、工作任务的完成情况、工作的产出等。然后利用互联网把这些信息从你公司的设备传输到你的手机上。这个时候你就得到了一个可以监管企业生产的程序,然后就可以躺在床上管理你的公司了。

说起来容易做起来难。你需要掌握面向对象的编程思想来实现对现实世界中员工的抽象,创建诸如名字、工号、职务和性别等属性,赋予他们类似拧螺丝、搬砖、写材料的行为。还需要提前设定好规则来让他们正常工作,比如你可以让员工不需要你的安排就可以自发处理客户订单的逻辑,这种逻辑大多数时候都是由一些分支和循环语句组成。比如:如果有订单的要求是获取一个A产品,那么就安排工作给负责生产A产品的员工,让他生产一个A产品;如果订单要求获取999个B产品,那么就安排工作给1个负责生产B产品的员工,让他重复999次B产品的生产任务。当然你还可以直接将工作分配给999个负责生产B产品的员工,让他们同时生产。如果你的员工没有999个,但你又想用最快的速度完成订单,那么你就需要一点更复杂的逻辑。做完上面这些,你还需要使用数据库系统去把所有的数据存储起来。最后还需要编写网络程序以保证信息可以在互联网中传输。

随着话题的深入,编写程序这件事情似乎越来越难。尤其是当你要解决在现实世界中本身就很复杂的问题时,编写程序这项工作所能给你带来的创造性快感很快会被这些错综复杂的现实问题消磨殆尽。但是不要沮丧,你会使用代入法或者加减法对复杂的方程进行消元,你也一定能理解编程,当一件事情复杂到无法解决的时候,就把它分解成为多个相对简单的小问题,重复这个过程直到你能容易的解决这些小问题,这种朴素的分而治之的思想基本就是软件工程的全部了。

在过去的几十年来人类积攒了大量的代码,这些代码被打包成为各种技术脚手架用于解决各类问题。一般情况下你不需要去编写一个把数据存储在硬盘上的程序,因为已经有人写了这样的代码并把它们打包成了数据库软件供你使用;你也不需要去编写把网络数据转换成为网页的程序,因为有人已经制定了标准并提供了浏览器程序帮助你完成这件事情。随着时间的推移你甚至不需要写任何代码,借助低代码平台将自己期望的工作流程按照一定规则配置起来就可以得到一个能够解决你问题的程序。

你可以使用三个月的时间去学习编程所必须的技能,掌握和计算机交流的编程语言,但你绝对写不出来什么像样的编程产品。编写程序的重点在于你必须知道如何解决问题和如何分解复杂问题。微服务就是为了解决这些复杂问题而生的。

微服务思想帮助开发者保持轻松与专注

很多编剧都看过一本叫做《步步为营》的书,这本书专门教授编剧们如何去编写情节跌宕起伏的剧本。正如这本书的名字一样,编剧在编写剧本的时候需要以步步为营的心态去通盘考虑所有事情才能让作品即合理又离奇,最终达到出乎意料之外,又在情理之中的效果,由此可见编剧的工作似乎并不轻松。很多时候编程也是这样,尤其是在处理复杂问题的时候,程序员同样需要保持这种步步为营状态去编写每一行代码。但是你考虑的越多,往往你就越难完成好这件事情。

上面我们说到编程的本质就是解决问题,而解决问题的核心在于分解问题。我们会把一个复杂问题分解成为很多小的问题。微服务的原则是针对一个小的问题,我们创建一个小的领域,编程的时候你只需要关心当前领域内的问题如何解决而暂不考虑其他领域的问题。这种方法带来的直接好处就是编程的难度会被大幅度降低,你可以使用一种轻松的状态专注于眼前的某一个领域,一个微服务就是为了解决某一个领域的问题,而将眼前的事情做好往往才能做好更多事情。

将复杂问题的解决拆解为很多小的领域,这些小的领域都专注于解决某一个小问题,对应的微服务就是这个领域的解决方案。在编码的时候不再需要再去保持那种步步为营的紧张心态,因为在当前面对的领域中你不需要考虑其它领域的问题,所以一次性要解决的问题就变得更少,要考虑的因素也就更少,这样就可以保持专注以一种轻松自如的状态发挥出自己最好的水平去解决问题。

总结,微服务使用服务拆分的技巧把复杂问题拆解,实现了复杂业务逻辑的解耦。每一个微服务都是一个独立的小程序,你可以用自己的全部力量去编写一个小程序。编写简单的小规模的程序让人感觉到轻松也更加容易保持专注。

微服务让团队协作更加容易

软件分治的思想不单单可以通过微服务的方式来落地。微服务技术出现之前大型项目依旧能够被组织的很好,软件架构师会将复杂问题拆解,然后将任务下发给各个团队,团队之间通过各种约定作为前提,各自去完成对应的工作,最终再将大家的产出组装成一个庞大的应用,为了确保最终大家的代码能够被合并在一起,大多数时候工程师们都必须使用同样的技术框架和编程语言。

正如上面所说,在没有微服务技术之前软件团队使用各种各样的手段进行分工协作来解决复杂问题,但最终一定有一个整合的过程。如果一个产品各个模块的功能都已经完成但就是迟迟无法上线,那多半就是还处于整合阶段。代码整合需要耗费大量的人力和时间,而微服务则可以提高这一步骤的实施效率。

一个微服务就一个完整的软件。使用微服务来作为团队的产出,团队最终交付的是产品而非一堆代码。架构师不用去关心团队使用了什么样的编程语言和技术,不需要面对来自不同团队的不同模块的代码,只需要按照事先约定好的服务规划方案整合各个团队产出的微服务软件即可。如果需要一个锤子那就让团队去造一个锤子,而不是让团队只给你木头和铁块儿。这种直接产出完整软件的工作方式减少了代码整合的难度,也让每一支团队都能专注的在自己擅长的领域内工作。

微服务模式给团队带来的另一好处是使得团队的目标更加明确。传统的软件开发中,大家产出的不是产品而是代码库,工作目标多少有些不明确,稍有不慎就可能迷失在代码细节中以至于忘记自己最初的目的。微服务架构师给出明确的服务拆分方案,告诉各个团队他们各自应当去解决的问题。团队在编码过程中会有明确的目标,所有的工作都将是以目标为导向的。

微服务模式还能保证工作界限足够清晰。在服务拆分之后每一个微服务本质上就是一个全新的小型项目,这样的小型项目一个小型团队就能胜任。大家解决各自领域内的问题,产出产品,并保证在之后依旧能维护自己的产品。我愿意称这种模式为生产责任制,使用这种生产责任制的协作方式让团队的工作界限更加清晰,保证团队始终对自己的微服务负责。

微服务能更好的应对变化

上面提到传统解决方案的实现方式,其最终步骤是将多个模块的代码进行整合,从而形成一个完整的可以解决一系列问题的编程产品。在实施过程中,这样的工作模式会很快消磨掉编码人员的工作热情,无法保证程序员能投入最大的专注力去解决问题,往往还会在团队协作和工作界限上带来隐患。我们把这种程序称之为单体应用,相较于微服务它需要投入更多的精力去实施,同时也需要投入更多的代价去进行维护。

单体架构程序臃肿而庞大,这种程序发布之后除了架构师之外恐怕没有任何人能够解其全貌。基于这样的程序,软件工程师们很难对变化做出快速的响应,一个典型的例子就是2021年所发生的几起新冠疫情一码通系统宕机且无法快速恢复的事件。据我所知某城市的一码通系统采用的就是传统的单体架构程序,简单来讲这样的程序仅仅有一个进程,一旦系统出现了不可预知的错误将有很大的概率导致整个程序停止服务,而要对其做出修复则需要重新测试整个程序的所有功能然后重新发布新的版本。所以在当时全城的人都开始集中访问一码通系统的时候,这种单体程序因为算力的缺失而无法正常提供服务,最终不得不发出公告请求用户非必要不使用一码通系统。最终,这个一码通系统阉割掉了许多原有的功能只保留最核心的风险码查询业务才堪堪保证了高峰时间的正常运行。

我能理解一码通系统的架构师在面对海量请求时,明知问题出在哪里但又无法快速解决问题时的绝望。假设那个城市的一码通系统采用的是微服务架构而非单体架构,我敢保证在面对突发状况时技术团队的响应速度一定能快很多。首先基于微服务架构的编程产品很大概率不会因为某一个模块无法正常工作而导致系统整体无法提供服务。其次微服务架构不会在遇到算力和网络瓶颈的时候整整十几个小时无法完成算力补充。最后微服务架构在需要进行应急发布的时候决不会中断所有服务。

为了保证系统的可用性,微服务架构的程序并没有将鸡蛋放在同一个篮子里,所以不会出现因为某一种突发情况打翻整篮子的鸡蛋情况。微服务架构的程序使用不同进程不同服务的形式粗暴的隔离了系统的各种功能,当一个服务需要应对变化的时候仅需要更新某一个服务而不必关心其他不相关的服务。微服务架构的程序在解决某一个问题的时候可以方便的进行拓展,大多数时候处理流量激增的事件最简单的做法就是再开启一个相同的服务,结合云服务动态伸缩的特性,只要使用微服务架构,我可以保证在几分钟之内将系统的处理上限提升好几倍。

何时使用微服务

与其去谈论何时使用微服务,倒不如直接告诉你何时一定不要使用微服务。当我们要解决的问题本身并不复杂的时候,盲目的使用微服务架构也许会适得其反。我们不能用一个本身就很复杂的方法去解决一个原本并不复杂的问题。所以在面对规模相对较小、功能较为单一的程序时,我们使用原有的单体架构进行程序设计即可,即使在后期遇到了诸如功能拓展、产品升级的需求,我们依旧可以快速将单体架构的程序改造成为微服务。

相信坚持读到这里的读者应当对微服务有了一定的了解。在上面的描述中我花费了大量的文笔去解释微服务的价值,它能够帮助软件开发人员解决复杂问题,能够让团队的工作变得轻松,能够让大家都在自己擅长的领域内保持专注,能够帮助软件团队快速应对不可预知的变化。但实际上微服务远没有上文说的那么简单,当我们试图去解决复杂问题时,微服务本身的设计就又成了新的复杂问题,但大多数时候这种复杂程度通过借鉴前人的经验和充分的调研与分析可以被削减到能够让软件工程师接受的程度,所以微服务也并非解决一切问题的银弹。

最近两年来我用微服务架构落地了两个规模较大的项目,并在项目的开发和维护中尝到了很多微服务的甜头,本文中对微服务的推崇也是这两个项目给我带来的最直观的体验。但我毕竟会因行业限制、个人阅历不足和工作经验不够等问题所带来的认知偏差而犯错,关于微服务的专业解释网络上会有更专业的资料,本文仅仅是采用一种较为朴素的形式描述个人对于微服务的感受,如果各位读者有不同的意见希望及时与我沟通或在评论区留下你的见解。

写在后面:今天博客的域名终于审核通过了!大家记住域名是 www.lovedotnet.top

你可能感兴趣的:(为什么需要微服务)