做到这7点,避免微服务落地失败

Posted Cloud Native Community

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了做到这7点,避免微服务落地失败相关的知识,希望对你有一定的参考价值。

本文译自 7 Ways to Fail at Microservices[1],译者张海立。作者 Holly Cummins,总结了她见过的导致微服务落地失败的一些情况,并提出了 7 个重要的关注点以引导大家来尽量避免。译者是在工作闲暇时间完成的翻译,其中难免有不当之处,请读者指正。


本文主要观点:

 微服务是一种手段,而不是目标 分布式并不能保证解耦性 合约测试(Contract Testing)是任何微服务架构的重要组成部分 分解(Decomposition)需要发生在前端、后端和集成层,以及业务逻辑中 如果企业没有能力快速、独立地发布微服务,那么微服务的许多好处就会丧失

我(Holly Cummins)是 IBM 的一名 技术顾问 [2],我的一部分工作是帮助企业实现云原生。在去年 11 月的 QCon Plus 上,我介绍了 一些不正确的微服务使用方式 [3]。这些问题是基于我的经验来整理的,它们是我在客户现场反复看到的一些问题。

我看到的第一个问题是,我们有时甚至不知道问题出在哪里。人们觉得我们应该做 微服务 [4],但我们并没有真正花足够的时间来定义我们为什么要做微服务。

我们要解决的是什么问题?现在是什么问题在困扰我们?我们做了微服务之后,什么会更好?这是一个很自然的本能问题,尤其是对于我们这些技术人员来说。我们想直接开始用微服务去解决问题,同时想玩一些这样新的酷炫的技术。尽管这些也非常重要,但更应该清楚我们要通过微服务去解决什么问题。

容器技术使这种 “直接开始用微服务去解决问题” 的情况变得更糟:因为容器是一种近乎神奇的技术,这使得它本身就是一个伟大的解决方案 —— 它是如此轻巧,它是如此的便携,它使许多事情变得更好。于是我们最终决定:“因为我已经有了这些容器,如果只在一个容器中运行我的应用程序,那将是对容器能力的严重浪费。我应该在尽可能多的容器中运行它!” 不幸的是,“没有足够的容器(来发挥伟大的容器技术的能力)” 并不是一个合理(分辨为什么我们需要微服务)的问题陈述。

简历驱动的开发

我看到的另一个问题是 简历驱动的开发 [5]。我们在看自己的简历时,有时会觉得在应该在 “微服务” 这部分写点什么。既然什么都不写肯定是不好的,所以我们会想:“我可以通过重新架构我公司的技术架构来让我的个人简历变得更漂亮啊”。读到这里时你可能在想,“不会吧,这也太功利了吧。应该没有人真的会为了完善他们的个人简历来做公司的架构决策吧?” 然而事实证明 …… 确实是有人会这么做的。

Red Hat[6] 公司最近做了一项调查,调查了 基于容器的开发的主要驱动因素 [7]。职业发展是头号驱动力。职业发展是简历驱动发展的一种更好的说法。

避免在简历上出现微服务部分的缺口是一件重要的事,因为目前微服务几乎是一种新的主流技术理念。即使我们此刻没有寻找新的工作,我们也不希望成为异类 —— 当我们环顾四周,似乎其 TA 人都在做微服务。于是一种很自然的想法是,如果 TA 们都在做微服务,那我为什么不去做做微服务呢?我把这称为 “微服务嫉妒”(Microservice Envy)。

微服务不是目标

“微服务嫉妒” 是一个问题,因为微服务并不是我们应该羡慕的那种东西。我们的一位技术顾问同事有一个讲法,如果一个客户一直在谈论 Netflix 的技术并要求使用微服务,他就知道这个合作可能有问题了。几乎可以肯定的是,他们转向微服务的原因并不正确。如果对话更深入一些,涵盖了耦合和聚合等内容,那么他就知道客户他们转向微服务的原因确实存在问题。

微服务转型的出发点不应该是微服务本身。微服务是实现业务敏捷性或弹性或同等的更高层次目标的手段。实际上,微服务甚至不是唯一的手段;它只是一种手段而已。

分布式单体

重要的是要问:“你是有微服务,还是有一个分布在数百个 Git 仓库的单体?” 不幸的是,这就是我们经常看到的情况。一个分布式的单体是一个可怕的东西 —— 很难说它到底怎样,它比纯粹单体更容易出错。在传统的单体中,所有的东西都包含在一个单一的开发环境中,你可以得到一些好处,如编译时检查和 IDE 重构支持。因为你总是在一个进程中执行,你可以得到有保障的函数执行。你不必担心记住分布式计算的谬误和服务发现,以及处理你试图调用的东西已经停止存在的情况,事情是比较安全的。另一方面,如果我们去掉了单体的安全性,但保留了耦合性,我们最终会得到 “云原生意大利面条”。

术语 “意大利面条架构”(Spaghetti Architecture)可以被定义为一个信息技术问题,它阻碍了企业快速解码和转换其应用程序和数据以满足不断变化的需求的能力。“意大利面条架构” 是一个源自一盘意大利面条外观的比喻。每根意大利面条代表每个业务工具,它们被纠结成无限的复杂线。—— 摘自《 什么是 “意大利面架构” 和如何避免它 [8] 》。

