专栏名称: 聊聊架构
在这里煮酒聊架构。
目录
相关文章推荐
高可用架构  ·  醍醐灌顶!异地多活架构设计看这篇就够了 ·  3 天前  
架构师之路  ·  github标星17.5W,榜单前20唯一中 ... ·  5 天前  
架构师之路  ·  又一篇10W+,它来了... ·  3 天前  
架构师  ·  详解三大权限模型 ·  1 周前  
架构师  ·  详解三大权限模型 ·  1 周前  
51好读  ›  专栏  ›  聊聊架构

关于微服务的发展方向,我们和5位专家聊了聊

聊聊架构  · 公众号  · 架构  · 2017-04-05 07:46

正文

作者|Mark Little
编辑|薛命灯

微服务已经从少数几个“独角兽”公司的内部开发实践变成了广为人知的架构模式,很多开发者正在考虑是否采用微服务架构。很多人认为,为了从DevOps中获得好处,采用微服务架构是必要的前提。

在过去几年,我们见证了很多促进微服务成形的新技术,它们在与面向服务架构(SOA)寻求差异化的同时却也巩固了它们之间的关系。有些人认为,如果采用微服务的组织没有做出相应的调整,那么微服务技术和方法论可能不会起到太大作用。

InfoQ与五位专家从不同的角度针对微服务当前的状况展开讨论,预测了微服务的发展趋势,专家们也分享了他们在微服务开发中获得的各种经验。

参与讨论的专家:

  • Chris Richardson —— 开发者和架构师,Java Champion,《POJO in Action》的作者

  • James Lewis —— ThoughtWorks技术委员会成员

  • Martijn Verburg —— jClarity的CEO和联合创始人

  • Christian Posta —— Red Hat首席架构师,《Microservices for Java Developers》的作者

  • Adam Bien —— Java(SE/EE/FX)咨询师和布道者

InfoQ:我们关注微服务已经好多年了,从一开始到现在,我们从中学到了什么?

Richardson:“微服务”是一个很糟糕的名字。它强调了服务的大小,导致开发人员创建了很多粒度很小的服务,每个服务拥有一个单独的REST端点。不仅如此,这个名字还暗示了微服务在开发者心目中的重要位置。例如,人们会说“我们可以用微服务来解决这个问题”,我也看到了越来越多的“某某微服务框架”,而实际上,这些框架跟微服务架构不一定有太多联系,它们只是简单的Web框架。

使用“微服务架构”这个名字会更恰当些。它是一种架构风格,它把一系列协作的服务组织成一个系统来支撑业务。

Lewis:我认为,微服务的大范围采用造成了一定程度的语义折射。我和Martin Fowler对微服务进行了清晰的定义,微服务的特性可以帮助公司走向成功。我与很多大型公司进行过交流,他们想要采用微服务架构,他们接受了微服务的第一个特性,对服务进行组件化,但他们并没有根据微服务的其它特性对组织结构做出相应调整,特别是对于产品、业务能力和去中心化的监管来说。我个人认为组织调整是成功实施微服务的关键因素。

Verburg:太多了!不过我挑几个我最喜欢的:

  • 服务发现 —— 不管是在开发时还是在运行时,服务发现比我们想象得要难得多。我经常看见整个团队的开发人员在争论“下一步应该把消息发到哪里”。

  • 分布式跟踪 —— 我们很难通过简单的方式完成对业务逻辑和事务的跟踪。例如,如果一个业务逻辑需要经过十个以上的微服务,而且这些微服务使用了不同的技术,那么该如何为此创建一条跟踪信息?

  • 分布式架构 —— 基于微服务的应用一般都是分布式的,需要横向伸缩和负载均衡。传统单体应用开发人员和系统管理员必须学习一系列新的技能。例如,如何对Websocket连接进行负载均衡?要知道,Websocket连接是双向且“持久”的。

Posta:现在微服务的概念如日中天,我希望我们能够弄明白一件事情,乌托邦式的架构是不存在,简单地使用时髦技术并不等于微服务,而且组织的沟通结构与服务架构有着更深层次的关系,这个联系比我们先前意识到的要更加紧密。

