API 网关位于任何大规模应用的前线。它们向外部世界暴露服务,执行安全,并塑造客户端如何与后端交互。大多数团队从现成解决方案开始,如 AWS API Gateway、Apigee 或 Kong。对于许多用例,这些工具工作良好,但在某些时候,它们可能不够用。
Tinder 在 2020 年左右达到了那个临界点。
多年来,Tinder 扩展到超过 500 个微服务。这些服务通过服务网格在内部通信,但面向外部的 API(处理从推荐到匹配到支付的一切)需要统一、安全且开发者友好的入口点。现成网关提供强大功能,但没有精度。它们对配置施加约束,在部署中引入复杂性,并缺乏与 Tinder 云栈的深度集成。
还有一个速度问题。产品团队频繁推送后端服务和移动客户端的更新。网关需要跟上。每次延迟暴露新路由或调整边缘行为都会减慢功能交付。
然后是更大的担忧:安全。Tinder 在全球运营。真实用户流量从超过 190 个国家涌入。坏流量也是如此,包括机器人、抓取器和滥用尝试。网关成为关键瓶颈点。它必须执行严格控制,检测异常,并应用保护过滤器而不减慢合法流量。
工程团队需要的不仅仅是 API 网关。它需要一个能够与组织一起扩展、深度集成内部工具,并让团队快速移动而不损害安全的框架。这就是 TAG(Tinder API Gateway)诞生的地方。
问题
在 TAG 之前,Tinder 的网关逻辑是第三方解决方案的拼凑。不同的应用团队采用了不同的 API 网关产品,每个都有自己的技术栈、操作模型和限制。对一个团队有效的东西对另一个团队成为瓶颈。
这个碎片化设置引入了真正的摩擦:
- 不兼容的技术栈使共享代码或配置变得困难
- 可重用组件无法在团队间传播,导致重复和漂移
- 会话管理行为在不同网关间变化,产生微妙的 bug 和不一致的用户体验
- 操作开销攀升。每个网关都有自己的怪癖、升级周期和维护成本
- 部署速度减慢。团队花更多时间学习、调试和绕过网关限制,而不是交付功能
同时,核心功能在现有网关中缺失或难以实现。一些例子:
- 没有干净的方法启动可独立扩展的每应用网关
- 对 Kubernetes 原生工作流支持有限,Tinder 已在其他地方采用
- 配置格式沉重或不灵活,减慢团队尝试暴露或修改路由
- 构建自定义中间件(如用于机器人检测或请求模式执行的过滤器)不受支持或痛苦维护
- 在边缘转换请求和响应需要编写样板或采用脆弱插件
这些不是边缘情况。它们是快速移动、全球规模产品中的日常需求。
需求很明确:一个统一的内部框架,让任何 Tinder 团队能够构建和运营安全、高性能的 API 网关,摩擦最小。
评估现成解决方案
在构建 TAG 之前,团队评估了几个流行的 API 网关解决方案,包括 AWS API Gateway、Apigee、Kong、Tyk、KrakenD 和 Express Gateway。
这些平台各有优势,但都没有与 Tinder 的操作和架构需求很好对齐。评估期间出现几个核心问题:
- 与 Envoy 集成弱,Envoy 作为 Tinder 内部服务网格的骨干
- 配置开销高。设置甚至基本路由或转换涉及冗长配置文件、不熟悉的插件系统或自定义脚本
- 陡峭学习曲线减慢入职和调试。团队必须学习每个网关的内部,而不是专注于交付功能
- 对 Tinder 首选语言和工具支持差意味着更多胶水代码和更少重用。摩擦快速累积
- 扩展性有限。添加自定义过滤器或中间件通常意味着分叉网关、编写不支持的插件,或处理脆弱的生命周期钩子
TAG 架构
TAG(Tinder API Gateway 的缩写)是基于 Spring Cloud Gateway 构建的基于 JVM 的框架。
它不是即插即用产品或单个共享网关实例。它是一个网关构建工具包。每个应用团队可以使用它启动自己的 API 网关实例,定制其特定路由、过滤器和流量需求。
在其核心,TAG 将配置转化为基础设施。团队使用简单的 YAML 或 JSON 文件定义其路由、安全规则和中间件行为。TAG 通过 Spring 的反应式引擎在幕后连接一切。
这个设计解锁三个关键结果:
- 更快的开发者工作流:大多数更改不需要代码,只需要配置
- 更强的安全边界:团队拥有和隔离其网关实例
- 更好的重用:通过共享过滤器和通用中间件模式
从开发者角度,体验看起来像这样:
- 在配置文件中定义路由
- 应用内置过滤器如 setPath、rewriteResponse 或 addHeader
- 重用全局过滤器用于共享关注点如认证或指标
- 在需要特定验证、转换或控制的地方放入自定义过滤器
大多数 API 网关在配置增长大时受苦。路由加载需要时间。过滤器增加复杂性。一些系统甚至在运行时解析配置,在请求时引入延迟。TAG 通过在启动时做繁重工作完全避免这个。
启动流程
基于 Spring Cloud Gateway 构建,TAG 用自定义组件扩展默认生命周期,在处理任何流量之前处理所有配置。结果是一个完全准备的路由引擎,从第一个请求就准备好。
以下是启动流程如何工作:
- 网关观察者启动流程,发出加载路由定义的信号
- 网关配置解析器读取特定于环境的 YAML 配置并验证结构。这包括路由路径、谓词、过滤器和后端服务绑定
- 网关管理器组装路由 ID 到其相关过滤器(预构建、自定义和全局)的映射
- 网关路由定位器获取该映射并将每个路由的谓词和过滤器绑定到 Spring Cloud Gateway 的内部路由引擎
- 完整路由表加载到内存,所以当 TAG 开始接收流量时,不需要任何运行时解析或配置评估
这个设计确保路由逻辑以最小开销执行。每个决定已经做出。每个路由、谓词和过滤器都编译到运行时图中。
权衡简单而刻意:如果配置错误,网关在启动时快速失败,而不是在生产流量期间缓慢失败。它早期执行正确性并保护运行时性能。
请求处理流程
当请求到达 TAG 驱动的网关时,它通过定义良好的过滤器、转换和查找管道,然后到达后端。这是一个一致的执行路径,让团队在每个阶段控制。
以下是 TAG 如何从头到尾处理传入请求:
1. 地理位置
TAG 应用全局过滤器,将客户端 IP 地址映射到三字母 ISO 国家代码。这个轻量级检查支持:
- 国家特定速率限制
- 地理感知请求禁止
- 区域功能门控
过滤器在任何路由匹配前运行,确保甚至无效或阻止路径可以早期停止。
2. 模式捕获
TAG 捕获请求和响应模式,不是完整负载。这通过全局异步过滤器发生,将事件发布到 Amazon MSK(Kafka)。数据流支持:
- 自动生成 API 文档的 API 文档
- 基于请求模式和形状的机器人检测
- 实时分析流量结构的异常检测工具
过滤器在主线程外工作,避免影响请求延迟。
3. 会话验证
集中全局过滤器处理会话验证和更新,确保会话逻辑在所有网关和服务间保持一致。没有每服务会话漂移或重复逻辑。
4. 路由匹配
一旦初步过滤器完成,TAG 使用 Spring Cloud Gateway 的谓词引擎将请求路径匹配到配置的路由。如果未找到匹配,请求早期拒绝。
5. 服务解析
识别路由后,TAG 使用 Envoy 的服务网格解析正确的后端服务。这个方法从固定 IP 或静态服务列表解耦路由。
6. 预过滤器
在转发请求前,TAG 应用为该路由定义的任何预过滤器。这些可以包括:
- 跨不同后端版本的加权路由
- HTTP 到 gRPC 转换,当前端客户端谈论 HTTP 但后端说 gRPC
- 自定义过滤器,如修剪头部或验证请求字段
预过滤器按配置确定的顺序运行。
7. 后过滤器
后端服务响应后,TAG 通过后过滤器处理输出。这些通常包括:
- 日志记录或错误丰富
- 头部修改或屏蔽敏感字段
- 响应转换为形状规范化
同样,执行顺序是可配置的。
8. 响应返回
一旦所有后过滤器完成,最终响应发送回客户端。无惊喜,无副作用。
执行顺序
每个过滤器(预、后、全局或自定义)遵循严格的执行顺序。开发者可以:
- 在任何阶段插入自定义逻辑
- 在路由间共享过滤器
- 定义精确的执行优先级
这个可预测性使 TAG 在负载下可维护。
结果
TAG 已成为 Tinder 的标准 API 网关框架。不是依赖一个集中式网关实例,每个应用团队部署其 TAG 实例,带应用特定配置。这个模型给团队自主权,同时保持路由定义、流量过滤和安全执行的一致性。
每个 TAG 实例独立扩展,使其容易适应流量模式、功能启动或业务优先级的变化。TAG 现在为 Tinder 供电 B2C 和 B2B 流量,不仅为 Tinder,也为其他 Match Group 品牌如 Hinge、OkCupid、PlentyOfFish 和 Ship。
长期优势
TAG 的设计解锁几个长期优势:
- 会话和认证逻辑标准化:移除团队和服务间的不一致
- 自定义插件支持:允许快速实验和在边缘的微调行为
- 无供应商锁定:意味着 Tinder 控制其演进路径,无需等待第三方路线图更新
- 配置即路由(RAC):让团队更快推送更改,无需编写代码或等待中心团队
超越当前生产使用,TAG 为需要在 API 层可见性和控制的未来计划奠定基础。
这里的教训不是每个公司需要构建自定义网关。教训是在一定规模下,灵活性、一致性和性能不能仅用现成工具解决。TAG 有效是因为它深刻由 Tinder 如何构建、部署和保护其软件塑造,而不损害开发者速度或操作清晰度。
本文为学习目的的个人翻译,译文仅供参考。
原文链接:How Tinder’s API Gateway Handles A Billion Swipes Per Day。
版权归原作者或原刊登方所有。本文为非官方译本;如有不妥,请联系删除。