【编者按】“意大利面条” 这个比喻似乎可以理解为:各个服务虽然看似分离了,但却各种层面上耦合、混合在一起,同时还容易断裂、崩坏。

分布式不等同于解耦

几年前,我被邀请到一个陷入困境的项目中去提供援助。当我进入项目时,团队对我说的第一件事就是 “每当我们改变一个微服务时,另一个服务就会出现故障”。如果你一直在关注微服务的优势,你就会知道,这与应该发生的事情完全相反。微服务应该是相互独立的,解耦的。然而,如果你把你的系统做成分布式,解耦 [9] 就变得不那么容易了(它是有代价的)。虽然 “分布式”(Distributed)和 “解耦”(Decoupled)都以 D 开头,但它们本身不是一回事。

拥有一个高度分布式的系统是很有可能既具有分布式所带来的所有痛苦,同时又仍然是完全纠缠和耦合的。上面提到的困境就是在这种情况下发生的事情。当我开始探索代码库的时候,我不断地在每个代码仓库中看到相同的代码。这个应用程序的对象模型是相当复杂的,有大约 20 个类,其中一些类有 70 个字段。这是一个非常复杂的结构体。

微服务开发的原则之一是充分的 DRY(Don’t Repeat Yourself),避开公共库,因为它们是耦合的来源。在这种情况下,为了避免中央对象库的耦合,每个微服务在其代码中都有一个剪切和粘贴的对象模型副本。但如果领域结构体(Domain Schema)仍然是共享的,就仍然存在耦合。复制对象代码并不能消除耦合,它只是消除了编译时检查的可能性。如果一个字段名改变了,它仍然会破坏所有人,但这种破坏直到运行时才会发生。

这个悲伤的故事表明了领域驱动设计(Domain-Driven Design)原则在微服务中的重要性。我们要实现的理想情况是,每个微服务都能整齐地映射到一个领域。这样做的一个副作用,也是你做得对的一个标志,就是你的微服务的接口粒度很小。如果我们沿着技术边界而不是领域边界划分,我们最终会出现像我看到的情况;每个微服务都有一个巨大的、脆弱的接口。其结果是一个支离破碎的 “意大利面条” 式的混乱状态。

火星气候轨道飞行器

虽然从技术上讲它是一个航天器,而不是一个微服务平台,但 火星气候轨道器 [10] 很好地展示了分布式和解耦之间的区别。NASA 在 1998 年发射了火星气候轨道器,其任务是研究火星气候。遗憾的是,轨道器没有成功绕过火星;相反,探测器坠入火星。NASA 的事后调查发现,问题源于两个不同的控制系统之间的关系,这两个系统由不同的团队建造。大多数时候,转向是由探测器本身的一个系统完成的。每隔几天,当轨道飞行器进入地球的视野时,佛罗里达州的监督控制系统就会发出航线修正。这大约是一个系统可以做到的分布式;它的一部分在太空中。但这两个系统之间的领域实际上是相似的:都在处理发动机推力的计算。这两个团队在沟通中对界面的样子还不够清楚,所以他们最终使用了不同的单位。太空中的部分使用公制单位,地球上的部分使用英制单位,所以灾难发生了。我们可以肯定地说,在这种情况下,系统是非常分布式的,然而这种分布式并没有帮助。

以消费者为导向的合约测试

这种微妙的沟通问题在有多个团队参与的时候经常发生。令人高兴的是,有一个很好的缓解措施:消费者驱动的合约测试 [11]。在 IDE 没有帮助我们进行类型检查的系统中,我们需要测试我们的集成,但我们希望尽量减少全面的集成测试。集成测试很重,运行成本很高,而且本身就是耦合的。如果我们已经投资开发了微服务,我们不想在测试时倒退并制造一个大的集成单体。那么,我们如何让自己得到信心,让我们确信我们正在建立一个真正有效的东西呢?

数据模拟(Mock)是一种常见的解决方案,但数据模拟本身也有一个问题。为了建立数据模拟,生产团队和消费团队在开发之初就会就接口的情况进行对话。他们达成了一个协议,然后消费团队就去尝试写一个数据模拟,这个模拟看起来就像他们对生产团队所说的代码的理解。在理想的情况下,他们会做得很好。问题是,消费团队经常会把自己的假设也写进了模拟中,而他们也许不是知道其他代码是什么样子的,是否是合适这部分模拟的,毕竟不是消费团队编写的代码。

在顺利的情况下,他们得到了正确的结果。单元测试全部通过,而且在集成阶段也继续通过,一切都很好。不幸的是,这并不总是发生。有时,实际的实现与消费团队所理解的不同,要么是因为生产团队改变了他们的想法,要么是因为某个地方的人做了一个不正确的假设。在这种情况下,测试仍然会通过。然而,当我们真正整合真实的服务时,它就会失败。问题是,模拟的行为没有经过真实服务的验证。生产团队很可能甚至从未见过已经创建的模拟。

