QCon 全球软件开发大会(北京站)门票 9 折倒计时 4 天,点击立减 ¥880 了解详情
写点什么

正确设计微服务架构:Michael Bryzek 在纽约 QCon 上的演讲

2018 年 6 月 30 日

在 2018 年纽约 QCon 大会上,Michael Bryzek 讨论了如何“以正确的方式”设计微服务架构。关键要点包括:应该先为所有 API 和事件设计模式,这样就可以自动生成样板代码代码;优先使用事件流订阅,而不是直接调用 API;应该在自动化方面进行投入,例如自动化部署和依赖管理;工程团队必须专注于编写简单有效的测试,因为这样可以提高质量、简化维护任务并实现持续交付。

Flow.io 的联合创始人、董事长兼首席技术官 Bryzek(之前是 Gilt 的联合创始人)在演讲开始时分享了自己经历过的一个故事。当时他们要将一个系统内的 URL 从“foo.com/latest/bar.js”改为“foo.com/1.5.3/bar.js”,却收到反馈说“需要几周的时间”,而且团队中已经没有足够的资源可以完成这项任务。为什么如此简单的一个 URL 格式变更需要这么大的工作量?带着这个疑惑,他发现,URL 是在一个库中实现的,这个变更涉及了几百个依赖服务,其中有一些已经几年没有更新过,为了重新构建和部署这些服务,需要其他的依赖项也做出更新。

这个故事很明显可以作为“不那么伟大的架构”的一个例子,为了眼前的开发速度,却换来了未来的瘫痪。相比之下,一个伟大的架构应该有助于扩展开发团队,带来更高的质量和更高的性能,并降低成本,同时能够很自然地为未来的特性提供支持。微服务架构是一种非常流行的现代系统实现方式,但它需要正确的设计方式;工程师应该努力不要把它设计成“意大利面”系统,而是寻求“分层”的方法。

接下来,Bryzek 提出了一系列对微服务的常见误解。第一个误解是“微服务能够让团队选择符合他们任务的编程语言和框架”。而实际情况是,这可能需要付出很高的代价,为了在技术栈中支持额外的开发语言,团队规模和投入成了关键的输入。

如果我们将 Google 视为一家优秀的工程公司,他们拥有大约 20,000-30,000 名工程师,使用了至少 8 种编程语言。那么可以说,每 4000 名工程师采用了一种编程语言。

第二个误解是“代码生成是邪恶的”。而现实情况是,“定义 100%受信任的模式”对于资源和事件来说非常重要,因为这个时候生成代码对于扩展开发和维护工作来说非常有用。第三个误解,“事件日志一定是事实来源”,而现实情况是,事件是接口的关键部分,但“将服务作为资源的记录系统是没有问题的”。最后一个误解是“每个开发人员维护的服务不应该超过三个”,在实际当中,这个数字可能是错误的。Bryzek 表示,这是“自动化发挥作用”的地方,Flow.io 的开发人员每人维护大约五个服务,每周用于维护的时间不到 5%。

接下来,Bryzek 介绍了 Flow.io 的架构。他们的架构使用了基于 JSON 的面向资源的 API 模式,可以对实体和相应属性进行定义,并带有适当的元数据。模式定义文件保存在 Git DVCS 中,并启用了持续集成。他们通过一系列测试保证整套 API 的一致性,并将这些测试作为高级的 linter。这些测试的目标是让工程师相信“整套 API 是由一个人写出来的”。

工程团队使用了开源的 apibuilder.io 工具,并结合他们的测试来防止出现错误,并在 API 设计阶段验证可能发生的重大变更。apibuilder 的 CLI 工具可用于生成和更新与资源 API 和路由相关的代码。API 客户端的代码也可以自动生成,其中包括用于高保真和快速测试的模拟客户端。Bryzek 表示,在 Flow.io 的架构中,记录系统是 API 规范,代码生成可以确保团队“遵循规范”。

接下来讨论了数据库架构。有人建议每个微服务应该要有自己的数据库,并且不允许其他服务直接连接到此数据库,其他服务应该使用服务接口来访问不属于自己的数据库,服务接口由 API 和事件流组成。 Flow.io 工程团队花了很大精力创建 CLI “dev” 工具,用来管理所有的基础设施和常见的开发任务。创建数据库只需要一个命令就可以完成。所有的存储需求通过 JSON 模式来定义,虽然 JSON 模式与相关的 API 模式是相互独立的,但使用的是相同的工具链。数据库 DDL 操作和配置(例如创建表)是自动生成的,相关的应用程序服务客户端数据访问对象(DAO)代码也是如此。这样不仅标准化了对数据库的访问,而且确保了从一开始就有适当的索引。

后续的演示侧重于代码部署。创建相关的 Git 标签就会触发部署,而 master 分支上发生变更(例如拉取请求的合并)时就会自动创建这些标签,并且是“100%自动化,100%可靠”的。Bryzek 演示了 Flow.io 的持续交付管理系统“ delta ”(代码可在 GitHub 上获得),并强调了这种做法的重要性。

持续交付是微服务架构的先决条件。

微服务基础设施的定义要尽量保持简单,并使用单个 YAML 文件来定义元数据,其中包含计算实例类型、端口和操作系统的版本。系统中所有服务都会开放标准的“健康检测”端点,让所有部署、可观察性和警报工具都能够检测它们的健康状况。

在接下来的演讲中,Bryzek 讨论了事件和事件流的重要性。对于人们提出的要访问 Flow.io API 的请求,他回应说,“我们提供了一组出色的 API,但还是尽量订阅我们的事件流吧”。事件接口的关键原则包括:为所有事件定义模式;生产者可以保证至少一次交付;消费者需要实现幂等性。在 Flow.io 的架构中,端到端的单个事件延迟约为 500 毫秒,基于 PostgreSQL 实现,每个服务每天最大规模约为 10 亿个事件。

