从Uber微服务看最佳实践如何炼成?

博主推荐 : 掘金是一个面向程序员的的技术社区,从 后端到架构,从Spring教程到开源库,无论是入门还是进阶,来掘金你不会错过后端开发的任何一个技术干货。

导读:Uber成长非常迅速,工程师团队快速扩充,据说Uber有2000名工程师,8000个代码仓库,部署了1000多个微服务。微服务架构是Uber应对技术团队快速增长,功能快速上线很出色的解决方案。本文偏向微服务的入门篇,以Uber微服务为例,进行了深入浅出的讲解。

微服务特性

对于微服务没有适当的定义,你可以说它是一个框架,由小型的、独立的可部署的服务组成,执行不同的操作。

微服务专注于单个业务领域,可以作为完全独立的可部署服务,并在不同的技术栈上实现它们。

单体架构和微服务架构区别

在使用微服务构建自己的应用程序之前,需要清楚地了解应用程序的范围和功能。

微服务特性

  • 解耦 - 系统内的服务在很大程度上是解耦的。因此,整个应用程序可以轻松构建,更改和缩放
  • 组件化 - 微服务被视为独立的组件,可以轻松替换和升级
  • 业务能力 - 微服务非常简单,专注于单一功能
  • 自治 - 开发人员和团队可以独立工作,从而提高速度
  • 持续交付 - 通过软件创建,测试和批准的系统自动化,允许软件的频繁发布
  • 责任 - 微服务不像项目那样专注于应用程序。相反,他们将应用程序视为他们负责的产品
  • 分散治理 - 重点在于使用正确的工具来完成正确的作业。这意味着没有标准化模式或任何技术模式。开发人员可以自由选择最有用的工具来解决他们的问题
  • 敏捷 - 微服务支持敏捷开发。任何新功能都可以快速开发并再次丢弃

微服务优势

  • 独立开发 - 所有微服务都可以根据各自的功能轻松开发
  • 独立部署 - 基于各自的服务,可以单独部署在任何应用程序中
  • 故障隔离 - 即使应用程序的一项服务不起作用,系统仍会继续运行
  • 混合技术堆栈 - 可以使用不同的语言和技术来构建同一应用程序的不同服务
  • 细粒度缩放 - 各个组件可根据需要进行扩展,无需将所有组件扩展到一起

微服务设计最佳实践

在当今世界,复杂性已经渗透到产品中。微服务架构能够更好地保持团队的规模和功能。

以下是微服务设计的最佳实践:

现在,让我们来看一个用例来更好地理解微服务。

案例:购物车应用程序

当打开购物车应用程序时,你看到的只是一个网站。但是,在幕后,购物车应用程序有接受支付服务、顾客服务等等。

假设开发人员已经在一个整体框架中进行了创建。如下图:

购物车应用程序的整体框架

所有功能都放在一个代码库中,并在一个底层数据库下。

现在,假设市场上出现了一个新品牌,开发人员希望将这个品牌的所有细节都放在这个应用程序中。

他们不仅要重新为新标签提供服务,还必须重新构建完整的系统并进行相应部署。

为了应对这种挑战,开发人员决定将其应用程序从单体架构转移到微服务。如下图:

购物车应用程序的微服务架构

这意味着开发人员不必创建Web微服务,逻辑微服务或数据库微服务。相反,他们为搜索,推荐,客户服务等创建单独的微服务。

这种应用架构不仅有助于开发人员克服以前架构面临的挑战,还有助于轻松构建,部署和扩展购物车应用程序。

微服务设计指南

  • 作为开发人员,决定构建应用程序时,要将各个域分离,并在功能上明确。
  • 设计的每一个微服务都只专注于应用中的一个服务。
  • 确保设计的应用程序使每个服务都可以单独部署。
  • 确保微服务之间的通信是通过无状态服务器完成的。
  • 每一项服务都可以被推进到更小的服务中,拥有自己的微服务。

在设计微服务时,已经了解了基本的指导方针,现在来了解一下微服务的架构。

微服务架构是如何工作的 ?

一个典型的微服务架构(MSA)应该包括以下组件:

  1. 客户端
  2. 身份提供者
  3. API网关
  4. 消息格式
  5. 数据库
  6. 静态内容
  7. 管理
  8. 服务发现

如下图:

微服务架构

这个架构看起来有点复杂,让我们来简化一下。

1、客户端

架构始于不同类型的客户端,从不同的设备尝试执行各种管理功能,如搜索、构建、配置等。

2、身份提供者

这些来自客户端的请求将传递给身份提供者,这些提供者对客户端的请求进行身份验证,并将请求传递给API网关。然后,请求通过定义良好的API网关与内部服务通信。

3、API网关