一个更好的选择是有一个消费者驱动的合约测试。合约测试的美妙之处,以及为什么它与模拟不同,是双方都与合约测试互动。对于消费者来说,合约测试就像一个方便的模拟。

在另一方面,合约测试对于生产团队也是一个方便的功能测试。它是一个更深刻的验证,而不仅仅是像 OpenAPI[12] 的语法检查。合约测试实际上也会检查语义和行为,这节省了生产团队编写功能测试的时间。

如果所有的东西都是兼容的并且工作的,所有的合约测试都会通过。这是一个快速的信心提升,因为它们运行起来成本很低、也很轻便。如果生产团队破坏了什么,他们的测试将失败,并提供早期警报,在破坏性变化逃逸到集成环境之前。如果 API 发生变化,新版本的合约就会被双方(或连接的中间人)提出。

现在有几个不同的合约测试系统。如果你在 Spring 的生态系统中,Spring Cloud Contract[13] 工作得非常好。如果你是一个多面手,那么我非常喜欢 Pact[14]。它有几乎所有你可能使用的语言的绑定。

企业的毛球

当然,即使我们理清了所有的测试,即使我们在业务逻辑层有一套漂亮的解耦微服务,也不能保证成功。在我们的系统中还会有许多其他的元素,这些元素可能是我们在制定真正干净的微服务架构时没有考虑到的。我们对业务逻辑的开发非常投入,而忘记了前台和后台,以及所有的胶水层。在企业架构中,胶水层是非常可能存在的,而且是粘性的。我们的一位架构师把这称为 “企业毛球”(Enterprise Hairball)。

如果我们把所有的功能分解工作都集中在业务层,我们最终往往会得到一堆整齐的解耦的微服务,夹在一个单体的前端和一个单体的数据库层之间。在这些类型的系统中,变革将是一个挑战。然而,作为一个行业,我们正在更好地分解数据库,以便将其映射到各个微服务上,并且我们正在开发微前端。

但我们还没有完成分解。如果系统不是很复杂,我们将有一个集成层。这可能是消息传递系统,也可能是一些其他的集成解决方案,将复杂的系统拉到一起。即使在架构的其他部分实现现代化架构之后,集成层往往仍然是单体的,不灵活的。团队本身可能处于重大的负荷之下 —— 正如我的同事所称呼的 “恐慌的三明治”。因为集成层是单体的,他们必须小心翼翼地安排所有的变化,这就阻碍了其他所有人。

这可能会带来很多挫折感,特别是对集成团队来说。在外界看来,他们似乎反应迟钝,速度缓慢,尽管他们正在努力工作。为了理清这种耦合,我们需要采用模块化的集成模式。

如果我们不把集成层、数据库和前端层分割开来,会发生什么?几乎可以肯定的是,我们的微服务不会达到我们想要的效果。“毛球” 各部分之间的依赖关系将使任何部分都无法快速移动。业务层的微服务将不能独立部署,部署的速度将明显地不连续。

阻碍发布的拖累

你们有多少人经历过这种情况?你非常努力地工作,你创造了一些惊人的东西;你知道用户会喜欢它,但它还没有到他们手中。价值被摆在台面上了,但你那令人惊奇的东西却不能被发布。即使你有一个微服务架构,你也会有一个发布看板。所有其它的微服务都需要同时发布,因为它们需要一起测试,这样做的成本太高,除非正好是大批量服务同时发布。即使填写发布清单也很昂贵。大家时常会害怕发布,因为可能在过去曾被低劣的发布所深深地伤害。发布检查表、发布委员会、单线程测试和其它发布方法都是为了减少那些已知的风险。因为整个组织的发布期限是共同的,所以我们最终不得不争分夺秒地在最后期限前把功能塞进去。当然,这也使得发布的风险更大。某个人正在跟踪一个电子表格,上面有所有微服务之间的依赖关系,这些微服务的耦合度比它们应该的要高。然而,发布还是得按期执行。当我们选择微服务时,这并不是我们所希望发生的!所有这些用心良苦设计的流程都成为了拖累,阻碍了价值到达用户手中,而且往往实际上又增加了风险。

测试自动化

通常情况下,我们如此害怕发布的原因是在发布中涉及到大量的手工工作。特别是,真正能给我们带来信心的测试并不是自动化的,所以我们需要做大量的工作来弄清楚我们的应用程序是否能工作。当我访问一个客户,听到 “我们的测试没有自动化” 时,我听到的是 “我们不知道我们的代码目前是否工作,它可能工作。上次我们做人工 QA 的时候它是有效的;我们希望它仍然有效”。这是一个可悲的情况。

如果你关心你们的测试,就把它自动化 —— 质量是你应该关心的东西。特别是如果架构已经偏向于 “意大利面条”,并且耦合性已经悄然出现,那么就很可能出现断裂。去 “意大利面条化” 是很困难的,所以我们要在一个快速反馈的地方,尽可能早地发现断裂。如果你要成为 “意大利面条”,至少要成为经过测试的 “意大利面条”。

