微服务:真正的架构模式

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 本文讲的是微服务:真正的架构模式【编者的话】本文来自Medium,通过比较CRUD app和数据流app两种应用类型的微服务化探索来向听众介绍微服务。
本文讲的是微服务:真正的架构模式【编者的话】本文来自 Medium ,通过比较CRUD app和数据流app两种应用类型的微服务化探索来向听众介绍微服务。

简介

微服务的神秘和背后的知识令我着迷。微服务作为概念,它属于现代最有趣的架构之一。微服务应用广泛,涉及不同的使用场景。但也有很多地方模糊不清,难以定论。

人们在讨论微服务时,我会努力理解他们的真实意图。尽管在上一次演讲中我分享了对微服务的认识,但我很清楚其它公司和我们使用的架构是不一样的。最近我询问了一位同行,了解到他们部署微服务的方式(和我)不同。所以我打算通过比较这两种方式向技术大会的观众介绍微服务。

这篇文章会举两个例子。第一个是我上次演讲中的微服务例子,属于困难模式。第二个例子以流式架构实现微服务,在我了解的为服务使用场景中,它更接近微服务应用的“理想情况”。

微服务基础

我认为微服务作为架构由以下因素演进而来:
  1. 21世纪初,大量创业公司使用一门语言像rails,来快速扩展他们的业务和团队。遇到某些困难后,他们开始思考,可以用一门语言做哪些合理的事情。
  2. 云计算的发展让我们更便捷、简单地获得服务器实例运行软件。
  3. 我们都认可使用分布式系统架构,尤其是网络调用来解决问题。

伸缩调整、易于获取新硬件、分布式系统与网络,将这些因素结合起来,会发现它们在我提出的“microservice for CRUD”概念中作用巨大。如果你将一家公司拓展到将近成功的水平,但在技术/工程团队拓展上遇到麻烦。将庞大单一的管理拆分成service-style的架构会有很大帮助。这是我的亲身经历。

微服务的要点看起来像这样:
  • 服务支持独立伸缩。如果系统服务的一部分有高负荷或相对其它服务有高容量的需求,你可以扩展服务来满足需求。这在单一系统架构(译者注:比如说Java Web中把代码编译成一个war包发布)里可行,但是有时也会变得很复杂。
  • 服务允许在可控的范围内故障。在您系统中各个模块可独立操作的情况下,可以通过拆分成不同的服务来提高可用性。例如,一款商业app,如果产品的搜索流程崩溃,但是它仍然可以提供检测服务,这将是一件好事。可是实际操作起来比理论要复杂得多,并且人们对于微服务有许多愚蠢的认识,比如暗示服务重叠没有价值。通过设置实现可控的故障并不是必须的,但拥有它情况会好些,但让单一架构做到这一点(设置独立可控的故障域)并不容易。
  • 服务要能支持开发团队人员独立良好地工作在各自负责的模块。再次声明,这单一架构系统中你是可以做到的,因为我就做到了。但整体上的挑战(以及与monorepo(单个代码仓库)中服务相关的挑战)是,当这些“域(译者注:可理解为范围)”的概念以源代码呈现时,工程师要努力去理解理论上与实际编码上的区别。如果我能看到所有代码,并且它们可以编译在一起,就像是一个交付件(而不是各个服务单独拆分构建),我更趋向把它作为整体。这样我就可以从这里抓起代码在另一个地方使用,从那里获取数据在这里使用,等。

我还准备了一些笔记。人们经常弄混“Monolith”和“monorepo”。一个Monolith风格的应用是指把一组代码编译成单独的服务交付件(过程中可能会产生额外的客户端交付件)。你可以通过配置文件来让交付件做几乎任何你能想象的事情,包括上文所有的service-type,但是如果所有代码没有集中放到一个仓库中,这样做最后会生成很大的镜像,也会导致混乱,因为团队有时会根据不同的构建工具和配置文件编译生成不同的交付版本。我依然认为这种架构是单一架构。

Monorepo或者是monolith repository是一种模型,它指一个单一的代码仓库,包含了你正在编码的系统的所有代码(很可能还不包括OSS/外部依赖的源代码)。代码仓库中的代码由多个独立的应用交付件组成,这些代码都可以独立编译/打包和测试,不需要整个仓库的代码。monorepo的一个优势是,当修改了共享库的版本后,依赖共享库的开发人员可以更容易地开发,而不用去等其他团队更新依赖库的版本后再开发。monorepo模型最大的缺点是,支持它的OSS工具不多,因为大部分OSS工具不是这么构建的。所以需要大量投资开发新的工具来支持monorepo模型。

基于CRUD应用的微服务

在介绍CRUD应用由单一架构到微服务架构演进之前,我会先介绍构建中等规模CRUD平台所需的架构设计。这种平台有一个不错的用例,它涉及“事务”和“元数据”。

