你做的是微服务还是小单体?

先讲一个关于微服务的小故事:第一次接触到微服务这个概念的时候,我的第一反应以为微服务就是微信提供的某种服务。那段时间正是微信生态开始爆炸繁衍的时候,全中国好像把微信当成了和上世界90年代一样的下海年代,各种诸如微商,微店,微社区之类的微X概念盛行。不过自从稍微对这个名词进行了研究以后,我就再也不信任自己大脑的第一反应了。人类大脑在认知新概念的时候都会优先采用偷懒模式,首先尝试用一些已知的概念进行连接,发现已知概念都无法连接以后才会去建立一个新的概念出来。我们都需要警惕这个认知陷阱。

有哪些是微服务的误解?

总所周知,微服务这个概念是Martin Fowler大叔和James Lewis在2014年提出来的(https://martinfowler.com/articles/microservices.html),而大叔又是我们ThoughtWorks的“Chief Scientist”,所以这几年我们在全球的微服务相关业务一直保持迅猛增长的势头,感觉可以堪比山东蓝翔的挖掘机技术了。

这几年,不论是大小的传统银行,还是某个制造业龙头,甚至连一些政府机构都找到我们说:我们的核心系统要进行变成微服务的,我们的ERP要进行微服务改造,我们要做一个数字化的微服务平台。当我们进一步询问对方为什么要进行微服务改造的时候,有的客户说是现在系统太大不好维护拆小了才好维护,有的客户说要学阿里搞数字化中台。

如果让这些客户描述一下在他们心中什么才是微服务的时候,下面是一些常见的回答:

  • 业务方觉得,微服务就是有很多的小服务可以让我调用,当我要开展一个新业务的时候,可以很快地对这些服务进行组装。
  • 技术方觉得,微服务就是用Spring Boot框架构建HTTP服务,要构建轻量级的RESTful API,要使用API Gateway,要能够做到服务的注册和发现,微服务可以使用Docker容器运行,并且使用Kubernate进行集群管理等等,好像只要使用了这些新技术就是微服务了。

本人已经在多个项目中进行过微服务的设计和拆分,也最终能够端到端地把设计的微服务最终落地实现出来。所以上面这些回答在我看来好像都少点什么。业务方想要的是能够快速实现新需求,但是如果我把服务都做到一个单体里面,新需求也可以通过组装服务接口来快速实现。技术方关注的是各种框架和技术,但是如果使用了这些框架和技术以后,随着各种新需求的实现,“微服务”开始慢慢的膨胀起来,有一天你发现膨胀的“微服务”有一部分业务能力需要拆分出去,但这个服务内部过度耦合的实现让你已经无从下手,难道要再进行一次微服务改造吗?

微服务的核心价值是什么?

让我们先统一一下微服务定义,全世界谈到微服务的时候都在引用老马的这个定义:“微服务是一种新的软件架构术语,微服务架构描述的是通过一组可以独立部署的服务来构建软件应用的架构。虽然没有对此架构体系的精确定义,但是有一些共同的特征:围绕组织和业务能力,自动化部署,智能化的端点,去中心化的编程语言和数据。“

在这个定义里其实并没有给出微服务应该使用什么技术,也没有说一个微服务应该多大。微服务只是一种架构风格,这种价格风格构建出来的软件可能具有哪些特征。既然是一种软件架构风格,而且我们都知道如果要构建一个软件应用,采用10个微服务的架构风格来构建,肯定要比采用一个服务来构建的成本要高很多,因为除了相同的功能以外,微服务架构还需要考虑服务之间如何进行交互,如何保证安全等诸多问题。那为什么这些软件行业的大师们要推崇这样一种明显增加开发成本的架构方式呢?

关于这个问题,只要做过大型企业级软件应用开发的朋友们一定会直接想到答案。大型软件应用通常都有很长的生命周期,在开始开发的时候采用传统单体架构也许会很快实现功能。但是会不断地有新功能要被添加进来,随着功能越来越多,软件的复杂度会急剧上升,修改bug或者增加一个新功能的成本越来越高,甚至有一天会发生无法下手修改的情况。这个问题其实从有了软件这个行业以来就一直困扰着软件工程师们,他们也尝试了很多种方法去解决这个问题,有人从项目管理角度入手,认为好的项目管理可以让软件更好维护;有人从工程实践角度入手,认为采用各种敏捷方法可以让软件更好维护。可惜没有一个是能够彻底解决问题的银弹。

微服务架构风格同样也是为了解决软件维护困难而被发明的,所以我希望所有正在正在进行微服务改造或者准备开发一个微服务软件应用的朋友们都能够先明确我们要从微服务中获得的最核心价值是什么:就是让软件系统在不停扩张的同时却没有过度地增加软件维护成本。基于这个核心价值,使用什么技术,使用什么语言,有没有用Docker,拆分了多少个微服务等等这些都不是一个好的微服务软件系统的核心诉求。

弄清楚了这个根本性问题,相信下一个问题已经在你脑中浮现了:微服务架构为什么能够解决这个软件系统难维护的问题呢?对于这个问题一个比较简单直接的回答是因为系统被拆小了,拆分以后的微服务复杂度降低了,这样修改也就容易了。但是仔细想想这跟答案也是有不充分的地方:

  1. 在拆分以后如果要修改一个功能发现有修改好多个微服务,这不是变的更复杂更难维护了吗?
  2. 拆分以后的一个微服务膨胀速度很快,那在这个微服务上是不是维护成本也会越来越高呢?

从这两个追问我们可以发现,拆成多少个微服务不是微服务架构的要点。如何保证拆出来的微服务容易维护,而不又是一个小单体,这才是微服务架构的要点和难点。很多客户和行业内的朋友在聊到微服务的时候也都提到,他们知道微服务架构是好东西,但是对一个微服务应该是怎么拆分和设计出来是完全没有概念的。

所以,如何设计或拆分才能避免拆分出来的微服务不会只是一个拆小的小单体,这才是所有打算采用微服务架构的组织最需要关注和解决的难点问题。

如何拆才能避免小单体?

关于微服务拆分和设计,就不得不提到我司另外一位同事Newman的作品《微服务设计》,相信很多人都读过这本书,这本书很薄,但是里面却涉及到了关于微服务所有的的方面,服务建模,服务集成,服务部署,服务测试,服务监控,服务安全几乎全部都囊括了。但是美中不足是每一个问题都只是点到即止,如果作者能够用一个构建微服务的案例来串起来所有这些知识,我相信这本书会更赢得更多的好评。

在《微服务设计》的“第三章 如何建模服务”中,主要介绍的就是如何确定服务之间的边界。Newman给出了两个好服务的标准:

  • 低耦合:如果做到了服务之间的松耦合,那么修改一个服务就不需要修改另一个服务。一个松耦合的服务应该尽可能少地知道与之协作的那些服务的信息。
  • 高内聚:就是把相关的行为聚集在一起,把不相关的行为放在别处。如果你要修改某个服务的行为,最好只在一处修改。

这两个标准是只要熟悉面向对象编程的人都铭记于心的标准,甚至是很多人经常挂在嘴边的。那么在微服务架构中如何做才能满足这两个标准呢?Newman给出的方法是由Eric Evans提出的领域驱动设计(Domain Driven Design 下面简称DDD),DDD是Eric在2004提出的,早于微服务10年,所以从时间上可以看出DDD也不可能是为微服务准备的。但是DDD的学习曲线过于陡峭对软件工程师要求较高,大部分公司也已经习惯了用简单的单体架构来开发,所以DDD一直只是少部分高端软件工程师的玩具。而微服务架构流行以后,大家发现使用DDD方法可以帮助设计出高内聚低耦合的微服务,这样DDD也成为了微服务设计的最佳实践。

客观来说,从我接触和实践过的各种微服务拆分方法论中,DDD虽然不是唯一的,但是通过DDD建立的软件架构在实战落地时能够带来的好处是非常明显的。

举一个具体项目的例子,在项目中我们使用DDD方法定义好了限界上下文(支付微服务),以及上下文内部的聚合。所以在一个支付微服务中有支付聚合,账户聚合,日志聚合,这些聚合时间通过消息订阅方式进行通信。比如当支付聚合提交支付经办以后,会向事件发布器发布一个支付已提交事件,然后事件发布器会找到这个事件的两个订阅者账户聚合和日志聚合,账户聚合会根据事件保存支付的收款方信息,而日志聚合记录一条提交支付的日志。可以明显看到聚合之间通过事件实现了解耦,当需要改动一个聚合时并不会导致另外一个聚合的变动。

随着项目的进行,很多微服务里面都有了日志聚合,然后我们发现好像应该有一个微服务用来专门处理和日志相关的逻辑了。这时候基于上面的架构,我们可以很容易的把支付微服务中的账户聚合,日志聚合抽离出去形成新的微服务。要知道这种基于聚合来拆分或合并微服务的动作是在项目开发中经常发生的事情,如果每次当你需要从微服务中拆分一些模型和逻辑时候都发现这不是一个简单容易个过程,那么你需要停下来想想是不是又在构建一个小单体了

不要买椟还珠

最后让我再用另外一个故事来收尾吧,在我最近参与的微服务设计改造项目中,客户找了两个咨询公司来帮他们进行微服务识别,我们采用的是DDD和事件风暴工作坊的方法一步步推导出限界上下文。最后客户在比较了双方的产出物后提出一个疑问,就是如果从识别了多少个微服务来看,两个咨询公司的结果好像没有太大的差异?我觉得这种问题比较普遍,很多时候大家对微服务设计的理解都是以为只要最后确定拆分出多少个微服务就可以了。根据我这篇文章前面的论述相信你能够明白,在进行微服务设计之后,最有价值的东西是设计出来的微服务当业务的发展需要进行拆分和重新组合时,这个过程是非常轻松而且简单的。至于拆分出多少个微服务,定义了多少个API这些比较显而易见的度量指标并不能给你带来微服务架构的真正价值,它们只是用来包装珍珠的盒子而已。

在这篇文章中多次提到了DDD,限界上下文这些概念,由于篇幅限制这里没有深入对这些概念进行展开。所以我在下面特别准备了一些书单,在这些书中有更详细的介绍。

  1. 《领域驱动设计》Eric Evan著,这本书非常有名,但是阅读难度较大,有很多人表示这本书读不懂,我自己前前后后至少读了三遍以上,豆瓣地址https://book.douban.com/subject/1629512/
  2. 《实现领域驱动设计》Vaughn Vernon著,书比较厚,但是很落地,有很多实际的例子来讲解每个DDD的概念应该如何应用,尤其是提出了领域事件这个模型作为DDD的一个充分补充 https://book.douban.com/subject/25844633/
  3. 《领域驱动设计模式、原理与实践》 (Scott Millett) / Nick Tune著,这本书也是非常好的一本书,可惜市场上没有新书买了,只能从淘宝上买高价书 https://book.douban.com/subject/26761413/

原文发布于微信公众号 - 馔玉阁(hejian_zyg)

原文发表时间:2018-09-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏云计算D1net

面向能源效率的云计算

如今,云计算仍然是人们最为关注的技术趋势之一。企业和个人都体会到了实现云计算的好处,包括操作方便和节省成本,因此他们越来越多地选择云服务保持竞争力。 云计算在许...

3587
来自专栏编程一生

漫画:大公司都在重复造轮子吗?

1724
来自专栏云计算D1net

成功部署云计算的关键10个技巧

对于一些组织来说,云计算的使用已经开始,而无论他们知道与否,希望成功部署云计算,制定一个计划是有所帮助的。 Consultancy Cloud Technolo...

2988
来自专栏平凡文摘

十个老大难的程序员问题

1102
来自专栏云计算D1net

你迁移到了云,然后网络瘫痪了...然后呢?

或早或晚,大规模连接故障总有一天会降临到我们身上。在这种情况下,您所在的企业是否有能力继续保持运作,抑或是只能在互联网服务中断时让每位员工提前下班? ? 也许...

2948
来自专栏海天一树

云技术简介

一、概念 ? “云计算”概念由Google提出,一如其名,这是一个美丽的网络应用模式。云计算是是分布式处理(Distributed Computing)、并...

63310
来自专栏依乐祝

白话架构设计为你阐述什么是架构设计,架构设计的三大原则是什么

前面两篇文章给大家介绍了我们实战的CMS系统的数据库设计,源码也已经上传到服务器上了。今天我们就好聊聊架构设计,在开始之前先给大家分享一下这几天我一直在听的《从...

1323
来自专栏云计算D1net

IBM投资数十亿美元 押注BlueMix PaaS云

IBM认为,开放SoftLayer云平台即服务(PaaS)的中间件堆栈的是一个保险的赌注,一步只能赢不能输的棋。因此,蓝色巨人将数十亿美元摆在台上。 ? ...

2745
来自专栏安恒信息

手机重力感应可泄露用户身份信息

研究人员发现,智能手机和平板电脑里的加速计只要有一丝不同之处就可以创造出独一无二的重力感应“指纹”,这种指纹可以当成是一个用户的身份,在这个身...

3347
来自专栏DevOps时代的专栏

业务安全与 DevSecOps 的最佳实践

2532

扫码关注云+社区