发布周期

手动测试只是发布过程中涉及的手动流程的一部分。在受监管或以合规性为重点的行业,几乎总是有一堆人工合规性工作。合规性是我们非常关心的事情 —— 所以我们应该把它自动化。

有了所有这些手工流程和所有这些造成减速的流程,这意味着即使我们正在上云,但我们没有实际得到上云的红利。我们在使用云,但它好像又不是云。讽刺的是,在云中,我们曾经做过的事情、曾经是一个好主意的东西、曾经让我们更安全的事情,实际上正在伤害我们。旧式的治理在云中是行不通的,它不能实现我们所希望的商业结果,而且它失去了很多上云应得的商业利益。

通过观察发布周期,很容易发现一个企业是否实现了上云的目标。几年前,我的一位同事与一家大型的传统银行进行了一次销售会谈。他们的市场被金融科技公司和新兴的挑战者银行吃掉了,这个企业明白他们为什么会输 —— 他们无法快速地跟上。他们来找我们,解释说他们有大量的 COBOL 资产,而这正是拖累他们的原因(很可能确实如此)。然后他们补充说,他们显然需要摆脱所有的 COBOL 并转向微服务,因为其他人都在做微服务。然后他们又说,他们的发布委员会一年只开两次会。讲到这里的时候,我的同事感觉不妙。如果你的发布委员会每六个月才开一次会,你就知道你的发布节奏将是每六个月一次。你有多少个可独立部署的微服务并不重要,你不可能在这种情况下获得敏捷性。

这家银行需要的帮助并不是真正的技术帮助;他们需要改变他们对风险的思考方式,以及他们的运营方式,他们的发布计划需要进行彻底的改革,他们需要一大堆的自动化。缺乏持续交付的纪律性是阻碍他们获取敏捷的原因,而不是 COBOL。

“我想进行分解” 是一个常见的客户要求,但分解有不止一个意思。当我们希望有一个分解的应用服务时,这并不能保证模块化 —— 有时它只是意味着乱七八糟的东西被分散得更广。如果有一些外部约束,比如发布看板和陈旧的工作流程,让我们总是被限制住,那在我们解决这些问题之前,我们如何分解都可能是徒劳无功的。

关于作者

Holly Cummins 是 IBM 企业战略部的创新领导者,并在 IBM Garage 担任顾问多年。作为 Garage 的一员,她为各行各业的客户提供技术驱动的创新,从银行业到餐饮业,从零售业到非政府组织。Holly 是 Oracle Java 冠军、IBM Q 大使和 JavaOne Rock Star。她与人合著了 Manning 的《Enterprise OSGi in Action》。

引用链接

[1] 7 Ways to Fail at Microservices: https://www.infoq.com/articles/microservices-seven-fail/
[2] 技术顾问: https://www.linkedin.com/in/holly-k-cummins
[3] 一些不正确的微服务使用方式: https://plus.qconferences.com/plus2021/presentation/7-ways-fail-microservices
[4] 微服务: https://microservices.io/
[5] 简历驱动的开发: http://radar.oreilly.com/2014/10/resume-driven-development.html
[6] Red Hat: https://www.redhat.com/
[7] 基于容器的开发的主要驱动因素: https://www.redhat.com/en/blog/red-hat-survey-reveals-career-progression-driving-developer-hunger-containers-and-kubernetes
[8] 什么是 “意大利面架构” 和如何避免它: https://data-sleek.com/what-is-spaghetti-architecture-and-how-to-avoid-it/
[9] 解耦: https://en.wikipedia.org/wiki/Decoupling
[10] 火星气候轨道器: https://en.wikipedia.org/wiki/Mars_Climate_Orbiter
[11] 消费者驱动的合约测试: https://pactflow.io/what-is-consumer-driven-contract-testing/
[12] OpenAPI: https://swagger.io/specification/
[13] Spring Cloud Contract: https://spring.io/projects/spring-cloud-contract
[14] Pact: https://pact.io/

关于云原生社区

云原生社区是国内最大的独立第三方云原生终端用户和泛开发者社区,由 CNCF 大使、开源意见领袖共同发起成立于 2020 年 5 月 12 日,提供云原生专业资讯,促进云原生产业发展。云原生社区基于成员兴趣创建了多个 SIG(特别兴趣小组),如 Kubernetes、Istio、Envoy、Dapr、OAM边缘计算机器学习可观察性、稳定性、安全等。点击了解我们


点击下方“阅读原文”查看更多

漫谈微服务与DevOps:如何在实践中快速落地?

本文围绕作者这些年在OpenStack、Kubernetes、Microservice、DevOps、Cloudfoundry、ELK等云计算相关领域及技术的实践,从微服务和DevOps两方面着手,旨在为两者的落地提供一个快速可行路径。

针对这“说说还可以,一深入讨论就吵架”的热点概念,详解了在产品研发过程中的思考与实践,通过多维度的架构与技术剖析,与大家深入沟通云计算的企业级落地思路。