事务:指用户做了一个行为,你想把它持久化,这里数据的一致性最有价值。CRUD中的Create,Update,Delete操作频率比Read低得多。

元数据:描述用户的信息,但是只能由内部内容创建者修改,外部用户(比如审查者)很少能修改。通常具有很高的可缓存性。甚至有时能够容忍一定程度的临时不一致性(显示陈旧的数据)。

CRUD依赖型公司还有哪些能做的事呢,尤其是分析领域?当然有,你可能需要根据用户在浏览网站时的行为以及其它个性化的操作来频繁地调整结果。但是做到实时调整结果很困难,因为你不一定总是能从用户那里得到足够的数据来达到最好的效果,所以这(指上文调整结果)不是系统的一级关注点。

这种架构在迁移过程中是相对简单的:
  • 确定独立实体。这篇论文Life Beyond Txns有很多有趣又实用的定义。越早迁移架构越好,否则系统臃肿后不得不实现一个分布式事务。你可能希望拥有企业产品,用户等服务的数据,再集成其它面向企业的逻辑和聚合服务。
  • 从实体中抽象出逻辑,集成到服务实体中。尽可能不要去改变数据模型,并且通过重定向访问新的服务实体APIs。

基本上就这些了。你需要做的是收集足够的用户函数、数据和术语,然后改成微服务架构并开发新的功能。

这些服务不是典型的SOA,也不是很小的微服务。拥有数据的服务会更复杂。你可能不想要太多服务,因为你希望在满足用户请求的同时,不需要太多的网络跳转,甚至不需要分布式事务(理想情况)。

可能你不需要每天都开发新的服务,特别是当你有一个五十人的工程团队和一个长期的产品路线图时,你可能不会为了“点一下按钮就动态添加一个新的功能”而投入大量的工程时间到开发编排和工具上。

决定投入多少时间在工具上很简单:开发人员花费在自动添加新服务的时间VS实现和维护自动化程序的时间VS随着时间的推移,你希望添加多少新的服务?比较下它们就可以了。显然,如果你认为让人们能够快速频繁开发微小的服务很重要,你最好投入更多的时间和开发更多的工具。与所有工程优化决策一样,这样做不代表它完全正正确,但是在可预见的未来,它是正确的,而且我们还需要不断地重新评估。

在这个实例中,我发现有许多是微服务必须具备的。比如上文中我提到过很多次的编排。但是如果你不需要自动启动服务或频繁地迁移服务,你则不需要动态服务发现(如果需要的话,负载均衡器是一个不错的选择)。

允许团队为每个服务选择合适的语言、框架和数据存储也不是必须的。事实上,对于你的团队这样做可能是一个令人头疼的问题而不是福音。

为每个微服务创建单独的数据存储。
不要让所有微服务都使用同一个后端存储服务。因为使用单一的数据存储,不同团队编写的微服务就可以容易地共享数据库结构,也会减少许多重复的工作。但是,如果某个团队更新了数据库结构,使用该结构的其他服务也需要调整。
这是真实存在的,但是对于较小的团队,可以通过事先约定好规则来禁止共享数据库结构(如果还有顾虑,可以通过代码审查、自动测试和检测来预防)。如果你很仔细地定义数据相关的服务,不太可能发生这样的事情。另一种方法在下一段介绍:

将数据分离开,可能使数据管理更加复杂,因为分离的存储系统更容易脱离同步或变得不一致,外键也可能被意外更改。这时你就需要增加工具来执行主数据管理(MDM):后台检测然后修复数据不一致性。例如,它可以检测每个数据库的用户id,来验证所有数据库中的id是否一致(任何数据库中没有重复或多余的id)。你可以自己写工具或者买一个。许多商业版的关系型数据库管理系统(RDBMS)会执行这些类型检查,但是它们耦合性很高导致无法伸缩( 出处)。
上面这段可能令很多经验丰富的数据检测工程师失望(译者注:因为商业检测服务不支持伸缩,言下之意是要自己开发)。 正是由于数据检测的开销,我鼓励小型组织,在决定使用完全独立的数据存储或个人存储之前,要评估约定数据库共享的方法。决定最终使用何种数据存储服务是可以根据需要来推迟的。

这一版本的微服务架构在扩展CRUD应用方面令人期待,因为这种架构允许你分块重写代码。你可以重写整个系统,或者简单地修改对缩放最敏感的部分。你需要主动参与到涉及到分布式系统复杂性相关问题上,仔细思索数据和基于数据的事务。可能你不需要大量的数据管道,就知道哪里的数据需要修改。

我一定要用微服务来扩展这些吗?答案很可能是no,但是并不意味着使用微服务来扩展系统是一个坏的作法。但是使用极端的微服务模型可能是一个坏主意,因为你很可能不想以分布式事务的方式来切分你的数据。

