Kong 是由 Kong Inc.(原 Mashape)开源的高性能云原生 API 网关与微服务管理层。它构建在 Nginx 与 OpenResty 之上,基于 LuaJIT 提供高吞吐、低延迟的流量代理与可扩展的插件体系。
概述与核心定位
在微服务架构和云原生体系中,API 网关位于客户端与后端服务之间,扮演着统一入口与流量看门人的角色。Kong Gateway 提供了如下核心能力:
- 动态路由与反向代理:基于 Host、Path、Method、Header 等条件实现动态流量分发与协议转换(HTTP/HTTPS、gRPC、TCP/UDP、WebSockets)。
- 插件化架构(Pluggable Architecture):认证鉴权、限流熔断、安全防护、日志监控等通用能力全部以插件形式解耦,开箱即用。
- 高可用与弹性扩展:无状态的数据面节点支持横向水平扩容,具备毫秒级甚至亚毫秒级的转发延迟。
- 多环境部署支持:支持传统虚拟机、Docker 容器、Kubernetes(KIC - Kong Ingress Controller)以及混合云部署。
核心架构与运行机制
架构全景:控制面与数据面
Kong 的架构在设计上解耦了控制面(Control Plane, CP)与数据面(Data Plane, DP):
- 控制面(Control Plane):负责接收运维和开发人员的配置变更(通过 Admin API 或声明式配置文件),将元数据持久化并下发给各数据面节点。
- 数据面(Data Plane):运行在生产流量路径上的 Kong 实例,负责接收客户端请求、执行插件链逻辑并反向代理至上游后端服务。
两种部署模式:DB 模式 vs DB-less 模式
| 模式 | 存储介质 | 配置生效方式 | 适用场景 |
|---|---|---|---|
| 传统 DB 模式 | PostgreSQL / Cassandra | 运行时通过 Admin API 写入数据库,节点通过轮询机制同步到本地共享内存 | 传统虚拟机/容器环境、需要动态通过 REST API 增删改路由的场景 |
| DB-less 模式 | 无外置数据库(内存存储) | 通过 kong.yml 声明式文件加载,或结合 decK / Kubernetes Ingress Controller (KIC) 动态同步 | GitOps 流程、Kubernetes 云原生集群、极简高可用架构 |
底层机制:OpenResty 与共享内存
Kong 基于 OpenResty(Nginx + LuaJIT) 构建,充分利用了 Nginx 的 Master-Worker 多进程非阻塞事件驱动模型:
- 内存缓存(Shared Dictionaries,
lua_shared_dict):路由配置、插件元数据、Token 缓存等数据加载在 Nginx 进程间共享内存中。Worker 进程处理流量时直接读取内存,无需每次请求都查询后端数据库。 - 事件驱动与异步通信:当数据库配置发生变更时,控制面发送通知或节点定时拉取,自动更新 shm 缓存,避免 Worker 重启或重载配置带来的抖动。
核心实体与流量模型
Kong 的路由系统围绕一组核心实体构建,各实体之间的关联与流量流向如下:
[ 客户端请求 Client ]
│
▼
[ Route (路由匹配规则) ]
│
▼
[ Service (后端服务抽象) ]
│
▼
[ Upstream (负载均衡集群) ] ── (按权重/轮询分发) ──► [ Target: Backend IP:Port ]
核心实体解析
- Service(服务):对上游真实后端 API 的抽象定义,包含协议(protocol)、域名/主机名(host)、端口(port)、基础路径(path)等属性。
- Route(路由):客户端请求进入网关时的匹配规则。一个 Service 可以挂载多个 Route。当请求的
hosts、paths、methods、headers等匹配 Route 定义时,该请求将被转发至对应的 Service。 - Upstream(上游集群):对应后端一组承载相同业务的服务器集群,负责负载均衡(Round-Robin、Consistent-Hashing 等)与主动/被动健康检查(Health Checks)。
- Target(目标实例):Upstream 中的具体服务节点(IP/域名 + 端口 + 权重)。当后端实例宕机时,健康检查机制会自动将其标记为
unhealthy并摘除流量。 - Consumer(消费者):代表调用 API 的客户端或用户。通过与认证插件(如 Key-Auth、JWT)配合,可对特定调用方进行身份识别、独立限流与权限控制。
- Plugin(插件):注入到请求生命周期中的功能模块。插件可以绑定在不同层级:
- Global:全局生效,作用于所有流经网关的请求。
- Service 级:仅对特定后端服务生效。
- Route 级:仅对特定路由规则生效。
- Consumer 级:仅对特定用户生效。
核心操作与配置方式
使用 Admin API 管理实体
Admin API 默认监听在 8001(HTTP)或 8444(HTTPS)端口,提供标准的 RESTful 接口。
1. 创建 Service
curl -i -X POST http://localhost:8001/services \
--data name=user-service \
--data url=http://upstream-user-backend:8080/api/v1
2. 创建 Route
为 user-service 创建路由,将匹配 /users 路径的请求转发过去:
curl -i -X POST http://localhost:8001/services/user-service/routes \
--data name=user-route \
--data "paths[]=/users" \
--data "strip_path=false"
3. 配置 Upstream 与 Target
实现动态负载均衡与健康检查:
# 创建 Upstream
curl -i -X POST http://localhost:8001/upstreams \
--data name=user-backend-pool
# 添加 Target 实例
curl -i -X POST http://localhost:8001/upstreams/user-backend-pool/targets \
--data target="10.0.1.10:8080" \
--data weight=100
curl -i -X POST http://localhost:8001/upstreams/user-backend-pool/targets \
--data target="10.0.1.11:8080" \
--data weight=100
随后将 user-service 的 host 字段更新为 user-backend-pool 即可将流量接入负载均衡池。
声明式配置与 decK
在 DB-less 或 GitOps 模式下,使用 kong.yaml 集中声明所有网关配置:
_format_version: "3.0"
services:
- name: order-service
url: http://order-api:8080
routes:
- name: order-route
paths:
- /orders
strip_path: false
plugins:
- name: rate-limiting
config:
minute: 100
policy: local
consumers:
- username: app-client-01
keyauth_credentials:
- key: secret-api-key-123456
通过官方工具 decK 执行差异比对(diff)与平滑同步(sync):
# 验证配置合法性
deck validate -s kong.yaml
# 比较当前网关运行态与配置文件的差异
deck diff -s kong.yaml
# 将配置同步推送到网关
deck sync -s kong.yaml
常用插件体系
Kong 官方与社区提供了数十种插件,覆盖 API 全生命周期的治理需求:
认证与安全(Authentication & Security)
key-auth:API Key 认证,客户端通过 Header(如apikey: xxx)或 Query 参数传递密钥。jwt:解析并校验 JSON Web Token 签名与有效时间(exp、nbf),免去后端重复验签开销。oauth2:将 Kong 作为 OAuth 2.0 授权服务器或资源服务器,支持多种授权流程与 Token 验证。ip-restriction:基于白名单(whitelist)或黑名单(blacklist)阻断或放行客户端 IP 流量。cors:自动处理浏览器跨域预检请求(OPTIONS)并注入标准 CORS 响应头。
流量控制与可靠性(Traffic Control)
rate-limiting:基于秒/分/小时维度的速率限制。支持三种计数器存储策略:local:单机内存计数,性能最高但集群间不共享配额。redis:借助 Redis 集中存储计数器,适用于多节点精确限流。cluster:依赖 Kong 数据库聚合(DB 模式可用)。
response-ratelimiting:根据后端返回的自定义 Header 执行动态限流。proxy-cache:根据请求 Method、Path、Header 缓存后端响应内容,降低上游服务压力。
监控与可观测性(Observability)
prometheus:暴露标准 Prometheus 格式指标端点(请求延迟分位数、状态码计数、带宽吞吐、Upstream 健康状态)。zipkin/opentelemetry:生成符合 OpenTelemetry / W3C TraceContext 规范的分布式追踪链路,自动注入traceparent上下文头。file-log/http-log/tcp-log:将结构化访问日志异步输出至磁盘或通过 HTTP/TCP 流转至 ELK、Loki 等日志分析系统。
插件执行生命周期
Kong 插件的执行流程与 OpenResty(Nginx)的处理阶段深度绑定。开发者或使用者理解执行生命周期,对于分析请求流程和编写自定义 Lua 插件至关重要。
生命周期阶段对照表
| OpenResty 阶段 | Kong 插件 Hook 接口 | 执行时机与职责 | 典型操作 |
|---|---|---|---|
init_worker | init_worker() | Nginx Worker 进程启动时触发 | 初始化定时器、后台拉取数据、创建连接池 |
ssl_certificate | certificate() | SSL/TLS 握手阶段 | 动态读取证书、根据 SNI 匹配自定义证书 |
rewrite | rewrite() | 接收到请求头部,路由匹配前执行 | 全局重定向、修改原始 URL、早期流量切分 |
access | access() | 路由匹配完成,转发上游之前执行(最核心阶段) | 身份认证(JWT/Key-Auth)、鉴权、黑白名单、限流拦截 |
header_filter | header_filter() | 接收到上游返回的所有响应头 | 增删改 Response Header(如 CORS、安全头注入) |
body_filter | body_filter() | 接收到上游返回的响应体数据块(流式 chunk) | 响应体内容脱敏、修改、追加数据 |
log | log() | 请求完全响应客户端后异步执行 | 统计耗时、记录日志、上报 Prometheus 指标 |
插件执行优先级(Priority)
每个插件定义中都包含一个整型数值 PRIORITY。在同一执行阶段(例如 access 阶段):
- 高优先级插件优先执行:例如认证插件(
jwt,Priority 通常约为1005)优先于限流插件(rate-limiting,Priority 约为901)执行。 - 安全短路机制:如果在前置插件中调用了
kong.response.exit(401, ...)终止请求,后续插件的access阶段将不再执行,直接跳转至header_filter和log阶段。
生产实践与性能调优
1. 数据库缓存与 Worker 同步调优
在 DB 模式下,合理设置配置缓存时间可有效降低数据库负载:
db_update_frequency(默认 5s):Worker 轮询数据库检查配置版本的时间间隔。生产环境若变更较少,可适度增大(如 10s–30s)。db_cache_ttl(默认 0,永不过期):实体缓存在共享内存中的存活时间。结合 Kong 内部缓存事件失效机制,保持为 0 可获得最佳命中率。
2. 上游 Keepalive 连接池复用
如果未启用长连接池,Kong 对上游后端的每次反向代理都会经历 TCP 三次握手与四次挥手,在高并发场景下会导致大量 TIME_WAIT 连接与端口耗尽:
# 调整 kong.conf 配置参数
upstream_keepalive_pool_size = 512
upstream_keepalive_max_requests = 10000
upstream_keepalive_idle_timeout = 60s
同时确保上游后端服务配置了合理的 keepalive_timeout。
3. DNS 解析与负载均衡缓存
Kong 默认使用内置的异步 DNS 解析器:
dns_hostsfile/dns_resolver:明确配置高可用的内网 DNS 服务器。dns_stale_ttl:当 DNS 服务器暂时无法连通时,允许使用过期解析结果的时间,保障极端网络抖动下的业务连续性。
4. 日志异步化与非阻塞 I/O
- 避免在核心链路(
access/header_filter)执行同步阻塞的 I/O 操作(如阻塞式网络请求、复杂同步写盘)。 - 日志收集建议优先采用基于内存缓冲的异步上报插件(如
http-log配合queue缓冲参数),防止远程日志系统抖动拖垮网关转发性能。