写点什么

“四个维度” 讲明白什么是微服务!

用户头像
攀鱼飞岩
关注
发布于: 2020 年 05 月 16 日
“四个维度” 讲明白什么是微服务!

微服系列文章


第 1 篇: “四个维度” 讲明白什么是微服务!

第 2 篇: 微服务涉及的技术生态有哪些?

第 3 篇: 微服务-为什么要有服务发现与注册?

第 4 篇: 万字长文,助你吃透Eureka服务发现机制!


一、从康威定律说起


关于微服务的理论思想,我们可以从一个著名的定律说起---康威定律,康威定律是一个叫梅尔文·康威的程序员,他在 1968 年发布了一篇文章,文中论述了设计系统的组织与系统本身的关系,并列举了各个不同行业的真实案例,最后得出了结论:“oganizationrs which design systems (in the broad sense used here) are constrained to produce designs which are copies of the communication structures of these organizations”。



大致的意思就是系统设计(产品结构)等同组织形式,每个设计系统的组织,其产生的设计等同于组织之间的沟通结构,简单一点理解就是:系统设计受限于设计系统的组织架构形式,用大白话来说就是:有什么样的组织架构就会设计出什么样的系统架构。


 当然,这个结论在当时并没有上升到定律的高度,直到《人月神话》、《架构之美》这两本书畅销书都引用了其观点并“大肆吹捧”,康威定律才慢慢传播开,最终成为了与摩尔定律齐名的软件工程定律。


虽然时间过去了 50 多年,但这些结论依然历旧弥新。当一个组织增长到一定的规模,组织之间的沟通、协调就会出现低效与冗余,为应对内外部环境,组织就要进行适当的变革。在互联网公司这种变革的成果,就是诞生了一个个独立作战的小团队,无论是腾讯的“大公司小团队理念”,还是亚马逊贝佐斯提出的“二个披萨饼原则”,(一个团队的规模最多只能用两个披萨饼喂饱)都印证了这点。


同样,随着组织的变革也影响着系统架构的设计,因为系统架构一个十分重要的职责就是:“解决团队分工协助问题,系统架构体现了组织的沟通与协助方式。这正是康威定律所说的“系统设计(产品结构)等同组织形式”。


二、单体架构与微服务


有了康威定律的理论基础,从组织的维度我们可以认为微服务的本质是:

“将一个个业务功能拆分出来,并由一个微型团队来开发、构建、运维,团队与团队之间通过定义清晰的边界进行沟通”。

下面将通过两张图,更细致的理解微服务的概念:

单体架构


先看第一张图,这是典型的单体架构风格,由人数众多的大团队在一个单体里面进行协助开发,在业务复杂程度低,团队规模不大时,这种方式团队能聚焦核心业务,快速响应。但随着业务的不断发展,团队人数的不断扩张,系统的规模与复杂性会成指数级增长,整个研发过程就会面临着 3 个问题:


  • 人数众多,团队之间沟通协调困难,信息不一致(可以参考项目管理中的沟通途径计算)

  • 项目工程庞杂,各类库与组件的依赖关系错综复杂,大量重复性代码,项目推进举步维艰;

  • 代码管理、版本管理变得困难,构建编译时间变长,运维部署困难,系统启动时间变长;


这些问题,直接影响着团队的交付效率,影响着系统的可用性、可扩展、可伸缩等。

而面对这些问题的解决之道就是微服务,我们再看第二张图微服务的架构风格。


微服务架构


我觉得有必要先个微服务下一个定义,这里我引用软件领域泰斗级人物“马丁·福勒”他对微服务的定义。对于马丁·福勒,你可能没听说过他,但是作为一个程序员你不可能不知道他的作品《重构》,就在今年 5 月份《重构》出了第二版,更不可能不知道由他与其他 15 为软件泰斗共同创造的“敏捷软件宣言”。

微服务定义:


“微服务架构风格是以一组小服务来开发单个应用程序的方法,每一个服务运行在自己独立的进程中并使用轻量的方法通信,通常是一个 HTTP API 接口。这些服务围绕相关业务范围构建并且由全自动化部署机器独立部署。这些服务只需要最低限度的管理,可以用不同的编程语言去编写并且使用不同的数据存储技术”


基于微服务的定义我们可以总结出微服务的一些特征:


微服务特征