基于数据处理流的微服务

现在我们讨论一个非常不同的使用案例。这个例子不是你们熟悉的CRUD应用,也不包含臃肿的企业规则和事务更新。相反,这个案例包含大量的数据流。它从不同的数据源接入许多小数据,小数据又汇聚成大量数据。不仅有大量的数据,还有大量的服务来消费、修改数据,或者存储起来以便进一步使用。

主要关注点是接收大量不断变化的数据,以各种方式处理它,并以合适的视图展示给客户。而这些在CRUD应用中是次要的。

我们以一个聚合度量(Metrics)信息的SaaS应用为例。这款应用的客户遍及世界,各种应用、服务、机器都将度量信息发送到聚合器。这些客户只需要查看他们的数据,虽然任何一个客户的数据总数可能非常大。我们的聚合器需要处理这些度量信息,并将它们发送到负责显示给客户的程序。面向客户的应用能够操作实时输入的数据以及来自缓存或者后端存储系统的历史数据。数据的最大价值在于数据在移动窗口内现在/最近都发生了什么。

这种架构从一开始就要考虑数据容量问题,而这在CRUD世界里可能很长时间都不用考虑。另外,数据本身是随着时间不断更新的。“有状态”的数据在事务上最小化更新,最有用的数据是时间序列或者事件日志。事务性的数据,比如存储用户视图、配置等,它们类似CRUD中的“元数据”,与流数据相比很少改变。开发者的时间大部分用于管理输入流、提供新的输入类型、对输入流进行计算或者改变计算方式,而不是处理事务性数据的变更(CRUD)。

本例中,你可以假设一个服务,想要通过对数据流上的特定元素执行不同的计算来进行实验。不修改现有的代码,实验性服务选择一个时间点开始监听数据流,执行新的计算得到新的结果,然后将结果推送回数据流的不同信道上。某一时刻,实验程序从实验客户那提取数据,然后将实验计算结果而不是标准结果返回给客户。你需要记录所有步骤,用于实验完整与调试分析,不要求记录非常详细或者是系统事件甚至用户相关的事务性信息。

本例中,为了更快运行实验程序,编写新的代码可能比更改原有的服务代码更简单。特别是新开发的服务不需要担心调整数据消耗或者与现存服务的计算结果冲突。这就是我所说的“以数据流为中心的微服务”。

如果管理实时数据流给你的企业带来巨大的价值,并且你有非常多的开发者,要创建新的服务来消耗数据流、检测数据和产生结果,你肯定愿意投资开发新工具来尽可能简化服务创建和生产环境部署。你会慢慢把工具应用到所有服务上。但是你也要清晰地认识到,拥有可独立操作和实验的动态数据是微服务化的关键。

Cron job作为微服务

如果没有提到这一点将是我的疏忽。当一切微服务化非常容易时,自然也包括传统的cron job微服务化。

cron job是很好的概念,它没有把一切都视作“服务”。你可以用AWS的CloudWatch Events或者是调度Lambda函数实现这个目的(将cron job微服务化)。也可以使用Gearman调度cron job,它是一个支持队列和异步作业的运行程序。注意你的cron job必须幂等(同一个输入运行两次结果不变)。如果你有更简单的方法运行服务或者是基础的cron job,那没问题(你不需要微服务化)。

结论

我希望这篇文章能在微服务世界中带来多维度的突破。不断思考和尝试对我个人非常重要。它帮助我以极端的角度去理解人们习惯的事情。我指的是把大量时间用于流数据处理与把时间用在CRUD应用弹性伸缩这两个角度。

原文连接:Microservices: Real Architectural Patterns(翻译:adolphlwq)

=========================================
译者介绍

adolphlwq,博客地址:QuanTalk

原文发布时间为:2016-12-13

本文作者:adolphlwq

本文来自云栖社区合作伙伴Dockerone.io,了解相关信息可以关注Dockerone.io。

原文标题:微服务:真正的架构模式