还有一点很关键,在微服务架构里,我们应用了很多分布式的理论和实践,它们都是我们从过去的40年经验里学习而来的,多年来它们鲜有变化,我们只是用它们来解决新的业务问题。

Bien:我花了很多时间在Java EE项目上。在2009年推出的Java EE 6成为推进微服务架构发展的主力。在过去,我们把业务逻辑打包成WAR,不过Java EE 6打破了这条规则。在2009年,我们把我们的项目架构称为“非共享式架构”,那时“微服务”这个名词还没有出现。

在当时,监控和压力测试是一个艰难的任务。有了微服务,现在可以专注于压力测试、系统测试,并对各种使用场景进行监控。在微服务之前,很多项目专注于使用单元测试来提高代码覆盖率。而这一切开始在发生变化。

早期Java EE 6项目和现在的项目之间存在的最大区别在于通信协议的不同。在2009,我们更多地依赖二进制RPC协议,而现在默认使用JAX-RS(REST/HTTP)和Websocket。

InfoQ:最开始是那些“独角兽”在驱动微服务,你们认为现在还是这种情况吗?如果不是,那么谁是继任者呢?

Richardson:是的。大部分关于微服务架构的大会似乎都是在谈论“关于Netflix/Uber/Slack/Twitter……的微服务架构主题”。一方面,这些讨论是很有意义的,而且促进了微服务架构的传播。另一方面,这让很多开发人员认为微服务架构是为了解决应用程序的伸缩性问题,但实际上,它解决的是复杂性问题。总的来说,能够从主流公司听到关于他们使用微服务的经验是很有价值的。

Lewis:是的,我认为这些公司仍然处在不可取代的位置上。他们为微服务带来了很多先进的东西。它不是一种“101”式的架构风格,当微服务架构被大规模使用时,你就能明显地看到它的好处。

Verburg:他们还是的。BBC、Netflix、Twitter、Amazon这类公司都是基于微服务架构的,因为它们有横向伸缩的需求。不过这也是大部分IT组织在盲目跟风时无法解决的一个主要问题。“我们真的需要微服务吗?我们的规模需要使用微服务吗?我们的业务需要微服务吗?”对于很多组织来说,答案是否定的。

Posta:引用Branden Williams博士的一句话“再也不存在什么独角兽了,只有那些蹦向胶水工厂的纯种马……”那些互联网公司已经向我们展示过这一点,不过我认为在传统企业领域(FS、制造商、零售商,等等),还是有很多公司正在展示他们使用新技术快步前进的能力。

Bien:最开始没有人知道“微”意味着什么。关于服务大小的讨论是没有意义的。在Java EE里,一个微服务就是一个WAR包,它们通常由“单披萨”团队创建(“双披萨”的团队规模太大了)。

在我看来,继任者是那些基于微服务的企业项目。独角兽来了又去,如果他们只是在刚开始获得成功,那么对于他们的成功就很难给予平价。企业项目会持续更长时间。

InfoQ:有些公司将微服务架构用于全新的应用开发,而有些则关注如何将单体应用迁移到微服务架构。对于这两种情况,微服务的原则是否同时适用于架构师和开发人员?

Richardson:对于大型的复杂系统来说,不管是哪一种情况,微服务架构都是适用的。这要取决于实际的开发场景。例如,对于一个初创公司来说,他们还处在探索业务模型的阶段,那么应该更倾向于使用单体架构。

我认为大部分关键性的业务应用都是大型的复杂单体应用。这些业务无法快速演化,只能循序渐进地将其迁移到微服务架构。

Lewis:我参与过的团队经历过上述两种开发场景。对于迁移开发来说,迁移到微服务通常是有好处的,因为它会给我们带来更多的选择,而且它们包含了之前系统的功能。对于全新的开发来说,就要考虑功能和跨功能需求,以及系统所运行的环境。有时候可以使用微服务架构,但有时候不是必需的。

Verburg:原则都是适用的,但会有一些折衷。完全分解一个单体应用是终极目标,但应用在它生命周期的大部分时间里都会处于微服务和单体共存的状态(有些人把这称为怪物Cthulu的化身)。例如,微服务纯化论者在对单体应用进行迁移时,他们会把原则撇在一边,仍然会“通过存储过程来传递消息”,直到他们把整个应用重构完毕。

这个时候集成测试变得很重要。

