`

[转]REST 是微服务中最好的架构吗?

阅读更多

REST 是微服务中最好的架构吗?

【编者的话】本文作者Craig Williams通过人们对微服务误解切入,探讨了微服务的各种架构,最终给出开发者的启示是根据自己的业务逻辑,构建适合自己的微服务架构。

在我的微服务的旅程中,明显表明大多数关于在线样例/如何类的文章只专集中在REST作为微服务相互通讯的手段。正是因为如此,你可能会误认为REST风格的微服务时事实的标准,并努力使用这种方法设计和实施一个基于微服务的系统。事实并非如此。

REST

基于REST服务的例子这么流行不仅仅因为它们的简单,服务直接通讯和在http之上的相互同步,而且因为它们不需要任何额外的底层架构。
比如考虑一个通知客户特定产品库存的系统。这可以通过RESTful实现如下:
rest-flow.png

  1. 一个外部实体发送一个清单更新请求到一个REST网关地址。
  2. 网关转发这个请求给清单管理服务。
  3. 清单管理服务基于它接收的请求做清单的更新然后发送一个请求给后端库存通知服务。
  4. 后台库存通知器发送一个请求给订阅管理器,请求所有的注册条目已经存储在后台库存中的用户。
  5. 接着emails通过email服务会轮流给每个用户发送一个email REST请求。
  6. 每个服务则依次进行响应,退绕回网关并返回结果给客户端。

应当指出的是,尽管通信是点至点,硬编码的服务地址将是一个非常糟糕的设计选择,这极大违背了微服务的设计初衷。至于服务发现机制的使用,像Eureka 或者 Consul,它们机制是服务注册它们可用的API到一个中心的服务器上,然后客户端请求一个指定的API从这个服务器。

更深入讨论,在这种方式的实现上,也有一些底层的缺陷或事情需要考虑。

阻塞

由于REST的同步的特性,更新库存操作将不返回,直到通知服务已完成通知所有相关客户的任务。想象一下这样做的效果,若果一个特定的产品非常受欢迎,别的库存的客户希望1000s被通知到。性能可能被严重影响并且可扩展性将会受到阻碍。

单一和耦合模式

‘当一个产品到货,客户应当被通知’的认识被根深蒂固的认为应当由清单管理服务来做,但是我不这样认为。该服务的单一职责应及时更新系统库(库存的合并),别无其他。事实上,它不应该甚至不需要了解通知服务的存在。这两个服务紧密的耦合在这个模型中。

服务何时发布

未来服务失败时,在这些情况下,基于系统的微服务应该继续尽可能的发挥作用。由于上面描述的系统是紧耦合的,库存管理内部需要一个故障策略处理方案(比如)告知后台库存通知器实在哪里不可用。可能是库存更新失败?可能是服务重试?同样重要的是,请求到通知的失败应尽可能快,一些断路器模式(例如Hystrix)会对此有所帮助。尽管在失败的情况下将考虑通信的方法来处理,然而把所有逻辑封装到调用服务将会使调用服务变得臃肿。说回单个服务负责的问题,我的意见是不应该由清单管理负责处理,清单管理负责处理只会使通知器变黑。

管道

克服服务紧耦合的一个方法是把负责的程序从一个微服务移动到如下的企业模式的管道。我们的子系统现在是这样的:
pipeline-flow.png

通信可能一直是基于REST的,但是不在是点到点的;它现在是管道实体来编排的数据流,而不是服务本身负责。这克服了耦合的问题(通过一部管道,阻塞一些工作),它被认为是微服务通讯中的好的做法,尽可能争取服务的独立和一致性。采用这种方法,这些服务实体必须依靠第三方实体(管道编排),以便作为一个系统运行,因为没有特别的自给自足。

比如,通知管道将接受一个单独相应从后台订单通知器(即使有两个订阅者),但是必须配置这样一种方式,它可以解析响应,以便随后它可以为每个订阅者发送单个‘发送邮件’请求到邮件通知器。可以这样认为,电子邮件发送者可以通过单个请求批量修改发送邮件给许多不同的订阅者,但是如果以此为例,每一个用户名必须包括邮件体并且还要有某种令牌替换功能。在通知器有特定的知识关于邮件发送者的地方引入了额外的耦合行为。

异步消息

在一个基于消息传递系统中,来自服务的输入和输出都被定义为命令或者事件。每个服务订阅它们感兴趣的消耗事件,然后当事件通过其他服务被放到队列后,它通过一个机制像消息队列/代理可靠地接收事件。
通过这种方法,库存通知子系统现在能被重构如下:
mq-flow.png

通过队列名的共享信息获得凝聚力,并且提供一致的和众所周知的命令/事件格式;一个被事件或命令触发的服务应该能够被订阅服务消耗。在这个架构中,获得了很大的处理灵活性,服务的隔离性和自治性。

拿库存编目管理来说,它有一个单一的职责,仅仅负责更新编目,一旦它完成它执行的任务就不去关心别的触发的服务。因此附加服务可以增加消耗库存更新的事件,而无需修改清单管理服务,或任何管道编排器。

此外,它真的不关心(或者有任何的信息)是否早在后台订单通知之前已经死于可怕的死亡;库存已经更新,这对于库存管理而言这是一个出色的工作。对于库存管理服务故障的这种遗忘其实是一件好事;我们必须有一个处理后台通知器失败的方案,但是正如我之前说过的,可以说这不是库存管理本身的责任。

当设计一个基于系统的微服务时需要考虑的最重要的两件事是处理交易如添加,移除或修改服务不影响别的服务的操作或代码,以及适当的处理压力比如服务的失败。

但是在异步消息传递的世界上的一切并非完美无缺,目前仍有一些缺陷需要考虑:

设计/实现/配置困难

和同步编程模型比较起来异步编程模型通常更加复杂,这使得异步编程模型设计和实现起来更加复杂。这是因为有许多可能必须克服额外的问题,如消息排序,重复消息和消息幂等性。另外,消息代理的配置也需要一些考虑。例如,有相同服务的多个实例,那么消息被传递到两个服务或者仅仅只传递一个?两种方案都有使用案例。

异步消息的性质

未立即返回一个动作的结果的事实也可以增加的系统和用户界面设计的复杂性,在某些情况下它甚至不能清晰的划分逻辑的意义对于工作在异步方式的子系统。拿后台库存通知器为例,他和订阅管理的关系,如果没有没有关于订阅者应该被通知的消息它是不可能正常工作的,因此在这种情况下一个同REST调用才有意义。这和邮件发送任务是不同的,因此不需要直接发送邮件。

消息流的可视化

由于基于微服务的消息传递的分散和自治性,它很难获得一个完全的清晰的消息流图在系统内部。和管道的方法比起来,这使得调试起来更加困难,并且系统的业务逻辑也很难管理。

注意:基于时间的消息机制可以进一步扩展通过应用事件源和CQRS模式,但是这超出了本文的讨论范围。可以查看链接获取更多信息。

因此在设计微服务的时候哪种通讯方法是最好的?这与软件开发(和周期?)的大多数事情是一样的,取决于具体的需求!如果一个微服务实际需要同步响应,或者如果它自己需要接受一个同步响应,那么REST可能也就需要采用同步通讯方法。如果一个企业要求通过系统的消息流容易被监控和审计,或者考虑到能够修改和查看消息流从一个中心化的地方的优势,那么就可以考虑采用一个管道。但是异步基于系统的异步消息拥有松耦合和扩展的特性非常符合微服务的总体精神。通常情况下,尽管有一些显著的设计和实施的障碍,一个基于事件的消息传递方式将根据在微服务为基础的系统默认的通信机制作出决定时是一个不错的选择。

更多阅读


原文链接:is-rest-best-microservices(翻译:乔要周)

译者介绍
乔要周,目前就职于Allianz,sensior application administrator 崇尚开源精神,特别痴迷Docker。
转自: http://dockone.io/article/952
分享到:
评论

相关推荐

    Java微服务架构163课

    全套微服务架构,视频学习java微服务架构,包括如下 第1章 微服务简介 001构建单体应用 002微服务解决复杂问题 003微服务的优点 004微服务的缺点 第2章 Linux使用 005Linux 简介 006Linux 与 Windows ...

    1.微服务架构1

    介绍的:服务网关。服务网关是微服务架构中一个不可或缺的部分。通过服务网关统一向外系统提供REST API的过程中,除了具备服务路由、均衡负载功能之外,它还具备了

    基于springboot和docker部署的微服务架构.zip

    基于springboot和docker部署的微服务架构.zip j360系列之spring-boot微服务架构和docker部署 ##介绍## j360-order底层服务提供接口 使用restAPI提供服务 j360-deliver提供UI操作界面,调用底层j360-order提供服务 ...

    Java微服务架构l零从基础到精通高清视频教程全套 163课

    Java微服务架构l零从基础到精通高清视频教程全套 第1章 微服务简介 001构建单体应用 002微服务解决复杂问题 003微服务的优点 004微服务的缺点 第2章 Linux使用 005Linux 简介 006Linux 与 Windows 比较 007...

    基于微服务架构的平台化服务框架的设计与实现

    的不足,国内外互联网企业探索通过微服务架构方式,优化系统服务化的构建和 管理。微服务架构去中心化、高度自治、自动化等特点进一步对系统架构进行解 耦,并且和敏捷迭代、DevOps文化更加契合,可以使用较低的成本...

    《微服务架构设计模式》之三:微服务架构中的进程间通信

    服务可以使用基于同步请求/响应的通信机制,例如HTTPREST或gRPC。另外,也可以使用异步的基于消息的通信机制,比如AMQP或STOMP。消息的格式也不尽相同。服务可以使用具备可读性的格式,比如基于文本的JSON或XML。也...

    电子商务微服务:具有Spring Boot,云和多个模块的REST微服务架构,用于电子商务

    在具有Spring Boot,Cloud和多个模块的电子商务中实现REST微服务。 (作者:卡米尔·莱斯尼亚科夫斯基PL) 目录 项目架构 工具与技术 Java 8 Spring Boot-版本2.1.5发行 Spring Web MVC-版本5.1.7发行 Spring ...

    java微服务架构

    软件开发者想要往软件设计与架构精进的路线及选型。 ``` hikaru-server/ .idea hikaru-api | conrtoller - rest服务 hikaru-application | application - springboot 启动 hikaru-common | common - 基础应用抽...

    Java高并发高性能分布式框架从无到有微服务架构设计.doc

    Java高并发高性能分布式框架从无到有微服务架构设计 Java高并发高性能分布式框架从无到有微服务架构设计 微服务架构模式(Microservice Architect Pattern)。近两年在服务的疯狂增长与云计算技术的进步,让微服务...

    Microservices:使用Django实现微服务架构的简单项目

    微服务 使用Django实现微服务架构的简单项目

    基于SpringCloud完整的微服务架构实战

    Springboot-微服务的入门级微框架,用来简化Spring应用的初始搭建以及开发过程。Eureka-云端服务发现,一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。SpringCloudConfig-配置管理工具包,...

    网易蜂巢微服务架构:用RabbitMQ实现轻量级通信

    本次分享内容由三个部分组成:微服务架构与MQRabbitMQ场景分析与优化RabbitMQ在网易蜂巢中的应用和案例分享微服务架构是一种架构模式,它将单体应用划分成一组微小的服务,各服务之间使用轻量级的通信机制交互。...

    HZQ-Cloud:微服务开源项目架构

    微服务开源项目架构 项目演示地址: 平台服务结构 hzq-cloud-dependencies 通用依赖管理 hzq-cloud-gateway : 9000 网关 hzq-cloud-registry 服务注册中心( 目前支持nacos) registry-nacos:8848 支持 nacos 注册中心 ...

    微服务预习文档.pdf

    微服务(或称微服务架构)是一种云原生架构方法,在单个应用中包含众多松散耦合且可单独部署的小型组件或服务。 这些服务通常拥有自己的技术栈,包括数据库和数据管理模型;通过一个REST API、事件流和消息代理组合...

    nestjs-rest-microservices:使用NestJS框架构建的带有gRPC后端微服务的REST API。 仅用于学习和样板目的

    架构概述REST API充当其公开的不同微服务的网关/代理。 REST API的控制器调用后端的gRPC服务器/微服务。 然后,gRPC微服务会处理请求以连接到数据库或它为服务请求所需的任何其他服务。图表架构图如下所示。设计模式...

    GraphQL在微服务架构中的实践

    SOAP的接口,但是到今天REST风格的面向资源的API接口已经非常深入人心,也非常的成熟;但是这篇文章要介绍的主角其实是另一门更加复杂、完备的查询语言 GraphQL。作为Facebook在2015年推出的查询语言,GraphQL能够对...

    OnlineStore:使用微服务架构的在线商店的REST API

    该项目由使用微服务架构的在线商店的REST API组成。 这个项目的目标是利用我在8个月的过程中以自学成才的方式所获得的所有知识,为在线商店创建一个完整的业余应用程序。 微服务 产品服务微服务,负责产品管理。 ...

Global site tag (gtag.js) - Google Analytics