04 _ 微服务时代:SOA的革命者 你好,我是周志明。这一讲,我继续来带你探索软件架构中的微服务时代。

其实“微服务”这个词儿,Peter Rodgers博士在2005年的云计算博览会(Web Services Edge 2005)上,就已经提出和使用了。当时的说法是“Micro-Web-Service”,指的是一种专注于单一职责的、与语言无关的、细粒度的Web服务(Granular Web Services)。

“微服务”这个词,并不是Peter Rodgers直接凭空创造出来的概念。最开始的微服务,可以说是在SOA发展的同时被催生出来的产物,就像是EJB在推广的过程中,催生出了Spring和Hibernate框架那样。这一阶段的微服务,是作为SOA的一种轻量化的补救方案而被提出来的。

到今天为止,在英文版的维基百科上,人们仍然是把微服务定义成了SOA的一个变种。所以,微服务在诞生和最初的发展阶段,跟SOA、Web Service这些概念有所牵扯,也是完全可以理解的。 What is microservices- Microservices is a software development technique — a variant of the service-oriented architecture (SOA) structural style.- —— Wikipedia,Microservices

但我们现在再来看,维基百科对微服务的定义,其实已经有些过时了。至于为什么这样说,就是我在这一讲中要和你解释的了。

在微服务的概念被提出后将近10年的时间里面,它都没有受到太多人的追捧。毕竟,如果只是对现有的SOA架构的修修补补,确实难以唤起广大技术人员的更多激情。

不过,也是在这10年的时间里,微服务本身其实一直在思考、蜕变。

2012年,在波兰克拉科夫举行的“33rd Degree Conference”大会上,Thoughtworks首席咨询师James Lewis做了题为《Microservices - Java, the Unix Way》的主题演讲。其中,他提到了单一服务职责、康威定律、自动扩展、领域驱动设计等原则,却只字未提SOA,反而号召大家,应该重拾Unix的设计哲学(As Well Behaved Unix Services)。这一点跟我在上一讲中所说的“初心与自省”,可以说是一个意思。

微服务已经迫不及待地要脱离SOA的附庸,想要成为一种独立的架构风格,也许,它还将会是SOA的革命者,找到一条能被广大开发者普遍接受且愿意接受的、实现服务化系统的目标。

微服务真正崛起是在2014年。相信我们大多数程序员,也是从Martin Fowler和James Lewis合写的文章“Microservices: a definition of this new architectural term”里面,第一次了解到微服务的。这篇文章虽然不是最早提出“微服务”这个概念的,但却是真正丰富的、广为人知的和可操作的微服务指南。也就是说,这篇文章才是微服务的真正起源。

这篇文章定义了现代微服务的概念:微服务是一种通过多个小型服务的组合,来构建单个应用的架构风格,这些服务会围绕业务能力而非特定的技术标准来构建。各个服务可以采用不同的编程语言、不同的数据存储技术、运行在不同的进程之中。服务会采取轻量级的通讯机制和自动化的部署机制,来实现通讯与运维。

此外,在这篇论文中,作者还列举出了微服务的九个核心的业务与技术特征。接下来,我就一一解读为你解读下,希望你可以从中领悟到,微服务在团队、开发、运维等一系列研发过程中的核心思想。

第一,围绕业务能力构建(Organized around Business Capabilities)

这个核心技术特征,实际上再次强调了康威定律的重要性。它的意思是,有怎样的结构、规模和能力的团队,就会产生出对应结构、规模、能力的产品。这个结论不是某个团队、某个公司遇到的巧合,而是必然的演化结果。

如果本应该归属同一个产品内的功能,被划分在了不同的团队当中,那就必然会产生大量的跨团队沟通协作,而跨越团队边界,无论是在管理、沟通,还是在工作安排上,都会产生更高的成本。高效的团队,自然会针对这个情况进行改进,而当团队和产品磨合调节稳定了之后,就会拥有一致的结构。

第二,分散治理(Decentralized Governance)

这个技术特征,表达的是“谁家孩子谁来管”。微服务对应的开发团队,有着直接对服务运行质量负责的责任,也应该有着不受外界干预,掌控服务各个方面的权力,可以选择与其他服务异构的技术来实现自己的服务。

这一点在真正实践的时候,其实多少都会留点儿宽松的处理余地。因为大多数的公司都不会在某一个服务用Java,另一个用Python,下一个用Golang,而是通常都会统一主流语言,甚至会有统一的技术栈或专有的技术平台。

微服务不提倡也并不反对这种“统一”,它只负责提供和维护基础技术栈的团队,有被各方依赖的觉悟,要有“经常被凌晨3点的闹钟吵醒”的心理准备就好。

微服务更加强调的是,在确实有必要进行技术异构的时候,一个开发团队应该能有选择“不统一”的权利。比如说,我们不应该强迫用Node.js去开发报表页面;要做人工智能计算的时候,也可以选择用Python,等等。

第三,通过服务来实现独立自治的组件(Componentization via Services)