Posta:从它们对开发速度的影响来说,这些原则是相似的。你可能会有很多全新的开发项目,不过难点在于如何找到它们与现有系统的结合点,从而对其进行安全的扩展、加速和创新。

Bien: 2016年,大部分用户对于引入微服务架构是抱着很大希望的,他们希望微服务能够带来更好的可维护性,并降低成本。微服务并不缺乏受众,只是有太多人盲从,缺乏好的实现模式。

把一个超级复杂的单体分解成更加复杂的小型单体只会让事情变得更糟。对于已有的项目来说,首先要避免盲从,并重新对领域概念进行分析。将一个精益的单体分解成独立的单元完全是一件可有可无的事情。

对于新项目来说,首先要聚焦在业务逻辑上,在最开始的迭代中可以使用单体。只有在你对优缺点做过明确的了解之后才考虑引入微服务。毕竟交付一个精益的单体应用仍然是最为简单的方案。

不管怎样,新项目和已有项目都需要聚焦业务逻辑。

InfoQ:你们能列出关于微服务的5个要做和5个不要做的注意事项吗?

Richardson:最重要的一点是要知道微服务并非银弹。你需要仔细评估你的应用,并做出权衡。

Lewis:

要做的:

  • 监控,监控,监控。

  • 做好服务的独立部署。

  • 倾向于使用快速变更和canary部署而非集成测试。

  • 倾向于编排而非编配。

  • 对调用结构进行限制。系统的服务越多,就越难保证可用性。

不要做的:

  • 不要一下子构建中500个服务,而是先构建合理数量的服务,最起码当前的基础设施能够支撑得起。

  • 不要把它们看成银弹。要构建好微服务系统,你需要了解更多的分布式计算知识。

  • 不要被厂商的万灵油蒙蔽了双眼,面向服务架构当初就是这么死掉的。

  • 不要忽略了可替换性。微服务要小到可以直接被替换掉。

  • 不要使用分布式事务。

Verburg:

要做的:

  • 确保你的团队使用的是敏捷开发模式。

  • 确保你的团队具有DevOps文化。

  • 在构建整个系统之前先构建3个互相交互的服务原型,找出实现非功能需求的解决方案,比如安全问题、服务发现、健康监控、回压、失效备援,等等。

  • 让工程师为每个服务选择合适的技术,这是微服务的一个主要优势。关注集成测试。

不要做的:

  • 不要因为Netflix使用了微服务你也跟着用。

  • 忽略了数据一致性。“我们的微服务架构没有ACID事务,让你的金钱蒙受损失我们感到很抱歉”,这样的情况是不能被接受的。

  • 忽略了基础设施需求,甚至忽略了开发者的开发环境。所以要尽快让开发人员可以在一个模拟的生产环境里进行开发。

  • 忽视了命名的重要性。一旦发布了公开的API,你就被牢牢地绑在一起了。另外,不要忘了为你的API添加版本管理。

  • 抛弃多年的开发经验和已经写好的业务逻辑。要知道,微服务开发是一个演化的过程,不是重新发明轮子的过程。

Posta:

要做的:

  • 对微服务架构的实施进行评审,并把它作为指南。微服务可以用于衡量团队在不影响其他服务的情况下能够以多快的速度做出变更和部署。可以关注一些指标,比如构建的次数、部署的次数、缺陷的个数、部署的审批时间、恢复服务的平均时间,等等。

  • 为功能团队建立反馈闭环。对系统或服务做出变更,却不知道变更将会带来怎样的影响,这样做一点好处都没有。让开发人员和功能团队尽可能地接近用户(或者站在用户的角度),这样他们就可以更直观地感受他们的系统给用户带来的痛苦。

  • 关注数据。数据是公司的生存之本。在构建微服务时,要注意用例边界、事务边界、一致性问题,以及数据的处理(数据流、数据存储,等等)。

  • 赋予微服务开发团队自主权和自由,让他们担起职责。为他们提供自助的工具服务、API服务和基础设施服务。

  • 让微服务仪表化、可调试,并提供度量指标,把测试作为一等公民,而不是马后炮。