1)服务小而美:微服务是以一组小的服务组成,一个重要的特点就是小,至于具体多小,有一些不同的声音,这个不能一概而论,要看具体情况。我们需要使用领域建模的方法来定义服务的粒度,领域建模的知识我会在后面的文章中详细的介绍。


2)服务独立自治:独立自制是微服务一个显著的特征,主要体系在几个方面,第一,微服务由独立的团队来开发;第二、微服务可以使用不同的平台与语音;第三,独立于具体项目已产品的形式存在; 第四,微服务运行在独立的进程中,可独立部署;


3)服务松散耦合:微服务将业务划分清晰的边界,再封装到一个独立的服务中,符合软件设计的单一职责与最少依赖原则,微服务将系统的抽象程度提到了更高的层次,将系统对代码或组件的依赖转换为对接口,对服务的依赖;


4)服务互联互通:微服务强调小,轻量,服务通过相互连通组成复杂的业务功能,服务通信方式可根据具体场景,选择基于 HTTP Restfull 的轻量级协议,或是效率高的 RPC 协议,甚至可以选择基于消息队列的异步调用方式等;


5)非中心化治理:去中心化是微服务的又一个重要特征,去中心包括数据非中心化,管理去非中心化,微服务采用非集中化的数据存储,各个服务使用自己独立的数据存储,微服务也没有一个集中的服务管理器。


6)演进式设计:演进式架构已增量的、非破坏的变更作为第一原则,演进式设计也是微服务所提倡的。例如,要对一个巨型单体应用进行微服务转型,肯定不是把这个大的单体应用直接干掉不要,建一个新的微服务平台出来,而是要以增量的、非破坏的方式把某项业务一步步抽离形成新的服务。


三、 微服务带来的问题与挑战


架构设计是一门权衡、取舍的艺术,没有银弹,更没有十全十美的架构,微服务架构为我们带来了如:“可扩展性”、“容错性”、“灵活性”等诸多优点。我们收获这些好处的同时,也一定会带来某些弊端与挑战,这些挑战可以从四个方面来说:

1)分布式带来的通信复杂性与不确定性

对于单体应用,要完一个业务操作,我们通过本地方法调用,这些调用都在同一个进程内完成。进程内地的方法调用或类库调用,由平台语言本身来提供,比如 JVM 通过线程栈,能提供可靠、确定的调用机制,并且时间延长几乎可以忽略不计。而在分布式环境中,要完成一个业务操作,服务之间需要跨进程,跨网络进行相互调用,我们称之为远程方法调用,这两种调用方式有着这本质的区别,进程内调用习以为常的事情,在远程调用时就成了必须要面对的问题,这些问题包括:


  • 服务的调用方(消费者)怎样找到被调用(提供者)方?

  • 如果某个依赖服务挂了(进程死了、网络异常,服务器宕机)怎么办?

  • 服务接口需要暴露在网络上,接口的安全怎么保证?

  • 业务代码分散在各个进程中,那统一处理的代码怎么办(比如异常、日志)?单体中我们有 AOP 编程

  • 如果服务调用链层级太深,时间延迟怎么办?

  • 对于一个业务 bug、或线上问题涉及多个服务调用,怎么快速定位、排查问题?

2)非中心化带来的数据不一致性

微服务的一个重要特征是数据的非中心化存储,各个服务使用自己独立的数据库。这就带来了一个严峻的挑战,就是数据库的一致性问题。在单体系统中,使用单一数据库,程序员只需要关心最的核心业务问题,我们用数据库的 ACID 特性,就能轻易的保证数据的一致性,在代码框架的支持下只需要一个标记就能搞定一个事务处理。但是在分布式数据库中要做到这些,就是个非常棘手的问题,需要我们做很多额外的工作,同样对于像报表查询,统计业务从前一个 sql 语句能搞定的事情,数据非中心存储后就会非常麻烦。

3)众多服务带来构建、配置、测试、部署的困难性

软件系统最终是要经过编译、测试、部署到多个环境进行最终验证,最后再依次部署到生产环境,同时还要考虑生产环境的回滚策略,这些流程在单体应用中只是规模,体积比较大,但毕竟数量是少数的。我们需要可能只是一些细心与耐心。但系统被拆分成诸多微服务之后,假设有 20 个,同样的事情,重复的劳动我们需要做 20 次并且保存每次都不能出错,量变引起质变,当服务超过一定数量,我们要面对的不仅仅是重复劳动的问题。