本文不局限于微服务与DevOps,更多的从自己这些年的经历与实践来和大家交流,更希望本次分享之后能和各位长期保持沟通与学习。

老司机简介

顾伟,毕业于东南大学,现任普元公司主任架构师;先后参与和带领了华为BME、中信银行CBJUP、工商银行CTP、中航信RI、阿里云ACE、普元云计算平台、普元The Platform等大型项目的交付;长期致力于IT技术研究、产品设计、架构咨询等工作,擅长Web、OSGI、CI/CD、服务治理、云计算等领域技术;对DevOps、自动化运维、微服务架构有着浓厚的兴趣。

分享包括以下四部分:

  1. 我经历的云计算历程:简单介绍下自己参与的一些产品研发,然后从现在市场格局的角度,提出一些自己作为云计算产品线负责人的想法;

  2. 微服务与DevOps的认识:围绕今天的主题,从微服务与DevOps角度,阐述自己的理解;

  3. 平台级的实践与支撑:基于当前正在研发的“基于微服务架构的DevOps平台”,详解我们的设计与技术,当然也会有些坑里面会提到;

  4. 参考与总结:整个过程中我们也参考了很多优秀的架构与理念,希望对大家也有用,最后给今天的分享做个总结;

我经历的云计算历程

漫谈微服务与DevOps:如何在实践中快速落地?

漫谈微服务与DevOps:如何在实践中快速落地?

严格来算,我是09年开始做和云计算有关的事情的,中间经历了很多方向、技术的变更,对个人确实有好处(接触更多的人和事嘛),但对于产品线来说,这往往是很不明智的:

  • 09年:如果放到现在大家会叫它为“传统的PaaS平台”,我们做了一款“云应用交付平台”,平台面向于运营商,帮助其更快速的部署轻量化的应用及服务,并提供了一定的快速伸缩能力,平台没有用到现在大家熟悉的技术栈,说实话,就是个土生土长的有点土的家伙;

  • 11年:正值OpenStack与CloudStack兴起,我们也看到了云计算的“美好前景”,从IaaS层着手,旨在从所谓的“千亿”市场分一杯羹,“理想很美好,现实很残酷”;

  • 13年:混合云模式逐步被接受,大家是否记得前段时间刚刚正式下线的ACE平台,当时我们就参与了这款平台的企业级落地,虽有成功案例,但混合云目前的形式,大家都是清楚的;

  • 15年:我们走到了现在的阶段,以容器为默认承载,微服务架构为支撑,打造企业级DevOps数字化平台,事实证明这个13年就想到过的点子是很成功的,成功在于两面:市场上的客户反馈(包括收入)和内部的能力驱动(团队使能)。

那我们再来看看现在的云计算格局:

漫谈微服务与DevOps:如何在实践中快速落地?

我不太喜欢用标准的IaaS、PaaS、SaaS来区分,我认为这个界限越来越模糊(比如我们甭管好不好,三者都做),我更倾向于UCOBP的模式来看待领域:

  1. 就目前来说在运营商和软硬件提供商来看,市场趋于稳定,大家都还把住了自己的核心优势(体量、门槛…)

  2. 但从集成商和应用或者服务提供商来看,这些市场还是面临着竞争,比如现在的很多创业公司,都是瞄准这两块开始的

漫谈微服务与DevOps:如何在实践中快速落地?

我觉得像现在的云计算、大数据、移动互联、物联网、人工智能等大领域(其实我觉得泛领域更合适),进去很容易,想做好(至少赚到钱,借马云名言:“能赚到钱的不一定有价值,对社会有价值一定能赚到钱”)是要有几个前提的:

  1. 定位要明确,你在这些泛领域中有没有找到市场地位,不求找到的都是蓝海,但不能使劲往红海挤

  2. 方式要合理,我们一直遵循一个很简单的方法,我们自己叫“厚+薄”,这个面向企业市场很有用。所谓“厚”是说企业流程都是复杂的,无论用什么,需要基于企业级流程串接;所谓“薄”是说现在开源技术多如满天星,如何去其糟粕,取其精华,是我们要总结的

  3. 基因很重要,下一个红帽也许永远不会再出现了,不仅仅IT市场,大家的朋友如果做生意一样能感受到,以前只要愿意努力去做,加上一点点聪明,基本上不会失败;现在如果你要去拓新一个完全未知或不相干领域,基本上会有两条死路,做不起来或者做起来点儿被巨头给cut了。

漫谈微服务与DevOps:如何在实践中快速落地?

微服务与DevOps的认识

漫谈微服务与DevOps:如何在实践中快速落地?

漫谈微服务与DevOps:如何在实践中快速落地?

现在见客户就会聊微服务、聊DevOps、聊容器,但这种热点概念,真的是“简单聊聊可以,一深入就吵架”,比如以前谁问我传统应用该怎么拆分,我还会说一堆,现在基本上对于这种开放型问题都不敢回答了,怕“没朋友”。

我简单说说我对微服务和DevOps的认知吧:

漫谈微服务与DevOps:如何在实践中快速落地?

第一个就不说了,第二个垂直架构,典型的比如SSH框架,帮大家考虑了模块化、MVC等,但并没有考虑服务化。