不要做的:

  • 不要简单地复制独角兽公司的模式,要找到他们成功的原理,并把这些原则作为指引。只是简单地采用Netflix的技术不会让你的公司也成为Netflix。

  • 不要试图通过微服务来降低成本,微服务能够带来创新和业务成果,但不能用来最小化运营成本,这个跟传统的IT不一样。

  • 不要为了分解系统而分解系统。随意分解系统可能会让你的系统变成难以伸缩的分布式单体系统,事务处理会成为大难题。

  • 不要忽略了分布式系统存在的陷阱以及在系统集成方面存在的挑战。

  • 如果在CI/CD、API、DevOps、自助平台、自助团队等方面存在问题,那么就不要强行使用微服务架构。在使用微服务架构前要先了解微服务的原则和最佳实践。使用微服务本身不是目的,通过微服务打造具有创新能力且能够快速行动的团队才是目的。所以首先要打好实施微服务的基础。

Bien:

要做的:

  • 对容器部署技术进行评估。容器技术有很大优势。

  • 关注业务逻辑。

  • 对关键用例或性能指标进行监控。

  • 关注系统测试,而不是单元测试。

  • 通过CI/CD进行自动化。

不要做的:

  • 不要盲目复制Netflix、Twitter、Facebook或者Google的做法,除非你也有他们那样的规模和需求。

  • 不要忽视缓慢的部署过程。部署一个大的WAR包要比一个小包要花更多时间。效率很重要。

  • 不要尝试在微服务间协调事物。

  • 不要在新项目里使用太多技术。少即是多。每一个依赖项都会拖慢部署速度,它们还需要额外的安全审计和缺陷修复工作。从来不存在“免费”的依赖项。

  • 如果可以不使用分布式,精益的单体会是更好的选择。

InfoQ:HTTP或REST/HTTP通常被认为是微服务事实上的通信标准,不过最近有很多组织在谈论使用异步或消息服务作为取代方案,你们是怎么看待这个问题的?

Richardson:是的。HTTP/REST是目前主要的IPC通信协议。它为人们所熟知,使用起来很简单。不足之处在于它在服务和客户端之间引入了一定程度的耦合,这在某些情况下多多少少会成为一个问题。例如,在处理一个需要从多个服务获取数据的请求时,就不会有问题,但如果这个请求是一个更新数据的操作,那么就需要使用异步的消息服务来实现事务的最终一致性,也就是sagas。

Lewis:对于我来说,微服务的端点问题不在于是否使用了REST/HTTP,而是微服务之间是否具有统一的接口。我曾经所在的一个团队同时使用了轻量级的消息服务和RESTful框架来实现统一的接口,而且这两种方式都很成功。解决问题的关键在于为问题选择合适的模式。如果你的业务流程具有异步特点,那么就应该使用异步的集成技术。反过来,如果你的问题可以使用map-reduce的模式来处理,那么就应该使用反应式的方案。我们总是尝试寻找简约的方案来解决问题,这完全取决于你自己是怎么想的。

Verburg:我认为,随着时间推移,这两种模式都会流行起来的。以jClarity为例,我们使用了异步的消息服务,不过同时也为开放接口使用了REST/HTTP(S)。

Posta:在对微服务系统进行扩展时,它们会表现出类似其他复杂自适应系统的特征(股票交易系统、蚁群系统、社区系统):自治的代理、独立的决策、反馈驱动的自我学习、非线性的迭代,等等。在这类系统里,事件、消息和时间戳让它们看起来更像是一个“异步”模型。时间戳成为这些系统的关注点(系统间的通信通道是不可靠的,这也是一个客观存在的事实),我们必须事先处理好这些问题,并让已知的模型在其它应用里得到扩展。

Bien:在我的项目里,HTTP/REST(一般是JAX-RS)已经足以应付大多数的使用场景。有时候我们也会使用Websocket进行异步通信、P2P(peer-2-peer)交互和消息传递。这些场景更像是例外,而不是规则。

InfoQ:相比传统的开发,微服务架构更偏向于分布式,对于一个微服务新手来说,他应该从哪里开始入手?

Richardson:开发人员依然要使用很多他们熟悉的框架和软件包来开发单独的服务,这个跟过去相比没有多大改变。不过,如果使用了微服务架构,事务管理和查询操作需要用不同的方式来处理。可以参考我最近发表的InfoQ文章和我的网站来了解这方面的问题以及如何解决它们。

