写点什么

一个创业公司的 API 网关落地实践

2017 年 3 月 05 日

HelloFresh 是一家食品电商初创公司,用户根据选定的菜谱下单,HelloFresh 把菜谱所需要的食材送至用户家中。来自 HelloFresh 的技术负责人Ítalo Lelis 在博客上分享了 HelloFresh 的 API 网关落地实践,本文为该博文的译文,并已获得原网站的翻译授权。

HelloFresh 的规模一直保持着增长的态势:我们的产品在持续改进,新的想法不断涌现出来,我们拥有完全自动化的供应链。持续的增长给我们带来了惊喜,同时也带来了技术方面的挑战。

在这篇文章里,我将会和大家分享我们的基础设施所经历的一次重大迁移,这次迁移保证了以后的路我们可以走得更快、更灵活,也更安全。

挑战

我们最近开发了一个 API 网关,所以接下来需要在不停机的情况下对网关后面的主 API(单体系统)进行迁移改造。升级之后,我们希望能够开发更多的微服务系统,并且无缝对接到目前我们的基础架构中。

架构

API 网关处在基础设施的最外层,它每天需要接收大量的请求,所以我们选择了 Go 语言来构建网关,因为 Go 性能好、简单易用,而且提供了优雅的并发解决方案。

我们手头已经有很多现成的工具,它们可以简化我们的迁移工作。

服务发现和客户端负载均衡

我们使用 Consul 作为服务发现工具,它和 HAProxy 配合起来使用可以帮我们解决微服务架构的两个主要问题:服务发现(新服务上线时会自动注册)和客户端负载均衡(把请求均衡地分发到各个服务器上)。

自动化

我们的工具箱里最有用的工具或许要数基础设施的自动化。我们使用 Ansible 在云端管理资源,包括单机、网络、DNS、运行持续集成工具的主机,等等。按照我们的惯例,开发一个新服务时,我们工程师的第一件事情就是为这个服务创建 Ansible 脚本。

日志和监控

从某种程度上说,我们应该监控基础设施里的所有东西。在日志和监控应用方面,我们有一些最佳实践。

  • 办公室里有仪表盘(就是国内公司里的大电视屏,显示系统状态),我们在任何时候都可以查看系统的运行情况。
  • 我们使用 ELK 技术栈来收集日志,从而可以快速地分析服务的运行情况。
  • 我们使用 Statsd Grafana 作为监控工具,这些工具总会给我们带来惊喜。

Grafana 的仪表盘为性能度量指标提供了非常完美的视角。

理解当前的架构

尽管有了这些工具,我们仍然有一个棘手的问题需要解决:理清当前的架构,然后想清楚如何顺利地进行迁移。我们花了一些时间对遗留系统进行了重构,让它们支持新的网关,同时我们也加入了认证服务。在这个过程中,我们遇到了一些问题。

  • 虽然我们可以对移动应用进行更新,但也要考虑到有些用户可能不愿意升级,所以我们要保持向后兼容,比如 DNS,我们要确保旧版本也能正常工作。
  • 我们需要整理出所有公开和私有的 API 端点,并让它们自动地注册到网关上。
  • 我们需要把认证工作从主 API 迁移到新的认证服务上。
  • 确保网关和微服务之间通信的安全性。

为了解决这些问题,我们写了一个 Go 脚本,这个脚本会读取 OpenAPI 规范( Swagger )文件并为 API 资源创建规则(比如速率限定、配额、CORS 等)代理。

我们在 staging 环境搭建了整个基础设施,并在上面运行自动化测试,对服务间的通信进行了测试。不得不说,自动化 staging 测试在整个迁移过程中起到了很大的作用。我们有很多功能测试用例,这些用例保证了主 API 的功能是完好的。

在确保了 staging 环境一切正常之后,我们开始考虑如何将它们推到生产环境。

第一次尝试

可以告诉大家的是,我们的第一次尝试简直是灾难性的。尽管我们已经做足了计划,不过仍然不足以把它们推向生产环境。先来看看我们的初始计划。

  • 把最新的 API 网关部署到 staging 环境
  • 把主 API 的变更部署到 staging 环境
  • 在 staging 环境运行自动化功能测试
  • 通过网站和移动端进行 staging 环境的手动测试
  • 把最新的 API 网关部署到生产环境
  • 把主 API 的变更部署到生产环境
  • 在生产环境运行自动化功能测试
  • 通过网站和移动端进行生产环境的手动测试
  • 庆祝胜利

在 staging 环境一切进展得都很顺利,当我们准备进入生产环境时,问题出现了。

  1. 认证服务的数据库过载:我们低估了请求的流量,造成数据库拒绝连接
  2. 错误的 CORS 配置:部分端点的 CORS 规则配置错误,造成请求无法获得资源

数据库被冲垮,我们不得不马上回滚。幸运的是,我们的监控系统捕获到了从认证服务获取令牌的问题。

第二次尝试

从第一次失败中吸取了教训,我们知道我们还没有为进入生产环境做好准备,于是在回滚之后,立即对问题展开诊断。在再次尝试之前,我们做了一些改进。

  • 准备蓝绿(blue-green)部署过程。我们为生产环境创建了一个副本,包括已经部署好的网关,通过一些简单的配置变更就能让整个集群运行起来,如果需要回滚,也只需做一些简单的配置变更。
  • 从当前的系统收集更多的度量指标,这样可以帮助我们决定该使用多少机器来处理负载。我们利用第一次尝试时所使用的数据作为探针,并使用 Gatling 来运行负载测试,确保我们可以应付预期的流量。
  • 再次进入生产环境之前,我们对认证服务的已知问题进行了修复,包括一个大小写问题、一个 JWT 签名的性能问题,并添加了更多的日志和监控。