第三个是分布式架构,以SOA为代表的这类技术已经热了很多年,也很成熟,也是目前很多企业架构的主体支撑。

而第四个以微服务架构为支撑的技术虽然在一些先进企业或互联网公司已经运用,但从生态上来看,还有很长一段时间要走,其更强调在DDD下的业务服务自治性及原子性。

漫谈微服务与DevOps:如何在实践中快速落地?

“DevOps”通常指的是新兴的专业化运动,这种运动提倡开发和IT运维之间的高度协同,从而在完成高频率部署的同时,提高生产环境的可靠性、稳定性、弹性和安全性。

其概念也特别多,简单浏览下就可以了:DevOps运动的起源通常被放在2009年前后,伴随着许多运动的相辅相成和相互促进——效率研讨会运动,特别是由JohnAllspaw和Paul Hammond展示的开创性的“一天10次部署”,基础设施即代码”运动(Mark Burgess和LukeKanies),“敏捷基础设施运动”(Andrew Shafer),“敏捷系系统管理(PatrickDeBois),“精益创业”运动(EricRies),JezHumble的持续集成和发布运动,以及Amazon的“平台即服务运动”等这些运动的相辅相成和相互促进而发展起来的。

云计算、微服务、容器这些概念或能力之间到底是什么关系呢?其实这个主要看大家的方向了,结合我所面临的客户以及IT现状,我的理解是这样的:

漫谈微服务与DevOps:如何在实践中快速落地?

  1. 云基础平台作为底层支撑,既可以是Docker、Unikernel这样的容器技术,也可以像vmware或OpenStack这样以VM为管理单元的方式,旨在为上层提供有SLA能力的资源池管理与调度;

  2. DevOps作为一层可选平台,以流程自动化、工具自动化为主要手段,通过长期的积累与优化,为最终业务交付提供更敏捷、更数字化的能力;

  3. 历史系统与微服务在企业会长时间并存(BiModal),不要试图一步到位,我所经历的企业客户中,都是从部分外围应用开始试点,甚至是先拆应用、再拆数据这样循序渐进的。

漫谈微服务与DevOps:如何在实践中快速落地?

平台级的实践与支撑

漫谈微服务与DevOps:如何在实践中快速落地?

先和大家说说我们的平台具体在做什么:

漫谈微服务与DevOps:如何在实践中快速落地?

这个定位(非市场定位)讲起来比较拗口,“用微服务架构,做云计算DevOps平台,支撑上层微服务的全生命周期管理”。 这里有个鸡生蛋、蛋生鸡的问题,那我们还是通过制定微服务的规范以及一部分配套工具,基于这些开发了第一版DevOps云平台,将其作为后续版本的生产线使用。过程中对康威定律又有了进一步认识,尤其是运用在异地协作和技术选型上,团队能力、异地松耦合是必须考虑的维度。

先将平台用到的一些技术栈列出来:

漫谈微服务与DevOps:如何在实践中快速落地?

图中标红的是目前我们已使用的,相信大家不难看出来:

  1. 我们主要是走的容器云这条线(当然传统的也是支持的),以Kubernetes为容器管理与调度的框架,结合Flannel网络、Ceph存储形成底层基础支撑

  2. 微服务方面使用SpringBoot作为载体,引入了Netflix的部分框架支撑微服务调用、配置

  3. 在全生命周期中,还支持了文档、Mock、自动化测试的能力,以便微服务架构下的快速交付

  4. 在监控方面采用Journald采集,Fluentd作为server、同时通过索引及时序库支撑数据分析及展现

这里有三个想法与大家共勉:

  1. 架构师的角色转变,从原来的技术货架的搭建(加法)到现在海量技术中选择最合适的(减法),对能力的要求更高

  2. 个人全栈已经不再多见,而团队全栈却越来越重要,学习型组织将是未来衡量团队能力的一大标准

  3. 框架能力的阳性与阴性,同样是结合现在海量技术来看,测试是必不可少的,但业务场景的多变往往会造成数据的片面性,比如Flannel的UDP和Vxlan模式(就像体育赛场上一样,阳性不好,但伪阴性就更糟糕了)

接着分别从微服务和DevOps方面来看看我们的一些关键设计和想法,先说说微服务架构:

漫谈微服务与DevOps:如何在实践中快速落地?

当然微服务架构中重要的不仅仅是上述的5个能力:

  1. 服务的隔离与互通

  2. 伸缩与漂移

  3. 升级与回退

  4. 熔断与降级

  5. 服务注册与发现

漫谈微服务与DevOps:如何在实践中快速落地?

上图亦可理解为是核心概念模型,面向的问题是这样的:

  • 有些企业会考虑生产上VM,开发测试上容器;

  • 有些企业需要开发测试预发上线四套环境,有些只要两套:

  • 有些企业环境间要求完全隔离,有些只要逻辑隔离;

  • 有些企业要求对接下层资源池,有些则完全没有资源池的概念;

  • ……