微服务架构的核心是为业务能力和业务子领域组织微服务。我推荐阅读Eric Evan的《Domain Driven Design》这本书,他的设计策略都是以微服务架构为中心的。

Lewis:我认为Sam Newman的《Building Microservices》是一本很好的书,我会从这本书读起。如果要了解微服务的背景,我推荐阅读Eric Evans的《Domain Driven Design》,还有Webber、Robinson和Parastatidis合著的《REST in Practice》、Hohpe和Woolf合著的《Enterprice Integration Patterns》,以及Michael Nygard的《Release It!》。关于构建组合系统背后的哲学,我极力推荐Eric Raymond的《The Art of UNIX Programming》。在Martin Fowler的网站上可以找到更多相关资源。

Verburg:对于从传统Java企业开发转到微服务开发的新手来说,microprofile.io社区是一个很好的地方。不管他们从什么地方开始入手,他们必须知道该如何建立基础设施。可以租用一些Linux主机(或者使用Docker),并构建一个“hello world”服务,这个服务与另一个“机器”上的“Hi Back!”服务进行交谈。在这个过程中,你需要使用到HTTP(S)、认证、负载均衡、IP tables、分布式数据存储引擎(比如MongoDB)等等。

在微服务架构里,应用程序代码是最简单的部分,难点在于系统工程。

Posta:这是一个很好的问题。过去40年关于分布式系统的研究和实践是实现微服务架构的核心基础。认识ACID数据库对你的重要程度,了解在采用分布式时所要面临的挑战,这是首要的任务。有很多这方面的论文可以参考,Jim Gray、Peter Bailis、Alan Fekete、Pat Helland、Leslie Lamport,他们的论文我都很喜欢。我主攻系统集成和消息服务,不过这些论文加固了我对基础概念的理解。

Bien:关注领域概念、目标领域和用户。举个例子,最好的Java EE项目只包含业务逻辑,这些业务逻辑只有少量的注解,没有多余的杂七杂八的东西、模式或间接依赖。

忘记以往的模块化概念,让代码保持简洁,小型化的WAR就是最好的模块。

总是假设微服务的基础设施会发生故障,并针对故障场景进行测试,提供最简单的解决方案(在类级别,而不是框架级别)。

InfoQ:是否有一些开发语言或技术可以推荐用于开发微服务?如果有,为什么?是否有一些是需要避免使用的?如果有,又是为什么呢?

Richardson:简而言之,微服务架构是独立于开发语言和框架的。不过有些经典的框架是基于某些语言开发的,这些框架可以用于构建分布式的应用。例如,Java开发者可以在Spring Cloud里使用Eureka/Ribbon来实现客户端的服务发现,也可以使用Hystrix的回路断路器。另外,也有人建议使用一些能够提供服务端发现的部署平台,这样开发者就不需要关注服务发现细节了。

Lewis:过去几年,人们更关注简单的事物,这是个好现象。我喜欢谈论Java的生态系统,那么就从Dropwizard和Spring Boot开始吧。我特别喜欢Dropwizard的设计思想,我记得关于它的宣传词是“一系列不那么糟糕的软件包”,相比那些重型框架,或许这些才是你需要的东西。在生态系统之外,我知道有很多团队在使用Go和Elixir,他们也很成功。不过我不能对JavaScript生态系统做任何评论,因为我对它并不了解。

Verburg:

  • microprofile.io、Vert.x、Spring Boot、JHipster对Java开发者来说都是很好的资源。在jClarity,我们使用了Vert.x,它是一种基于JVM的混合型语言,非常适合用于开发微服务,我极力推荐。

  • Scala开发者可以使用Akka。

  • JavaScript开发者可以使用NodeJS。

Posta:使用合适的东西可以帮助你走得更快。在我看来,Go、Java、.NET、NodeJS是最为常用的微服务开发语言。

在企业里,如果你需要将Java服务模块化,可以使用一些技术,比如Linux容器和像Dropwizard这样的“微框架”、WildFly Swarm和Spring Boot。如果要使用基于领域驱动的事件框架,那么像Vert.x这样的反应式框架是个不错的选择。其它的跟平台和应用相关的云服务技术,比如Kubernetes、Hystrix和Envoy可以用于解决复杂的分布式系统问题。

