顾宇:成功的微服务应该是什么样 — 组织篇

顾宇:成功的微服务应该是什么样 — 组织篇

本文内容源于我在 2018 年北京 DevOps 国际峰会上的分享 “成功的微服务应该是什么样”。PPT 可以在[这里下载] (https://pan.baidu.com/s/1jSleh_UxXpqI_oXOwcqf1w)

前言


4 月在深圳的 GOPS 大会上我分享了“落地微服务的难点和如何高效落地微服务”,这是我 2017 年 4 月份开始做的项目总结,后来发表到了自己的博客和” ThoughtWorks 洞见” 上。

本次介绍的案例来自于我 2013 年刚加入 ThoughtWorks 所服务的客户。

当时我们在做遗留 Java 系统的改造,把这个 Java 应用的一部分从系统内部调用的方式从 ESB 改成用 Sinatra (Ruby 的一个 Restful API 框架) 做的 HTTP 外部调用。

当时我还不知道我们做的东西就是微服务,只是觉得通过自动化持续交付的方式把应用进行了解耦。降低了系统的复杂性,减少了代码,同时减少了生产环境的故障和开发过程中依赖导致的进度阻塞。

当时这个项目前后进行了 8 个月。除了满足单块系统的解耦,我们还增添了功能并做了一些维护性的日常工作。

当时我们并没有一个独立的 Ops 团队,所有的运维相关工作都是团队内自己完成的。

在 2014 年的时候我们采用 Docker 进行部署,当时是个很新颖的东西。由于在互联网上找不到相关的材料,我们就自己写了一些编排工具,用来把 Docker 部署到生产环境中…… 当然,当时也不清楚什么是 DevOps。

2014 年第二季度我们开始做契约测试,是消费者端的契约测试,是客户自研的工具 Pact,不是我们开发的,并提出了契约测试理论。

我们会把串行的集成变成一个准并行的集成,你会在大大小小微服务的书和相关实践中都能看到这个工具,也是他们定义了什么叫契约测试。

到了2014年底我们把整个事情全部完成了之后,才知道什么是微服务,也知道什么是 DevOps。后来,这个微服务项目就成为了 ThoughtWorks 对外宣传的微服务案例中的其中一个。

2014 年11月份我离开了这个团队,开始把在这个团队上的经验推广给不同的客户,才发现我们自己的技术实践已经很前沿了,后来才慢慢才逐渐了解了 DevOps 和微服务的概念。

而在这段时间里,这个客户也开始复制我们之前的成功经验,开始进行了全面的微服务化改造。《Building Microservice》的作者 Sam Newman 也把我们的成功经验写进了这本书。

到了 2016 年年中的时候,他说我们要做SRE,不要做DevOps。

他们所能想到的功能越来越少,他们做的是把企业内所有的IT系统进行整合,这个时候带来最大的问题就是系统集成的问题,我们后面也是用微服务的案例进行解决的。

到2017年的时候,他们增长速度非常快,从一个国家的 NO.1 变成南半球的NO.1,他们做了一个 Panda Team,把所有的资源拿到一起做成一个平台,然后我们在平台上可以对接不同地区和国家的同一类的产品,因为他们已经开始做并购了,可以对接不推国家、地区的同类型的产品。

我们知道微服务带来最大的好处是同样的平台对接异构的语言、异构的产品,这样我们可以很快的把它结合到一起帮我们发展。

2017 年,我重新回到这个客户的项目上工作,发现了这个刚好是我离开这个团队 2 年的时间,能够使得我从一个新的角度来比较微服务改造后的效果。

本文以该客户为案例,从四个方面讨论一个成功的微服务应该是什么样的:

  1. 什么样的微服务改造是成功的?

  2. 成功落地的微服务的人员组织是什么样的?

  3. 成功落地的微服务有哪些技术特征?

  4. 在实践和落地的过程中的关键经验
这篇文章里,我们先谈前两个问题。下篇文章里,我们谈后两个问题。

什么样的微服务改造是成功的?


网上的微服务传说太多,而亲自经历实践过的其实没几个,而且我们所接触到的案例大部分都是国外的。

我们只能看到各种各样的新工具,却很难知道他们是如何使用这些工具的。

于是,国内的大部分微服务实践看起来就是买家秀和卖家秀的区别。

顾宇:成功的微服务应该是什么样 — 组织篇

我们看到的往往是一个结果,却很难看到一个过程。

我们大多数经验来自于“成功的微服务是什么样?”,但很少涉及到“失败的微服务是什么样?”、“如何避免失败?”以及“失败了怎么办?”的问题。

因此,在这篇文章的开头,我们先定义一下什么样的微服务改造是成功的。

但是这不是说你的微服务,按照本文所介绍的几点去做就是成功的,而是说如果你去做微服务如果成功了,它应该和这些点所带来的效果差不多。

毕竟每个系统都有自己特定的领域问题和技术环境,实施的路径大不相同。

我们做微服务的主要诉求就是希望系统规模在增长的同时,管理成本降低。

这个管理成本包括两个方面:

  1. 人员的管理成本降低。

  2. 技术的管理成本降低。

特征一:人员的管理成本降低


当业务扩张的时候,需要开发并维护更多的需求。因此,在时间和质量不变的情况下,只能通过增加资源来满足需求。

但是,边际收益递减规律告诉我们:在其它条件不变的情况下,任何单一要素的投入所带来的收益是会递减的。

因此,需要增加额外的要素来获得增长和回报率,特别是调整组织的结构,降低来提升容量。

而在大型应用系统开发面前,我们投入的只有人,因此我们可以看到:

大型的项目随着人员的增加,它所带来的管理成本也会增加,直到增加人员不产生收益为止。这是我们在大型应用系统,特别是互联网应用上看到的问题。

然而,微服务的出现。改变了应用架构,更确切的说,是改变了组织形式,降低了管理成本。

以前粗放式的通过把复杂问题分解,并且通过人海战术消灭需求的模式不可持续。

原因一是问题随着需求的爆炸,包含外部需求和内部需求,功能性需求和非功能性需求,应用系统会变得更加复杂。

原因二就是能够降低复杂度的这些方法论的工程师的获得成本,包括招聘和培训的成本都非常高。

而微服务架构能够大幅度的降低应用系统的复杂度,并通过敏捷团队的快速复制,降低管理的难度。

因此,我们可以看到团队自我改进、人员能力提升,你可以有更少的管理层,在 2018 年北京 DevOpsDays 上华为 DevCloud 团队的案例分享也证明了这一点。

如果你的微服务做得最够好,根据康威定律,你的架构会和你的组织结构是一致的。

如果你有了一个自治且自我成长的团队后,通过把最佳实践变成制度和规则充分授权,而不需要更多的请示和汇报,你的组织结构不会有一个很厚很高的层次以及对应的回报关系。

而是扁平而松散的结构,每个团队按照同样的制度独立完成任务,不会出现组织流程上的阻塞。但能够达到同样的质量效率。

另外一点我们通过 DevOps 实践提升了反馈速度,并通过自动化的方式减少了人工干预。DevOps 的文化之一就是做自动化,以前不会自动化会想办法自动化,你想到开源软件满足不了的团队会想办法做。

而这样的文化最后最后会形成一个开发软件的文化和制度,这个制度可以在组织内复制并且推广延续。减少了更多的人工管理成本。

特征二:技术的管理成本降低


另一个微服务成功的特征就是技术管理成本的降低,这个有两个方面的成本。一方面是开发成本,另一方面是维护成本。

首先,你会得到一个清晰的架构。而我们现在大部分系统的应用架构是混乱的,里面存在了太多的“暗知识”。

“暗知识”就是需要通过跟踪代码,跟踪日志,实际运行监测的到的不确定的知识。现在我们去画一个系统的架构分层图,你画出来的图跟实际系统对应程度并不是很高,而且很混乱,往往出现的情况是部署架构和逻辑架构不一致。

其次,你会得到更快、更稳定的发布反馈。这实际上是 DevOps 带来的好处。使得你可以更频繁的去部署应用,在部署和更新的时候应用更稳定,存在更少的宕机时间。

在这个过程中会发现有很多的自动化,然后随着微服务做得越来越多。最大的问题就是面对微服务的管理。实际上,在外部需求功能不变的情况下,微服务的大小决定了微服务的数量。

同样也决定了团队的数量和管理的复杂度。所以,微服务的大小不是问题,问题是你有多少人员能够支撑这样的复杂度。

当你发现需要管理这么多微服务你需要额外的自动化,你的团队里就会自驱形成自动化的意识。

我们知道如果你的开发任务量在增加的时候,我们在不增加资金投入,不增加开发时间的情况下的情况下能做到最好的方式就是减少满足你最终交付时间点的需求。

但是到了微服务的环境下,你不需要再有这样的到期时间点交付的任务,你发现不需要增加人同样可以解决这些问题;

另外一点是更快的业务相响应速度,我的业务平均是3个月,现在我们把它压缩到1个月。我们当时做的第一个服务,我们只能衡量那个团队,我们现在有不同大小的团队,小的需求可能就两天,大的需求也可能是三个月,但是带来的效果不一样。

成功微服务落地的组织特征


接下来我们说一下成功微服务落地的组织结构,从组织结构的角度看它是什么样的。从2014年底我离开这个客户的项目,到2017年初我再次回到这个客户。中间的三年我并没有在这个客户的项目上工作,所以我能看到采用微服务之前之后的变化。

多个微服务团队


顾宇:成功的微服务应该是什么样 — 组织篇

从宏观上来看,一个企业为了满足各个方面的信息化需求,一定会有很多不同的应用系统。比如财务、人员管理、产品管理、工作流程等。等发展到了一定阶段一定会需要通过技术手段将不同的系统实现数据共享。

我们会采用系统集成技术来集成不同的系统,把所有的系统都整合到一起。这里就涉及到了两个问题:

一个是“Single source of truth”,也就是单一事实来源。我们希望在多系统集成的情况下,某一种数据,例如客户信息、价格,等都有单一的事实来源。否则在不同子系统之间出现数据不一致的情况。

另外一个就是之前提到的 Design For Failure,在业务正在运行的期间,应用系统的改造不能使当前业务崩溃。

因此,我们的任何一个决策都要保持现有业务运行的稳定,一方面是人员组织,另一方面是系统架构。

图里三个颜色表示三个业务系统,三个业务系统最开始只有 Team A 是做微服务的,它只做一个应用的一小部分,比如 APP-1 的其中一个微服务。而其它的团队还在维护各自的单体应用。

他们把所有应用业务切分成不同的微服务并集成,花了三到五年的时间。他们的团队所面对的维护工作量看起更大的了,因为他们需要关注的点更多了,但是它的团队没有增加反而减少了。

某些团队被拆散,和其他的团队整合。或者开发了新的业务部门。

之前在这个公司里面一共有120个开发人员,包括我们这边和客户那边的,到现在只剩80个人了。过去四年到五年有将近 30% 的人离职去搞比特币创业了,当然还有人补充进来。

然而他们的系统并没有因为要维护这么多模块垮掉,而是这么多人已经足够多了。一开始我们是有运维团队的,第一个微服务团队和这个团队是一起工作的。

到后面它又不再去到每一个团队工作了,而是形成一个运维模式,这个团队就是前面说的熊猫团队(PandA,Platform AND Architecture 平台和架构团队)。

多大的微服务团队?


多大的微服务团队是合适的?下面是我们微服务团队的照片,亚马逊提出两个披萨饼的团队。我们也采用过两个必胜客披萨的团队,但我们发现两个披萨的团队不符合实际。是因为你所碰到微服务的粒度是不一样大的。

因此,我们组建了“两个桌子间”的团队,如下图所示

顾宇:成功的微服务应该是什么样 — 组织篇

两个披萨团队不太科学,你所碰到的问题的力度是不一样大的。这是两个桌子,中间的走廊是看板,我们做的是两个桌子之间能快速交流的团队。

如果你坐在桌子的两边,你看到对方的脸看不到显示器,这样会形成人为的阻碍,但是人为阻碍在心理上也是有阻碍的,认为不是你的团队。

所以我们把中间空余的地方变成公共区域,而且我们面对的是看板,有问题及时沟通,不需要找会议室。

我们要做很容易相互交流的团队,这个团队我们最小的微服务团队3个人,最大的微服务团队20个人,20个人里面有一个是什么都不干的人,他是做UX页面设计的。因为在我们的应用里面,我们的 UX 是整个微服务团队公用的。

当然,你可以拥有“两辆轿车”的团队或者“一个大圆桌团队:团队所有人出去吃饭刚好可以坐下两辆轿车,或者可以坐下一个包厢的圆桌。主要还是为了降低团队沟通和决策的成本。

我们决定微服务团队的大小有三个原则:

  1. 团队的成员相互之间可以随时沟通:两个桌子之间的空地就是我们的会议室,有事随时沟通,同时也不会被隔壁桌子打扰。

  2. 不增加额外的管理成本:无需增加管理团队来管理微服务团队,微服务团队的工作责任边界完全自治。

  3. 不需要加班即可完成计划的任务:表明当前的工作量对于团队成员来说是合适的。

如果大于这个尺寸,证明你的微服务团队过大,需要进一步拆分。遇之相对应的是你的微服务的开发维护工作量过大,也需要进一步拆分。团队的最好的大小是和微服务的工作量是一致的。

如果小于这个尺寸,会因为微服务拆分的过小反而增加管理成本。你会发现有很多的团队需要协调,不得不增加协调人员来协调各微服务之间的工作,这就是额外的微服务团队管理成本。

从工作量的角度来看,每天的工作量要达到75%以上的时间利用率。也就是说,如果是“朝九晚六”(9:00-18:00)的工作方式,除去午休的一个小时。全天有8个小时的工作时间,起码要保证至少 6 个小时是在微服务的工作上。

可以有2个小时左右的时间处理私人和组织的事务。如果微服务团队内部的工作时间小于这个比例,那么就证明组织之间存在额外的沟通成本,这些沟通就是需要被拆分出来的依赖,或者被下放的责任。

微服务团队的组织


顾宇:成功的微服务应该是什么样 — 组织篇

作为一个微服务团队组织是什么样的呢?我们的微服务团队是一个全功能的敏捷 DevOps 团队。这样的一个团队除了满足以上的团队大小外,还需要满足“全功能”和“DevOps”两个条件。

首先,我们是一个全功能的团队,也就意味着我们的团队可以处理整个团队端到端的所有任务。

其次,我们是一个 DevOps 团队,意味着我们团队自己具备部署和发布的能力,而无需平台组或者运维团队的支持。

然后,除了一般的敏捷团队,我们还有一个微服务的负责人。这样的团队我们又叫项目经理(PM),又叫MS-MASTER,它是一个复合的角色,不光是经理还是架构师是技术角色。帮我们隔离外部的干扰,例如会议、沟通等……以确保团队可以独立的工作。

最重要的是,我们需要有一个业务分析师,我们叫BA。而发现需要这么一个角色的过程是经历过惨痛教训的:如果你的团队没有人十分熟悉业务流程和组织结构,划分出来的微服务就会和别的团队有重复。

这就违反了单一事实来源的原则,而提前的分析可以避免这一点。而团队内部大部分是开发工程师,两个到14个不等。然后是QA,我们的QA 不仅仅是做测试的,我们的 QA 还要理解业务,而 QA 是做全流程的质量保障。

我们的测试流程是开发工程师写的自动化测试。

注意,由于微服务的抛弃成本很低,我们并没有很高的单元测试覆盖率,但是我们要确保对应的端到端测试和集成测试都是大部分被覆盖的。

另外我们需要运维工程师来帮我们设计持续部署和在线微服务的监控。

树立起微服务的交付规范


树立起微服务的规范,这一点非常重要。这也是微服务成功扩张的基石。

当我们刚开始做微服务的时候,不知道哪一条微服务路径是更好的。尽管有各种各样的方法论,但在实际过程中还会出现这样那样的问题。

所以我们先做一到两个试点,然后去总结出一个模式出来,但是一定要注意不要把它形成一个公共代码库,否则又变成了新的聚合。

所以要在每个代码库中做到一定的质量规范,以确保每一个微服务上线质量都是有所保障的。

另外一点要创建一个交付流程,把代码的审查到最后上生产环境。要形成一个交付流程的规范,这个最好是自动化的,团队每一个人都最好遵守这个规范。我们是通过“流水线即代码”技术,把交付规范变成了一系列自动化的手段。

还有就是团队自治活动,一开始我们做微服务的时候很容易找不到北,因为你并不是很清楚哪些应该是独立的。

因此我们团队决定,用一句话来讲清楚你现在做的这个微服务是什么?如果你一句话没有把微服务讲清楚,那你这个微服务就已经太复杂了。

通过这样的方式,大家在讨论中学习,我们通过自治的活动去帮助大家提升微服务的认识,在做微服务的过程中做一些团队的改进。

微服务团队的工作节奏


顾宇:成功的微服务应该是什么样 — 组织篇
大家可以看到图中绿的就是我说的MS—MASTER,我们每个产品负责人和下面微服务的MS-MASTER之间是这个结构,但是每个结构之间是自组织的结构,然后我们会每隔一段时间更换每个人的职责,让你能站在别人的角度思考问题。

比如我之前做开发的,我现在做测试,我之前做测试,我做一段DevOps自动化的工作。这样可以保证团队每一个人理解其他人做这个事情的观点。

当然刚开始的时候,执行这个节奏很慢。但这个学习过程可以帮助团队每个人都了解所有的工作,不存在任何形式不透明的知识。

一个有效的方法是结对编程,当你碰到项目时间截止、预算截止又加不了人的时候,能够砍掉第一个敏捷实践就是结对编程。

但是把眼光放长远看,你会发现结对编程是利用的是短板原理。在你的团队你跟别人面对面工作,如果你一个人工作,你的工作能力不足你是很难感受到的。而和别人一结对,你的工作能力不足你就有了很清晰的认识。

这可以让团队成员向高水平的成员学习,不断提高团队的短板。

而不采用结对编程的团队一般就是末位淘汰制。这个很容易理解,但实际上这种制度只会浪费大家的时间。

因为在这样的组织里遵循马太效应,强者愈强,弱者愈弱,这不利于团队的发展。特别是需要复制的团队。

另外需要说明的一点就是结对编程是非常累的,因为你在写代码的时候,始终有一个人盯着你,你没有时间开小差,你所有时间都在思考、设计,如果你没有这样做的话就是对结对伙伴的不尊重,所以从另外一种角度来看,结对编程实际上是一种自我监督制度,让对方监督来克服自己的惰性。我们工作的高效率就是这么形成的。

顾宇:成功的微服务应该是什么样 — 组织篇

另外还要做微服务团队之间的交换结对(Switch Pair)。我们经常会出现一个问题,那就是我们团队有些人水平高,有些人水平低。水平高的人开发一些功能然后离职了,留下一个坑。

但是这个风险往往是我们忽视的,我们做交接的时候往往交出去没有接起来,然后又变成另外一个坑。而结对编程是避免坑的有效的手段,但是一定要注意定期交换结对的伙伴。为什么呢?

持续交付里面有一个很重要的原则叫做尽早并频繁的做一些让你感到痛苦的事情。如果一个团队成员离职让你很痛苦,做交接很痛苦,那每一天做一次交接。

这就是结对编程和交换结对伙伴所做的事,因为每一次你做交接的时候都把这个练了一遍。所以它的交接压力非常小,但是如果做了半年的系统离职了,你要交接半年的系统压力是非常大的。

所以结对编程明显一个缺点就是费人费钱。所以,结对编程也是一种 Design for Failure 的设计。

团队交流除了刚才提到的,我们还要定期做回顾会议。回顾会议非常重要,团队要学会自我改进。特别是微服务团队刚组建的时候,一定要养成复盘的习惯,否则很多问题就会积累,拖累整个微服务团队的工作节奏。

此外,你需要给团队充分的授权,如果你不信任你的团队,你的团队也会用不信任的方法对待你。这样子大家就会制造额外的制度来对付对方而不是和对方合作了。

演进的组织


在 Netflix 的微服务经验中,Netflix 的工程师 R. Meshenberg 提出。微服务的落地需要个方面的配合和统一。

这就意味着组织结构需要变化,这些变化的落地是困难的,这不是技术能够解决的问题。而且,你需要你的组织能够不断自我演化能够面对各种挑战。而组织结构的变化是往往容易被忽视的一环。

成功的微服务的组织都是可以自我演进的,它会带来技术的发展。下一篇文章我们就谈谈成功的微服务落地技术上有哪些特征。

猜你喜欢

转载自blog.51cto.com/15127503/2657629