生产者将所有的操作日志记录到相应的数据表中,记录插入、更新、删除等操作。在创建事件时,相应的日志记录被放入队列,等待发布。这是实时发生的,而且是异步的,每个日志记录对应一个事件。要在服务中重播事件,只需要把日志记录重新放入队列。消费者将新事件存储在本地数据库中,为了加快删除事件,数据库被分区。在事件到达时,记录进入队列,等待处理。事件通过微批次的方式进行处理,每次消费之间的间隔默认为 250 毫秒。出现任何故障都会在本地进行记录。有关这个方案的更多信息和代码示例,请参阅 Gilt Technology 的 db-journalling 代码库。有兴趣的读者也可以看看变更数据捕获(CDC)的概念, Debezium 是这方面的一个非常好的例子。

演讲的最后一部分侧重于依赖管理和“如何保持最新状态”。保持最新状态的目标就是要定期并自动更新所有服务,以便使用最新版本的依赖项;这对于核心库能够及时用上安全补丁和错误修复程序来说至关重要。Bryzek 回顾了开场时所讲的那个故事,他说,“这应该只要几个小时,而不是数周或数月”,并且内部开发的库应该与外部开源库一样使用相同的流程。Flow.io 的工程团队每周都会将所有服务的依赖项升级到最新版本,他们使用“ flowcommerce/dependency ”工具(已开源)来跟踪依赖项。这个工具基于服务代码库开启自动升级,并创建相关的拉取请求。一旦构建通过,就会部署每个服务。

Bryzek 总结说,工程师应该首先为所有 API 和事件设计模式,并且应该优先使用事件而不是直接调用 API。工程师应该在适当且有效的自动化上做一些投入,重点关注部署、代码生成和依赖管理等任务。还应该鼓励团队编写“简单却有效”的测试,因为这样可以提高质量、简化维护工作并实现持续交付。

Michael Bryzek 的演讲幻灯片可以在 SlideShare 上找到,演示视频以及 QCon 纽约的所有演讲将在未来几个月内在 InfoQ.com 上发布。

查看英文原文 Designing Microservice Architectures the Right Way: Michael Bryzek's Lessons Learned at QCon NY

2018 年 6 月 30 日 19:00405
用户头像

发布了 731 篇内容, 共 370.2 次阅读, 收获喜欢 1865 次。

关注

评论 1 条评论

发布
暂无评论
发现更多内容

给自己当前岗位所定义的理想岗位模型

邹小胖

自我思考

架构师训练营第2期 第13周总结

月下独酌

架构师训练营第2期

面试官:Netty的线程模型可不只是主从多Reactor这么简单

中间件兴趣圈

reactor Netty nio 中间件 线程模型

HDFS中的常用压缩算法及区别

王知无

大数据 hdfs

在 AWS 的视角下,正确打开零信任安全模型

亚马逊云科技 (Amazon Web Services)

云计算 AWS

第一周-胡赵凯-总结

hisun胡

产品经理训练营

Flink1.12集成Hive打造自己的批流一体数仓

王知无

大数据 flink

项目管理系列 (5)-沟通规划

Ian哥

项目管理 沟通与管理 28天写作

Springboot 中的切面AOP处理

武哥聊编程

Java aop springboot SpringBoot 2 28天写作

AWS Graviton2 | 匠“芯”定制,性能为王

亚马逊云科技 (Amazon Web Services)

云计算 AWS

第一周-胡赵凯-作业

hisun胡

产品经理训练营

架构师训练营 week13 课后作业

花果山

架构师课程--第十三周作业

孤星

有道乐读 x AWS | 云上的少儿图书馆!这个寒假让孩子爱上“乐读”

亚马逊云科技 (Amazon Web Services)

云计算 AWS

架构师训练营第2期 第13周命题作业

月下独酌

架构师训练营第2期

英雄惜英雄-当Spark遇上Zeppelin之实战案例

王知无

大数据 spark

第13周作业

Rocky·Chen

算法 数据分析

构师训练营 - 第十三周课后练习

joshuamai

架构师训练营 week13 学习笔记

花果山

敏捷开发需要内外兼修

Bruce Talk

敏捷开发 Agile

HTML(一)——html相关介绍

程序员的时光

程序员 28天写作

十三周总结

水浴清风

最长公共前缀字符串, RxSwift的概念详细解析, 极客大学认识产品经理 John 易筋 ARTS 打卡 Week 35

John(易筋)

ARTS 打卡计划 最长公共前缀字符串 RxSwift的概念详细解析 极客大学认识产品经理 极客大学产品经理训练营

如何 debug hive 源码,知其然知其所以然

王凯

hive 源码分析

数字货币合约交易系统软件开发|数字货币合约交易APP开发

开發I852946OIIO

系统开发

ClickHouse在大数据领域企业级应用实践和探索总结

王知无

大数据 Clickhouse

【计算机内功修炼】七:高并发高性能服务器是如何实现的

码农的荒岛求生

高并发 事件驱动 高性能 Event Driven 高并发优化

Hbase性能优化百科全书

王知无

大数据 HBase

前端也要懂机器学习(下)

执鸢者

机器学习 前端

软件架构-缓存技术

看山

缓存 架构

十三、数据应用二

Geek_28b526

边缘计算隔离技术的挑战与实践

边缘计算隔离技术的挑战与实践

正确设计微服务架构:Michael Bryzek在纽约QCon上的演讲-InfoQ