相关文章
|
11天前
|
API 数据库 开发者
构建高效可靠的微服务架构:后端开发的新范式
【4月更文挑战第8天】 随着现代软件开发的复杂性日益增加,传统的单体应用架构面临着可扩展性、维护性和敏捷性的挑战。为了解决这些问题,微服务架构应运而生,并迅速成为后端开发领域的一股清流。本文将深入探讨微服务架构的设计原则、实施策略及其带来的优势与挑战,为后端开发者提供一种全新视角,以实现更加灵活、高效和稳定的系统构建。
18 0
|
25天前
|
负载均衡 测试技术 持续交付
高效后端开发实践:构建可扩展的微服务架构
在当今快速发展的互联网时代,后端开发扮演着至关重要的角色。本文将重点探讨如何构建可扩展的微服务架构,以及在后端开发中提高效率的一些实践方法。通过合理的架构设计和技术选型,我们可以更好地应对日益复杂的业务需求,实现高效可靠的后端系统。
|
25天前
|
监控 持续交付 API
构建高效可扩展的微服务架构
在当今快速迭代和竞争激烈的软件市场中,构建一个高效、可扩展且易于维护的后端系统变得尤为重要。微服务架构作为一种流行的分布式系统设计方式,允许开发者将应用程序划分为一系列小型、自治的服务,每个服务负责执行特定的业务功能。本文将探讨如何利用现代技术栈搭建一个符合这些要求的微服务架构,并讨论其潜在的挑战与解决方案。我们将涵盖服务划分策略、容器化、服务发现、API网关、持续集成/持续部署(CI/CD)以及监控和日志管理等关键主题,以帮助读者构建出既可靠又灵活的后端系统。
|
27天前
|
监控 Kubernetes 持续交付
构建高效可扩展的微服务架构:后端开发实践指南
在数字化转型的浪潮中,企业对软件系统的要求日益提高,追求快速响应市场变化、持续交付价值成为核心竞争力。微服务架构以其灵活性、模块化和独立部署的特点,成为解决复杂系统问题的有效途径。本文将深入探讨如何构建一个高效且可扩展的微服务架构,涵盖关键设计原则、技术选型及实践案例,为后端开发者提供一条清晰的指导路线,帮助其在不断变化的技术环境中保持竞争力。
128 3
|
9天前
|
Kubernetes 安全 Java
构建高效微服务架构:从理论到实践
【4月更文挑战第9天】 在当今快速迭代与竞争激烈的软件市场中,微服务架构以其灵活性、可扩展性及容错性,成为众多企业转型的首选。本文将深入探讨如何从零开始构建一个高效的微服务系统,覆盖从概念理解、设计原则、技术选型到部署维护的各个阶段。通过实际案例分析与最佳实践分享,旨在为后端工程师提供一套全面的微服务构建指南,帮助读者在面对复杂系统设计时能够做出明智的决策,并提升系统的可靠性与维护效率。
|
20天前
|
存储 监控 Kubernetes
探索微服务架构下的系统监控策略
在当今软件开发领域,微服务架构因其灵活性、可扩展性和容错性而日益受到青睐。然而,这种架构的复杂性也为系统监控带来了新的挑战。本文旨在探讨在微服务环境下实现有效系统监控的策略,以及如何利用这些策略来确保系统的健壮性和性能。我们将从监控的关键指标入手,讨论分布式追踪的重要性,并分析不同的监控工具和技术如何协同工作以提供全面的系统视图。
|
20天前
|
监控 Java 开发者
构建高效微服务架构:后端开发的新范式
在数字化转型的浪潮中,微服务架构以其灵活性、可扩展性和容错性成为企业技术战略的关键组成部分。本文深入探讨了微服务的核心概念,包括其设计原则、技术栈选择以及与容器化和编排技术的融合。通过实际案例分析,展示了如何利用微服务架构提升系统性能,实现快速迭代部署,并通过服务的解耦来提高整体系统的可靠性。
|
26天前
|
消息中间件 敏捷开发 运维
构建高效可靠的微服务架构:策略与实践
随着现代软件开发的复杂性增加,微服务架构逐渐成为企业解决大型应用系统分解、敏捷开发和持续部署问题的有效手段。本文深入探讨了构建一个高效且可靠的微服务架构的关键策略,包括服务的合理划分、通信机制的选择、数据一致性保障以及容错处理。通过分析这些策略在具体案例中的应用,我们旨在为开发者提供一套可行的微服务设计及实施指南。
130 6
|
26天前
|
监控 数据管理 API
构建高效微服务架构:后端开发的新趋势
在现代软件开发领域,随着业务需求的不断复杂化以及敏捷迭代的加速,传统的单体应用架构逐渐暴露出其局限性。微服务架构作为一种新的解决方案,以其高度模块化、独立部署和可扩展性,正成为后端开发领域的新趋势。本文将探讨微服务架构的核心概念,分析其优势与面临的挑战,并提供实施高效微服务的策略和最佳实践,帮助读者理解如何利用这一架构模式提升系统的可靠性、灵活性和可维护性。
135 5
|
2天前
|
负载均衡 Java 开发者
细解微服务架构实践:如何使用Spring Cloud进行Java微服务治理
【4月更文挑战第17天】Spring Cloud是Java微服务治理的首选框架,整合了Eureka(服务发现)、Ribbon(客户端负载均衡)、Hystrix(熔断器)、Zuul(API网关)和Config Server(配置中心)。通过Eureka实现服务注册与发现,Ribbon提供负载均衡,Hystrix实现熔断保护,Zuul作为API网关,Config Server集中管理配置。理解并运用Spring Cloud进行微服务治理是现代Java开发者的关键技能。