这里,Martin Fowler与James Lewis之所以强调要通过“服务”(Service)而不是“类库”(Library)来构建组件,是因为类库是在编译期静态链接到程序中的,会通过本地调用来提供功能,而服务是进程外组件,它是通过远程调用来提供功能的。在第2讲中,我们已经分析过,尽管远程服务有更高昂的调用成本,但这是为组件带来隔离与自治能力的必要代价。

第四,产品化思维(Products not Projects)

产品化思维的意思就是,我们要避免把软件研发看作是要去完成某种功能,而要把它当做是一种持续改进、提升的过程。比如,我们不应该把运维看作就是运维团队的事,把开发看作就是开发团队的事。

开发团队应该为软件产品的整个生命周期负责。开发者不仅应该知道软件是如何开发的,还应该知道它会如何运作、用户如何反馈,乃至售后支持工作是怎样进行的。这里服务的用户,不一定是最终用户,也可能是消费这个服务的另外一个服务。

以前在单体的架构模式下,程序的规模决定了我们无法让全部的开发人员,都关注到一个完整的产品,在组织中会有开发、运维、支持等细致分工的成员,他们只关注于自己的一块工作。但在微服务下,我们可以让团队中的每一位成员,都具有产品化思维。因为在“2 Pizza Teams”的团队规模下,每一个人都了解全过程是完全有可能实现的。

第五,数据去中心化(Decentralized Data Management)

微服务这种架构模式也明确地提倡,数据应该按领域来分散管理、更新、维护和存储。

在单体服务中,通常一个系统的各个功能模块会使用同一个数据库,虽然这种中心化的存储确实天生就更容易避免一致性的问题,但是,同一个数据实体在不同服务的视角里,它的抽象形态往往也是不同的。

比如,Bookstore应用中的书本,在销售领域中关注的是价格,在仓储领域中关注的是库存数量,在商品展示领域中关注的是书籍的介绍信息。如果是作为中心化的存储,那么这里所有的领域,都必须修改和映射到同一个实体之中,就会导致不同的服务之间,可能会互相产生影响,从而丧失了各自的独立性。

另外,尽管在分布式中,我们要想处理好一致性的问题也很困难,很多时候都没法使用传统的事务处理来保证不出现一致性问题。但是两害相权取其轻,一致性问题这些必要的代价是值得付出的。

第六,轻量级通讯机制(Smart Endpoints and Dumb Pipes)

这个弱管道(Dumb Pipes)机制,可以说几乎算是在直接指名道姓地反对ESB、BPM和SOAP等复杂的通讯机制。

