跳转到内容

tyk — Go 实现的开源 API 网关,自带门户和多协议转换

是什么

Tyk 是一个用 Go 写的开源 API 网关——所有外部请求先打到它,它来做鉴权、限流、统计,再转发给后端服务。

打个比方:你家小区门口的保安亭。住户(后端服务)在小区里安心做事,外卖、快递、访客(API 请求)都要先在门口扫码登记、刷脸认证、拿号排队,保安再放行。Tyk 就是这个保安亭,写在 API 这一层。

它还多干一件事:跨协议翻译。前端发 GraphQL 进来,后端是 REST、gRPC 或 SOAP,Tyk 在中间帮你拼接、转换。这一招让它和单纯做反向代理的 nginx 拉开了差距。

最小例子(启动一个 gateway,配置存 Redis):

Terminal window
docker run -p 8080:8080 \
-v $(pwd)/tyk.conf:/opt/tyk-gateway/tyk.conf \
-v $(pwd)/apps:/opt/tyk-gateway/apps \
--link redis:redis \
tykio/tyk-gateway:latest

apps/ 下放 JSON 文件描述 API:监听路径、上游地址、限流规则。

为什么重要

  • 不理解 gateway 你会把鉴权代码 copy 到每个微服务,业务一上规模就乱
  • 不理解多协议转换你会让前端被迫学 gRPC、SOAP 这种它本不该碰的协议
  • 不理解开源 vs 商业的边界你会在 Tyk OSS 已经够用的情况下绕去买 Kong 企业版
  • 不理解 K8s Operator 你会把 API 配置写在 ConfigMap 里,靠人手 apply

核心要点

  1. 请求中间件链——像火车进站逐个检票口。请求进来后依次过 auth → rate limit → quota → transform → upstream,每一节都可短路。链条用 Go 写,所以单实例 ~2 万 QPS 不算难。

  2. 配置热加载靠 Redis——像超市的总账本。你改完 API 定义后调一下 /tyk/reload,gateway 从 Redis 拉新版本立刻生效,不用重启。分布式限流的计数器也共用这本账,所以多实例之间是真互通。

  3. 多协议 universal data graph——像翻译官。前端只想发 GraphQL,后端有 REST、gRPC、SOAP,Tyk 在中间替你把 query 拆成多个上游调用再合并。这是它和 KrakenD 都强调的差异点。

  4. K8s Operator + CRD——像把 API 当 K8s 资源来管。ApiDefinition 是一个自定义资源,你 kubectl apply 它就生效,可以塞进 GitOps 流水线,规模化时比手编 ConfigMap 干净。

实践案例

案例 1:5 秒一关的限流

最小 API 定义(apps/echo.json):

{
"name": "echo",
"api_id": "echo-1",
"org_id": "default",
"use_keyless": true,
"proxy": {
"listen_path": "/echo/",
"target_url": "http://httpbin.org/",
"strip_listen_path": true
},
"global_rate_limit": { "rate": 5, "per": 1 }
}

global_rate_limit 设成 1 秒只放 5 个请求。第 6 个会拿 429 Too Many Requests。use_keyless: true 意思是不用 API key,开放访问。

案例 2:一键导入 OpenAPI

Tyk 4.x 后原生认 OAS 3.0:

Terminal window
curl -X POST http://localhost:8080/tyk/apis/oas \
-H "x-tyk-authorization: foo" \
-H "Content-Type: application/json" \
-d @swagger.json
curl -X POST http://localhost:8080/tyk/reload

效果:paths.* 自动变 endpoint,security 段自动启用 JWT 或 API key。不用手写 Tyk 私有 schema。

案例 3:K8s 上声明式配 API

apiVersion: tyk.tyk.io/v1alpha1
kind: ApiDefinition
metadata:
name: orders
spec:
name: orders
use_keyless: false
proxy:
listen_path: /orders/
target_url: http://orders-svc.default.svc:8080/
jwt:
secret: kid-public-secret
identity_base_field: sub

kubectl apply -f orders.yaml 后 Operator 会调 Tyk control plane 把这条 API 注册进去。改完 push GitHub,CI 跑 kubectl apply 即可,不用进 dashboard 手点。

踩过的坑

  1. 忘了起 Redis 就开本地,limiter 和会话立刻报 connection refused——Tyk 把分布式状态全压在 Redis 上,OSS 版也跑不掉。
  2. 直接编辑 apps/*.json 想热生效但没调 /tyk/reload,gateway 不会自动 watch 文件——所有变更必须通过 reload endpoint 通知。
  3. 把 OSS 版当阉割版结果绕去自己写鉴权——其实 JWT、HMAC、OIDC、mTLS 都在开源版里,先翻 docs 再造轮子。
  4. K8s 上没用 Operator,直接 kubectl apply ConfigMap 维护一堆 API 定义——规模一上去就乱,应该上 ApiDefinition CRD。

适用 vs 不适用场景

适用:

  • 多语言多服务对外暴露 API,需要集中做鉴权 / 限流 / 计量
  • 前端想要 GraphQL,后端是异构 REST / gRPC,需要 gateway 做合并
  • K8s 环境想用 GitOps 管理 API 配置而不是 dashboard 手点

不适用:

  • 单语言单进程小项目,套 gateway 反而徒增运维和延迟
  • 内网纯 RPC 流量,没有外部客户端,用 service mesh 更直接
  • 想要”零配置”开箱即用,Tyk 的 JSON schema 上手有学习曲线

历史小故事(可跳过)

  • 2014:Martin Buhr 在伦敦把 Tyk 开源,主打”全功能不留商业阉割”
  • 2017 前后:加 dashboard 和 developer portal,形成开源 + 商业混合
  • 2019-2020:推 Tyk Operator 拥抱 K8s 声明式
  • 2022 后:补强 GraphQL universal data graph 和 gRPC 转换,扩多协议
  • 2024:原生支持 OpenAPI 3.0 作为 API 定义格式,OAS 一等公民

学到什么

  • gateway 的本质是把横切关注点(auth、限流、统计)从业务代码里抽出来塞到入口
  • 分布式限流必须有共享计数器,所以 Tyk 把 Redis 当成必选依赖
  • 多协议转换是 gateway 的进阶价值,单纯反向代理 nginx 做不到
  • K8s 时代 gateway 也要 CRD 化,否则跟不上 GitOps 流水线

延伸阅读

关联

  • kong —— 同生态另一主流开源 gateway,Tyk 和它常被一起评测
  • krakend —— 同样强调多端点合并的 Go gateway,定位更聚合
  • nginx —— 偏底层反向代理,Tyk 在它之上多一层 API 管理
  • haproxy —— L4/L7 负载均衡,Tyk 不和它竞争而是搭配用
  • caddy —— 走自动 HTTPS 路线的轻量代理,对比能看出”网关”和”代理”边界
  • redis —— Tyk 的强依赖,限流 / 会话 / 配置都走 Redis
  • kubernetes —— Tyk Operator 把 API 当 CRD 管,K8s 用户必看

反向链接

  • caddy —— Caddy — 自动 HTTPS Web 服务器
  • haproxy —— HAProxy — 高性能 LB,TCP/HTTP 双层负载均衡
  • kong —— Kong — 基于 nginx + Lua 的云原生 API 网关
  • krakend —— KrakenD — 把多个后端聚合成一次响应的高性能 API 网关
  • kubernetes —— Kubernetes — 容器编排平台
  • nginx —— nginx — 高性能 Web 服务器
  • redis —— Redis — 内存键值数据库