Uber 工程师 Emily Reinhold 最近介绍了他们是如何将整体式 API 拆分为灵活的模块化微服务体系结构的。她重点介绍了在 Uber 的迁移工作中,设计和体系结构方面几个最重要的考虑。
根据 Reinhold 的介绍,迁移至微服务的主要目标在于在三个指标方面实现更好的缩放性:应对流量的激增,更轻松地增添新功能,以及转为使用一种在组织迅速增长的情况下能轻松适应规模变化的体系结构。
为了降低微服务之间的耦合,Uber 工程师在常规设计方面做出了一些决策:
- MVCS,对众所周知的模型 - 视图 - 控制器(Model-View-Controller)方法进行的扩展,可明确包含服务层并承载应用程序逻辑。这样 Uber 就可以在业务逻辑和持久层之间实现解耦,借此更容易地修改持久层。
- UDR,Uber 的全球复制数据存储,该技术取代了 PostgreSQL,使得 Uber 可以通过多个数据中心同时为用户提供乘车服务。
此外为了应对大量服务所造成的后续问题,Uber 工程师还对体系结构进行了一些重大更改:
- 异步网络:为了处理数量日益增加的服务请求,Uber 工程师通过一种基于 Python 事件环路(Event-loop)的异步网络库 Tornado 实现了同时缩放至数万个开放连接的能力。使用 Tornado 的优势之一在于该技术可与 Uber 现有的 Python 网络代码集成,借此构建结构化的异步范式。
- 服务的发现和弹性:面对数量激增的服务,关键在于要能发现服务并找出故障点。例如需要收集故障率和 SLA 违背等指标,检测运行状况不正常的主机,通过短路(Circuit breaking)防止连锁故障。Uber 通过 Hyperbahn 使用 TChannel 解决了这一问题,这是一种他们自行开发并已开源的,适用于 RPC 的网络多工(Multiplexing)和帧通讯协议。
- 严格的接口定义:Uber 选择使用 Thrift 通过 IDL 定义服务接口,并借此生成不同语言的客户端源文件。Thrift 使得他们能够检测出客户发起的,与接口定义规范不符的调用。
最后 Reinhold 还提到 Uber 会通过下列基本原则确保生产环境正常运行:
- 通过负载测试发现瓶颈和断点。
- 通过容器实现更高的硬件利用率。
- 通过模拟服务中断确保系统能够顺利恢复并发现可能存在的弱点。
Emily Reinhold 也曾在上一次纽约 QCon 活动中讨论过这些话题。
查看英文原文: Breaking a Monolithic API into Microservices at Uber
评论