那概念模型上我们怎么办?上图的核心是业务运行及namespace的设计,下层无论资源有没有池化,都需要加一层Namespace的管理,这个管理有很多目标,比如隔离,再比如池化。

然后紧接着是pod,这个概念参考了Kubernetes,在微服务运行时,一直强调一个业务的独立性,比如一个业务,其应用及数据库是绑定的,且与其他业务隔离。那我们认为这种就是一个pod(豌豆荚),体现的是一个独立业务(微服务)。

一个pod无论内部如何,一般是跑在一台宿主机的,业务内部尽量本地调用,pod可以包括多个进程,也可以包含多个容器,也就是上图的pod与process的关系。

从可靠性及性能考虑,pod必须是集群的,所以一个pod可以有多个副本,也就是上图的pod与replication的关系。

下图是运行时的调用过程示意:

漫谈微服务与DevOps:如何在实践中快速落地?

漫谈微服务与DevOps:如何在实践中快速落地?

微服务的伸缩与漂移,需要与监控能力结合,监控结果判断则运用的是万年不变公式:

Result = function1*weight1 + function2*weight2 + …… + functionN*weightN。

以漂移为例子,漂移有很多触发器,有因为故障的,有基于优化考虑的,比如像优化漂移这种,就要求定义很多维度,包括资源均衡维度、宿主机特性维度、标签配置变更维度等,需结合多维打分对微服务进行合理调度。

那对于伸缩漂移所依赖的能力上,着重考虑下述两点:

漫谈微服务与DevOps:如何在实践中快速落地?

  1. 存储能力,存储可从服务状态特征考虑,一般来说,有状态服务采用共享存储,无状态服务采用非共享或者不适用存储。

  2. 监控能力,点线面结合的监控,需注意对Metrics的正确使用,以及全局流水号等规范约束。

漫谈微服务与DevOps:如何在实践中快速落地?

微服务的升级与回退:

  1. 发布要原子化,可编排,每个企业在流程上都会有所区别,只有在完全原子化的情况下,才能保证平台的快速实施

  2. 标签设计,让每个动作、每个状态、每个资源都可以标识;标签设计不仅仅用于部署,我觉得在任何产品中都有借鉴意义

  3. 状态设计,部署是原子化的操作,而内部的状态设计同样重要,比如可结合状态做挂起、唤醒等诸多操作

  4. 版本规范,这个不仅仅是版本号的规范,还包括版本升级规范、配置规范等,不过微服务架构下,建议全量升级与回退

  5. 路由能力,微服务这种快速迭代发布,伴随试错试对,快速变更,灰度等,对流量的出入动态性要求很高

漫谈微服务与DevOps:如何在实践中快速落地?

而对于我们来说,使用了rollingupdate机制来进行升级和回退(包括灰度),大家可参考Kubernetes的机制,一种基于标签和Replication的实现方法。对于升级回退、灰度中,最复杂的莫过于数据库以及前端负载的处理问题:

1、数据库简单的做法就是类似传统行业,尤其像银行等,只增不减的方式 2、前端负载问题要结合业务来实现,很多企业会在Apigateway中考虑,当然不同行业稍有区别,比如在电力行业,IBM给规划的API基线也有这个能力

漫谈微服务与DevOps:如何在实践中快速落地?

微服务的熔断与降级,当然熔断与降级并不是一个概念,只是很多时候会一起实现了:

  • 熔断是指上游服务在调用下游服务时,因下游服务的种种问题,对调用链智能处理的手段

  • 降级是指整体资源瓶颈时,一般业务暂停(优先保证核心业务)的一种处理手段

举例:熔断器实现方式,设计参考了一般都使用的三态设计,默认关闭态,调用出错率到一定程度半开,半开时,允许一部分流量继续调用下游微服务,如果一定时间还是出错(这个时间可结合MTTR设置),就将熔断器置为全开态,同样设置一定的时间后再尝试调用;

现在在熔断和降级这块实现的比较好的包括netflix的Hystrix,还有motan,大家都可尝试,我们Hystrix测试过,目前使用了motan,仅从能力上对比,Hystrix无疑更强大。前段时间乐视受攻击,差不多每秒200G流量,最终能撑下来据说主要功劳和这个有关系。

漫谈微服务与DevOps:如何在实践中快速落地?

微服务的注册与发现,解决微服务之间的调用、以及一定的客户端和服务端集群的问题。采用etcd作为分布式注册中心,在服务启动和停止时实现注册和注销,运行过程中,会定时同步服务的元信息(比如流量、健康性等),以便实现智能路由。

接着,我们来看看在DevOps实践中的一些关键点:

漫谈微服务与DevOps:如何在实践中快速落地?

四要素的提法和友商大同小异,包括组织、流程、技术、文化,下图会将四要素进行更细粒度的要素分解。

漫谈微服务与DevOps:如何在实践中快速落地?

  • 组织:包括全栈团队、自治团队等

  • 流程:包括开发、测试、集成、交付、度量等

  • 技术:包括监控、chatops等

  • 文化:包括协作、学习等

漫谈微服务与DevOps:如何在实践中快速落地?