Bien: Java已经诞生20多年了,它是一门成熟的开发语言,具有强大的工具和监控能力。Java在一开始就融入了微服务概念,比如Jini/JXTA框架,它们与No-SQL数据库(比如JavaSpaces)混在一起。可以说,Java超前了15年,那个时候市场还没有做好使用这些技术的准备。不过,从1999年以来的那些技术在今天仍然适用。我们并没有重新发明轮子。

我经常会建议将Java EE的应用服务器(Payara、TomEE和Wildfly)作为初创项目的微服务平台。在最初的业务逻辑探索阶段,我们没有必要把时间浪费在这些事情上。在一开始我们要十分注重效率。开发人员会对现代应用服务器的开发效率、内存使用和内建特性感到惊讶。Java SE/EE内建的功能可以完成很多事情,这要超出开发人员的想象。目前我只看到正向的反馈。

Docker是另一个关键因素。Docker结合Java EE是最理想的组合。

InfoQ:你们认为2年之后微服务会有怎样的发展?

Richardson:谁知道呢?早在2012年4月,我做了一场关于当时微服务架构情况的演讲。到目前为止,微服务架构的核心概念并没有发生改变。不过我见证了技术上的巨大变化:比如Docker和AWS Lambda的崛起。所以,我们很难对此做出预言。不过话虽如此,我仍然希望微服务架构能够顺着Gartner的发展曲线一路进入平稳状态。

Lewis:我认为,将来有些公司会因此大赚一笔,而有些公司则在尝试了微服务之后仍然不明白其深层的意义,并给自己招来大麻烦。我希望能够出现一些很酷的工具,用于服务可视化、请求消息跟踪和更智能的故障检测。那样的话就太棒了!

Verburg:从趋势周期来看,曲线会先到达顶峰,然后再跌入谷底。有部分组织会沿着斜坡前进。

Posta:如果你不介意,我想重新组织一下你的问题:假设给微服务2年时间,那么它是否可以达到给面向服务架构4年时间所达到的相同状态?答案是肯定的。

不同之处在于,互联网公司和初创企业把技术作为抗击传统企业的主要武器(游戏规则已经发生了变化)。至于技术趋势,它跟面向服务架构不会有太多的不同。只是那些没有采用DevOps、敏捷和微服务的公司会落后于那些采用了这些技术的公司。

Bien:有个开发者在一个Java User Group会议上自豪地声称:“我的团队只有4个人,但我们交付了35个微服务”。还有个咨询顾问向我演示了他如何在笔记本上运行70个JVM实例。

我的问题是:“你们为什么要这么做?这样做给你们的服务带来什么好处了吗?”

我期望看到第一批言过其实的微服务项目会比预想的需要耗费更高的成本。这些项目在一开始成为一些文章或大会的谈资,但却降低了开发者的效率。

糟糕的大会把事情引向了另一个极端。我不知道以后会不会出现Macroservice或者Nanoservice。不过我可以肯定的是,它们只是新瓶装旧酒。

讨论总结

在这个虚拟研讨会里,我们了解了微服务当前的状态、微服务的最佳实践和一些关于微服务在未来几年发展情况的预言。我们从这些专家那里得到了关于如何成功实施微服务的各种技术建议,不过我们也要意识到,微服务架构是一种分布式系统,过去几十年的理论和实践经验深藏其中,等待开发者去发现。我们还了解了专家们关于将REST/HTTP作为微服务通信手段的看法,并将其与异步和消息服务进行了对比。

今日荐文

点击下方图片即可阅读

解决分布式系统的一致性问题,我们需要了解哪些理论?


34 岁华为技术员工的裁员风波;深圳的工程师在买房买车生娃的结点上突然告知被裁;创业公司在资金困难时找相对高薪的程序员开刀.....工作数年的技术该怎么走出这个囚徒困境?斯达克学院 StuQ ,特别邀请拥有 15 年软件行业从业经验的什马金融CTO汪晓明,给我们做知乎Live分享。他将结合自己的实际经历,引入「技术半衰期」和「资源稳定度」两个概念,帮助大家建立思考框架,瞄准自己的目标,不再彷徨,不再浪费时光。