4)业务解耦带来的微服务拆分困难性

对于单体应用,如果我们的业务设计做的不好,模块化划分不到位,后果可能还没有那么严重,毕竟所有的数据都在一个数据库中,所有的代码也都可以进程内调用,大不了我就加一层来解决,实在不行就加两层(玩笑话),但是,我们想象一下,如果微服务在业务设计时没有规划好,把不该放一起的放到一起,该放一起的强行拆开,整个微服务就成了一团乱麻,远程调用的开销,服务的治理会是一场灾难。


微服务强调的是基于业务功能构建,业务功能之间要松散耦合,有明确边界。然后,对于一个复杂业务系统,在设计早期要做的这点并非易事。


根据墨菲定律--“凡是可能出错的那它一定会出错”选择微服务就一定会遇到上述我说的这些问题。


四、微服务的适应性


看到微服务这么多困难与挑战,是不是感到迷茫与沮丧,确实,“没有银弹”,“没有神丹妙药”,微服务不一定适合所有公司、所有项目。那么我们应该怎样权衡微服务与单体架构呢?这里就涉及到一个经济学中边际成本与收益的问题。我又得请出我们的大神“马丁.福勒”了,大神在一篇“微服务的适用性”文章中用一张图清晰的说明了微服务的适用场景。我们先来看看这张图:

​微服务 系统复杂性与生产力关系


图上的 X 轴表示系统复杂性,Y 轴表示生产力,两条曲线表示微服务与单体应用,在两个维度上的表现。当系统复杂性比较小的时候(X 轴靠近左边),单体应用的生产力要高于微服务,其实这很好理解,因为微服务要考虑,自动化部署、服务监控、故障处理、数据一致性等诸多问题,而这些对于业务系统本身来说都是额外的工作。当软件复杂性不高,团队规模不大时,这些工作会占据整个研发工作的很大比重。


当系统复杂性变大时,微服务额外部分的工作占整个研发工作的比重变小,而微服务带来的收益越来越大,这时整个研发的生产力并没有像单体架构那样直线下降,所以微服务能够在系统复杂性增加时,还能持续的保持良好的生产力。


在尝试微服务转型之前,我们需要结合公司的实际情况,考虑微服务带来的挑战与收益,再判断我们是否真的需要微服务。“马丁.福勒”的建议是:“ 除非系统过于复杂而无法作为一个整体进行管理,否则甚至不要考虑使用微服务,大多数的应用系统应该使用单体架构,只是要注意在单体内做好模块化,而不是直接使用微服务”


微服务架构充满刺激与挑战,但好消息是,对于大多数项目与团队,并不需要从零开始,我们只需“站在巨人的肩膀上”,领会他们的设计精髓、用好他们的成果即可。下面的文章我们将重点介绍微服务架构的具体技术方案与通用实践。


微服系列文章


第 1 篇: “四个维度” 讲明白什么是微服务!

第 2 篇: 微服务涉及的技术生态有哪些?

第 3 篇: 微服务-为什么要有服务发现与注册?

第 4 篇: 万字长文,助你吃透Eureka服务发现机制!


发布于: 2020 年 05 月 16 日阅读数: 5573
用户头像

攀鱼飞岩

关注

任何一步都不会决定成功,但可以决定失败! 2017.10.19 加入

记录技术,项目,管理,读书,挣钱,养娃等点点滴滴可以记录的事情。

评论 (6 条评论)

发布
用户头像
错字连篇累牍
2020 年 05 月 26 日 09:26
回复
用户头像
感谢分享原创内容,InfoQ官网推荐这篇。
2020 年 05 月 18 日 15:16
回复
哈哈~~ 主编认可是我前进最大的动力啊.....继续加油~~
2020 年 05 月 18 日 16:17
回复
啊,是小编不是主编啦。期待更多好作品。
2020 年 05 月 18 日 23:20
回复
用户头像
赞一个,学习了~
2020 年 05 月 18 日 10:54
回复
该评论已删除
2020 年 05 月 18 日 16:16
回复
该评论已删除
2020 年 05 月 18 日 16:22
回复
刚开始在info平台分享一些粗浅的想法,发现平台真是藏龙卧虎,请多多指教~~
2020 年 05 月 18 日 16:24
回复
查看更多回复
没有更多了
“四个维度” 讲明白什么是微服务!