我们花费了一个礼拜来完成上述的工作,之后的部署进展得很顺利,中间没有停机。不过尽管部署进展得很顺利,我们仍然发现了一些在自动化测试中没有发现的个别问题,不过这些问题最终得到修复,并没有对系统造成太大影响。

结果

最终的架构如下图所示。

主 API

  • 10 多个主 API 部署在装配了高端 CPU 的主机上
  • 主从 MySQL(3 个副本)

认证服务

  • 4 个应用服务器
  • 主从 PostgreSQL(2 个副本)
  • RabbitMQ 用于异步地处理用户的更新操作

API 网关

  • 4 个应用服务器
  • 主从 MongoDB(4 个副本)

其它

  • 使用 Ansible 批量管理远程服务器
  • 使用 Amazon CloudFront 作为 CDN/WAF
  • 使用 Consul 和 HAProxy 作为服务发现和客户端负载均衡工具
  • 使用 Stasd 和 Grafana 收集系统度量指标并触发告警
  • 使用 ELK 技术栈从不同的服务收集日志
  • 使用 Concourse CI 作为持续集成工具

查看英文原文: Scaling @ HelloFresh: API Gateway


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017 年 3 月 05 日 18:007343
用户头像

发布了 321 篇内容, 共 112.0 次阅读, 收获喜欢 113 次。

关注

评论

发布
暂无评论

Kubectl Plugin 推荐(三)| 插件开发篇

郭旭东

Kubernetes kubectl kubectl plugin

Kubernetes入门——深入浅出讲Docker

百度开发者中心

Docker Kubernetes 云原生

LeetCode题解:647. 回文子串,动态规划,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

阿里P8大牛亲自讲解!2021年Android网络编程总结篇,醍醐灌顶!

欢喜学安卓

android 程序员 面试 移动开发

uni-app跨端开发H5、小程序、IOS、Android(一):太强了,一次性搞定全端开发

黑马腾云

微信小程序 uni-app uniapp web前端 3月日更

区块链数字版权管理,区块链赋能知识产权保护

13530558032

NAC公链——Nirvana NA公链白皮书

区块链第一资讯

挖矿 区块链+

云原生时代下,容器安全的“四个挑战”和“两个关键”

阿里巴巴云原生

容器 云原生 k8s 安全 监控

【LeetCode】不同的子序列Java题解

HQ数字卡

算法 LeetCode 28天写作 3月日更

跟公司新招的这个“同事”搭档,工作搬砖太“自动化”了

华为云开发者社区

华为 AI RPA 自动化 员工

电商千万级交易的金手指:分布式事务管理

华为云开发者社区

微服务 事务 华为云 分布式事务管理 DTM

你遇到过哪些质量很高的 Java 面试?

张小方

Java 面试 阿里 薪资

私藏干货 | 实现分布式锁的三种方案对比

架构精进之路

分布式锁 3月日更

Kubernetes入门——Kubernetes工作原理及使用

百度开发者中心

#Kubernetes# #技术课程#

C语言中“野指针”、“悬空指针”是什么?

不脱发的程序猿

c 指针 编程之路 bug 3月日更

OpenKruise v0.8.0 核心能力解读:管理 Sidecar 容器的利器

阿里巴巴云原生

容器 微服务 云原生 k8s 应用服务中间件

阿里二面:什么是mmap?

艾小仙

微服务的下一步,离不开服务网格

xcbeyond

微服务 Service Mesh 服务网格 3月日更

多端框架开发 | 拼团商城项目开发说明

APICloud

小程序云开发 前端 移动终端 APP开发 多端开发

区块链数字版权管理,区块链赋能知识产权保护

13530558032

阿里P9春招特此分享:Java核心开发成长手册(2021版)涵盖所有p5-p8技术栈

比伯

Java 编程 架构 面试 程序人生

干货来袭!这份阿里内部面试题库已经助我拿到了5个大厂Offer!

Java王路飞

Java 程序员 架构 面试 阿里

您的客户管理决策是否低于10毫秒?

VoltDB

5G 物联网 解决方案 电信

惊讶!阿里大佬总结的图解Java小册火了,完整版笔记开放下载

周老师

Java 编程 程序员 架构 面试

面试官:啥?SynchronousQueue是钟点房?

四猿外

Java 并发编程 高并发 并发 SynchronousQueue

网易云音乐:基于分布式图学习PGL的推荐系统优化之路

百度开发者中心

带你走进与千万数据通信者共成长的“家园”

华为云开发者社区

华为 开发者 网络 华为数据通信 社区

阿里P8大牛亲自教你!一个三非渣本的Android校招秋招之路,满满干货指导

欢喜学安卓

android 程序员 面试 移动开发

看故事学Redis:再不懂,我怀疑你是假个开发

华为云开发者社区

MySQL 数据库 redis 缓存 数据

区块链电子证照应用赋能政府服务

13530558032

案例+源码!阿里新产高并发技术小册太香了!内容涵盖高并发、网络编程、微服务、数据处理等诸多技术栈

程序员小毕

Java 程序员 面试 高并发 阿里

一个创业公司的API网关落地实践-InfoQ