实现企业级DevOps,有很多方式和着手点,比如最常用的就是从持续发布开始。而我们更聚焦企业的全生命周期,所以在目前版本中(与上图有少许不对应),实现了基于微服务架构的以下15个DevOps领域系统:

  1. IAM:身份识别与访问管理,通过OAuth能力,一次登录,全网通行

  2. SPM:软件产品管理,DevOps平台的核心管理对象:产品。以产品维度为入口,管理包括产品的多版本,每个版本拥有多个组件,组件之间、组件与第三方产品之间的依赖关系等

  3. SCM:软件配置管理,主要是应用配置的管理,在编译打包时通过autoconfig技术,注入到最终部署包

  4. SRM:软件资源管理,资源,即上述产品的运行实例,所以持续发布等都是有SRM发起

  5. SEM:软件环境管理,企业环境千差万别,SEM屏蔽了异构环境的差异性,让上游系统及业务能够松耦合的运行

  6. QAF:质量保证反馈,这个系统负责收集全生命周期的数据反馈,为后续优化演进提供重要依据

  7. UMC:统一监控中心,主要收集日志及资源运行信息,通过计算分析,形成相关报表,同时与告警中心对接,风险异常准实时提示

  8. VCS:版本控制系统,默认集成GIT

  9. CI:持续集成系统,默认集成Jenkins

  10. BPR:二进制仓库

  11. DPR:可部署包(镜像)仓库

  12. PM:项目管理系统,可集成redmine或wiki,目前平台是自己实现的

  13. IM:团队间即时通讯系统

  14. TM:租户管理系统

  15. MKT:云市场,平台最终期望作为中间平台,通过市场打通内容提供者与最终用户

漫谈微服务与DevOps:如何在实践中快速落地?

这里对一些DevOps的关键系统协作方式做了一定描述,就不赘述了。

漫谈微服务与DevOps:如何在实践中快速落地?

最终这个平台同时支撑了公有云与私有云两条线(8月发布第二版),其中公有云目前运行于阿里云上,使用了阿里云的ECS、VPC、EIP等很少的服务种类;而私有云,目前也在一些企业开始试点。

当然,过程中,尤其是公有云上遇到了不少问题,举两个例子:

  1. 我们采用coreos系统作为宿主系统,阿里云的版本很低,只能自建升级服务器,但升级后网卡默认没有启动,且因为一些service未启动问题,导致无法快照。

  2. 再比如安全组问题,同一安全组的ECS完全不控制的方式,让我们也忙活了很久。

漫谈微服务与DevOps:如何在实践中快速落地?

参考与总结

漫谈微服务与DevOps:如何在实践中快速落地?

最后分享下我觉得比较好的一些可参考材料,并对分享做下总结:

漫谈微服务与DevOps:如何在实践中快速落地?

这个不确定最初是不是Gartner提出的,旨在给DevOps从运营效率、服务、组织、客户价值、业绩维度评估,让企业发现其需要改进的一些点。

漫谈微服务与DevOps:如何在实践中快速落地?

平台品质属性,很多时候翻译成质量属性,一种属性分类的方法是把在运行时可识别的特性与那些不可识别的特性区分开),另一种方法是把对用户很重要的可见特性与对开发者和维护者很重要的不可见特性区分开,和CAP类似,这些特性有些可叠加,有些则会相互制约,在产品设计时需清楚哪些是您最迫切的。

漫谈微服务与DevOps:如何在实践中快速落地?

Heroku的12Factor,这些因素为系统的CloudNative目标考虑,让云上云下得到同样的体验,这12因素不能简单的字面理解,要结合您现在的实际运行来看,则会发现其独到的地方,也不要想一蹴而就,只要时刻有这么根弦,在很多选择前面看看这12因素是否有类似的可参考,比如当时我们纠结了很久的,VCS是否使用TBD模式,其实这里面都可以找到相关答案。

漫谈微服务与DevOps:如何在实践中快速落地?

谷歌的Borg,作为谷歌内部的管理调度核心,支撑着谷歌上万台机器及业务的运行,这个虽然是不开源的,但其设计思路和架构是很容易被找到学习的。参考这个的原因是谷歌本身内部就是容器与微服务架构的生产运用,是一个真正大规模的实践参考。

漫谈微服务与DevOps:如何在实践中快速落地?

漫谈微服务与DevOps:如何在实践中快速落地?

扫描作者二维码加入由作者顾伟主持的“普元云计算研发开放群”,与大牛讨论更多云计算、微服务、DevOps、容器相关内容,加群备注为“云计算”。

延展阅读(点击标题):



喜欢我们的会点赞,爱我们的会分享!

今晚8:30,InfoQ大咖说最新直播,等你来看!

以上是关于做到这7点,避免微服务落地失败的主要内容,如果未能解决你的问题,请参考以下文章

微服务之服务容错 Hystrix

「微服务架构」Medium的微服务架构实践

活动丨火了两年的微服务架构,为何迟迟难以落地?

微服务构建持久 API 的7大规则

微服务构建持久API的7大规则

(转)微服务框架落地实践之路