由于客户端不直接调用服务,因此API网关作为客户端将请求转发到适当的微服务的切入点。

使用API网关的优点包括:

  • 所有服务都可以在客户端不知情的情况下进行更新。
  • 服务也可以使用非网络友好的消息传递协议。
  • API网关可执行跨切割功能,如提供安全性、负载均衡等。

在接收到客户端的请求后,内部架构由微服务组成,这些微服务通过消息相互通信来处理客户端请求。

4、消息格式

有两种类型的消息通过它们进行通信:

  • 同步消息:在客户端等待服务响应的情况下,微服务通常倾向于使用REST (Representational State Transfer),因为它依赖于无状态、客户端服务器和HTTP协议。这个协议被用作一个分布式环境,每个功能都用一个资源来表示,以执行操作。
  • 异步消息:在客户端不等待服务响应的情况下,微服务通常倾向于使用AMQP、STOMP、MQTT等协议。这些协议在这种类型的通信中使用,因为消息的性质被定义,这些消息在实现之间可以互操作。

下一个问题是,使用微服务的应用程序如何处理数据?

5、数据处理

每个微服务都拥有一个专有数据库来捕获它们的数据并实现相应的业务功能。此外,微服务的数据库只通过其服务API进行更新。参考下图:

微服务处理数据演示

微服务提供的服务被转发到任何支持不同技术栈的进程间通信的远程服务。

6、静态内容

在微服务内部进行通信后,将静态内容部署到基于云的存储服务,通过内容交付网络(CDN)直接将其交付给客户端。

除了上述组件,还有一些其他组件出现在典型的微服务架构中。

7、管理

该组件负责平衡节点上的服务和故障识别。

8、服务发现

用作微服务的指南,以找到它们之间的通信路由,由它维护节点所在的服务列表。

现在来看看这个架构的优缺点,以更好地理解何时使用这种架构。

微服务架构优缺点

微服务架构的优点 微服务架构的缺点
自由使用不同的技术 增加故障排除难题
每个微服务都关注单一业务能力 由于远程呼叫而增加延迟
支持单独的可部署单元 增加配置和其他运营工作量
允许频繁的软件发布 难以保持交易安全
确保每项服务的安全性 很难跟踪各种服务边界的数据
并行开发和部署多个服务 服务之间很难移动代码

下面来比较一下UBER之前和现在的架构。

Uber微服务案例

Uber之前的架构

像许多初创公司一样,UBER在开始之初在单一城市运营,为单一产品打造了单体架构。当时有一个代码库似乎被清理了,并解决了UBER的核心业务问题。然而,随着UBER在全球范围内扩张,它们在可扩展性和持续集成方面面临各种各样的问题。

UBER的单体架构

上图描述了UBER之前的架构。

  • 与乘客和司机连接的REST API。
  • 三种不同的适配器与API一起使用,当预定出租车时,执行诸如账单、付款、发送电子邮件/消息等操作。
  • MySQL数据库存储所有数据。

因此,可以发现这里所有的特性,比如乘客管理、计费、通知功能、支付、行程管理和驱动管理都是在一个框架内完成的。

问题陈述

当Uber开始在世界范围扩张时,这种框架引入了各种各样的挑战。以下是一些突出的挑战。

  • 所有的功能都必须重新构建、部署和测试,以更新单一功能。
  • 在单个存储库中修复bug变得非常困难,因为开发人员不得不一次又一次地修改代码。
  • 在全球范围内引入新功能的同时,要将这些特性进行扩展是相当困难的。

解决方案

为了避免此类问题,Uber决定改变自己的架构,效仿亚马逊(Amazon)、Netflix、Twitter等其他超级增长公司。因此,Uber决定将其整体架构拆分为多个代码库,以形成一个微服务架构。

参考下面的图表,看看Uber的微服务架构。

Uber的微服务架构

  • 我们在这里看到的主要变化是引入了API网关,所有的司机和乘客都是通过这个网关连接的。从API网关,所有的内部点都连接在一起,如乘客管理、司机管理、行程管理等。
  • 每个单元是单独的可部署单元,执行单独的功能。例如:如果你想在账单微服务中更改任何内容,那么只需部署账单微服务,而不必部署其他服务。
  • 所有的功能都是单独扩展的,即每个特征之间的相互依赖被移除。

例如,我们都知道,搜索出租车的人数比预订出租车和付款的人要多。这就得到了一个推论:在乘客管理微服务上工作的流程的数量超过了处理支付的流程的数量。

通过这种方式,Uber将其架构从单一业务转移到微服务中获益。

原文链接:

本文作者:数人云
原文链接:https://mp.weixin.qq.com/s/-xaC4icfGh1T047-oBCDlQ
版权归作者所有,转载请注明出处