ESB可以处理消息的编码加工、业务规则转换等;BPM可以集中编排企业的业务服务;SOAP有几十个WS-/*协议族在处理事务、一致性、认证授权等一系列工作。这些构筑在通讯管道上的功能,也许在某个系统中的确有一部分服务是需要的,但对于另外更多的服务来说是强加进来的负担。

如果服务需要上面的某一种功能或能力,那就应该在服务自己的Endpoint(端点)上解决,而不是在通讯管道上一揽子处理。

微服务提倡的是类似于经典Unix过滤器那样,简单直接的通讯方式。比如说,RESTful风格的通讯,在微服务中就是比较适合的。

第七,容错性设计(Design for Failure)

容错性设计,是指软件架构不再虚幻地追求服务永远稳定,而是接受服务总会出错的现实。

这个技术特征要求,在微服务的设计中,有自动的机制能够对其依赖的服务进行快速故障检测,在持续出错的时候进行隔离,在服务恢复的时候重新联通。所以“断路器”这类设施,对实际生产环境的微服务来说,并不是可选的外围组件,而是一个必须的支撑点。如果没有容错性的设计,系统很容易就会因为一两个服务的崩溃带来的雪崩效应而被淹没。

我想说的是,可靠系统完全可以由会出错的服务来组成,这是微服务最大的价值所在,也是咱们这门课的开篇导读标题中“The Fenix Project”的含义。

第八,演进式设计(Evolutionary Design)

容错性设计承认服务会出错,而演进式设计则是承认服务会被报废淘汰

一个良好设计的服务,应该是能够报废的,而不是期望得到长久的发展。如果一个系统中出现不可更改、无可替代的服务,这并不能说明这个服务有多么重要,反而是系统设计上脆弱的表现。微服务带来的独立、自治,也是在反对这种脆弱性。

第九,基础设施自动化(Infrastructure Automation)

基础设施自动化,如CI/CD的长足发展,大大降低了构建、发布、运维工作的复杂性。

由于微服务架构下,运维的服务数量比起单体架构来说,要有数量级的增长,所以使用微服务的团队,会更加依赖于基础设施的自动化。毕竟,人工是无法运维成百上千,乃至成千上万级别的服务的。

好,到这里,通过我的解读,你是不是已经大概理解了微服务核心的业务和技术特征了?以上9个特征,是一个合理的微服务系统展示出来的内、外在表现,它能够指导你该如何应用微服务架构,却不必作为一种强加于系统中的束缚来看待

Microservices: a definition of this new architectural term”一文中,对微服务特征的描写已经非常具体了,除定义了微服务是什么,还专门申明了微服务不是什么:微服务不是SOA的衍生品,应该明确地与SOA划清界线,不再贴上任何SOA的标签。

这样一来,微服务才算是一种真正丰满、独立、具体的架构风格,为它在未来的几年时间里,如同明星一般闪耀崛起于技术舞台奠定了坚实的基础。 Microservices and SOA- This common manifestation of SOA has led some microservice advocates to reject the SOA label entirely, although others consider microservices to be one form of SOA , perhaps service orientation done right. Either way, the fact that SOA means such different things means it’s valuable to have a term that more crisply defines this architectural style.- 由于与SOA具有一致的表现形式,这让微服务的支持者更加迫切地拒绝再被打上SOA的标签。一些人坚持认为微服务就是SOA的一种变体,尽管仅从面向服务这个角度来考虑,这个观点可以说也是正确的。但无论如何,从整体上看SOA与微服务都是两种不同的东西。也因此,使用一个别的名称,来简明地定义这种架构风格就显得非常有必要了。- —— Martin Fowler / James Lewis,Microservices

从上面我对微服务的定义和特征的解读当中,你还可以明显地感觉到,微服务追求的是更加自由的架构风格,它摒弃了SOA中几乎所有可以抛弃的约束和规定,提倡以“实践标准”代替“规范标准”。

可是,如果没有了统一的规范和约束,以前SOA解决的那些分布式服务的问题,不又都重新出现了吗?

没错,的确如此。服务的注册发现、跟踪治理、负载均衡、故障隔离、认证授权、伸缩扩展、传输通讯、事务处理等问题,在微服务中,都不再会有统一的解决方案。

即使我们只讨论Java范围内会使用到的微服务,那么光一个服务间通讯的问题,可以列入候选清单的解决方案就有很多很多。比如,RMI(Sun/Oracle)、Thrift(Facebook)、Dubbo(阿里巴巴)、gRPC(Google)、Motan2(新浪)、Finagle(Twitter)、brpc(百度)、Arvo(Hadoop)、JSON-RPC、REST,等等。

再来举个例子,光一个服务发现问题,我们可以选择的解决方案就有:Eureka(Netflix)、Consul(HashiCorp)、Nacos(阿里巴巴)、ZooKeeper(Apache)、etcd(CoreOS)、CoreDNS(CNCF),等等。

其他领域的情况也很类似。总之,完全就是“八仙过海,各显神通”的局面。

所以说,微服务所带来的自由是一把双刃开锋的宝剑。当软件架构者拿起这把宝剑的时候,它的一刃指向的是SOA定下的复杂技术标准,而在将选择的权力夺回的同一时刻,另外一刃也正朝向着自己映出冷冷的寒光。

小结

在微服务时代中,软件研发本身的复杂度应该说是有所降低,一个简单服务,并不见得就会同时面临分布式中所有的问题,也就没有必要背上SOA那百宝袋般沉重的技术包袱。微服务架构下,我们需要解决什么问题,就引入什么工具;团队熟悉什么技术,就使用什么框架。

此外,像Spring Cloud这样的胶水式的全家桶工具集,通过一致的接口、声明和配置,进一步屏蔽了源自于具体工具、框架的复杂性,降低了在不同工具、框架之间切换的成本。所以,作为一个普通的服务开发者,作为一个“螺丝钉”式的程序员,微服务架构对我们来说是很友善的。

可是,微服务对架构者来说却是满满的恶意,因为它对架构能力的要求可以说是史无前例。要知道,技术架构者的第一职责就是做决策权衡,有利有弊才需要决策,有取有舍才需要权衡。如果架构者本身的知识面不足以覆盖所需要决策的内容,不清楚其中的利弊,也就不可避免地会陷入选择困难症的困境之中。

总而言之,微服务时代充满着自由的气息,也充斥着迷茫的选择。软件架构不会止步于自由,微服务仍然不可能是架构探索的终点。如果有下一个时代,我希望信息系统能同时拥有微服务的自由权利,围绕业务能力构建自己的服务而不受技术规范管束,但同时又不必承担自行解决分布式问题的代价。管他什么利弊权衡!小孩子才做选择题,成年人全部都要!

一课一思

思考一下,你所负责的产品是不是基于微服务的?如果是,它符合微服务的9个特征吗?如果不是,你的产品适合微服务架构吗?你所在的企业、团队适合引入微服务吗?

欢迎在留言区分享你的答案。如果你觉得有收获,欢迎你把今天的内容分享给更多的朋友。

参考资料

https://learn.lianglianglee.com/%e4%b8%93%e6%a0%8f/%e5%91%a8%e5%bf%97%e6%98%8e%e7%9a%84%e6%9e%b6%e6%9e%84%e8%af%be/04%20_%20%e5%be%ae%e6%9c%8d%e5%8a%a1%e6%97%b6%e4%bb%a3%ef%bc%9aSOA%e7%9a%84%e9%9d%a9%e5%91%bd%e8%80%85.md