4. Kong 基础配置:Service、Route、Upstream 的创建与管理
好,我们直接进入正题。Kong 网关的核心抽象其实就三个东西:Service、Route 和 Upstream。很多人一开始会被这些概念绕晕,觉得不过是换个名字的负载均衡。我刚开始接触时也这么想,直到在生产环境踩了坑……嗯,咱们今天把这几个东西彻底捋清楚。
4.1 Service:你后端服务的“门牌号”
Service 就是后端业务服务的抽象。举个例子,你有一个用户服务跑在 10.0.1.5:8080,Kong 把它的地址、协议、超时等信息注册成一个 Service。客户端不需要知道这个 IP 和端口,只需要知道 Service 的名字。
核心字段
name:唯一标识,比如user-servicehost:目标主机地址(可以是域名或 IP)port:目标端口protocol:http / https / grpc 等connect_timeout、read_timeout、write_timeout:超时控制
创建 Service 有两种方式:Admin API 或声明式配置文件。我个人更推荐先用 API 做快速验证,再固化到声明式配置里。
# 使用 Admin API 创建一个 Service
curl -X POST http://localhost:8001/services \
-H "Content-Type: application/json" \
-d '{
"name": "user-service",
"host": "10.0.1.5",
"port": 8080,
"protocol": "http",
"connect_timeout": 5000,
"read_timeout": 30000
}'
一个小技巧:如果后端服务是 HTTPS,记得把 protocol 设为 https,Kong 会自动处理 TLS 握手。我曾因为忘记改协议,导致客户端一直报连接被重置,排查了半小时才发现是协议不匹配。
4.2 Route:流量进来的“规则引擎”
Service 定义好了,但客户端怎么找到它?这时就需要 Route。Route 决定了哪些请求匹配到哪个 Service。说白了,它就是一组转发规则:匹配路径、方法、Host、Header 等等。
一个 Service 可以挂载多个 Route,一个 Route 只能属于一个 Service。这种设计挺合理的——你想像一下,一个用户服务可能同时提供 RESTful API 和 WebSocket 连接,用不同 Route 区分就好。
Route 关键匹配条件
| 字段 | 说明 | 示例 |
|---|---|---|
paths |
路径前缀或精确路径 | ["/api/users"] |
methods |
HTTP 方法 | ["GET", "POST"] |
hosts |
请求的 Host 头 | ["api.example.com"] |
headers |
自定义 Header 匹配 | {"X-Version": "v2"} |
protocols |
协议类型 | ["http", "https"] |
# 为刚才的 user-service 创建 Route
curl -X POST http://localhost:8001/routes \
-H "Content-Type: application/json" \
-d '{
"name": "user-api-route",
"service": {
"name": "user-service"
},
"paths": ["/api/users"],
"methods": ["GET", "POST"],
"strip_path": true
}'
注意 strip_path 这个坑:strip_path 默认是 true,意思是从请求路径里把匹配的前缀去掉再转发给后端。比如请求 /api/users/info,Kong 会转发给后端 /info。如果后端不期望路径被裁剪,记得设为 false。我曾经因为这个导致上游收到路径不对,接口返回 404,折腾了半天。
4.3 Upstream:负载均衡与健康检查
生产环境里,后端服务往往不止一个实例。Upstream 就是用来描述一组后端节点,并让 Kong 在它们之间做负载均衡。它还可以配置健康检查,自动踢掉挂掉的节点。
我建议在服务实例数量超过 2 个时,一定要配 Upstream 而不是直接指向单个 IP。否则某个节点挂了,你的服务就全瘫了。
Upstream 的主要参数
name:Upstream 唯一名称,比如user-upstreamalgorithm:均衡算法,支持round-robin、consistent-hashing、least-connections等healthchecks:主动/被动健康检查配置slots:节点槽位数(默认 10000,一般不用改)
# 创建一个 Upstream
curl -X POST http://localhost:8001/upstreams \
-H "Content-Type: application/json" \
-d '{
"name": "user-upstream",
"algorithm": "round-robin",
"healthchecks": {
"active": {
"type": "http",
"http_path": "/health",
"interval": 10,
"healthy": {
"interval": 10,
"successes": 2
},
"unhealthy": {
"interval": 5,
"http_failures": 3
}
}
}
}'
# 添加目标节点
curl -X POST http://localhost:8001/upstreams/user-upstream/targets \
-H "Content-Type: application/json" \
-d '{"target": "10.0.1.5:8080", "weight": 100}'
curl -X POST http://localhost:8001/upstreams/user-upstream/targets \
-H "Content-Type: application/json" \
-d '{"target": "10.0.1.6:8080", "weight": 100}'
健康检查的间隔别设太短:我见过有人设成 1 秒一次,结果后端被请求刷爆。推荐生产环境主动检查间隔设为 10~30 秒,被动检查(根据代理请求判定)设 60 秒恢复时间。
4.4 三者如何串联?一张图看懂
你一定好奇这些概念怎么配合工作。来,我画张图把流程串起来:客户端请求发到 Kong,Kong 根据 Route 匹配规则找到 Service,Service 关联到 Upstream,Upstream 再从节点列表里选一个健康的实例转发。
4.5 实战:一个完整的创建流程
我们用手上的 API 串起来做一个完整的例子:先建 Upstream 并加入两个后端节点,再建 Service 指向这个 Upstream,最后创建 Route 把流量引进来。
# Step 1: 创建 Upstream
curl -s -X POST http://localhost:8001/upstreams \
-d '{"name": "user-upstream", "algorithm": "least-connections"}'
curl -s -X POST http://localhost:8001/upstreams/user-upstream/targets \
-d '{"target": "10.0.1.5:8080", "weight": 50}'
curl -s -X POST http://localhost:8001/upstreams/user-upstream/targets \
-d '{"target": "10.0.1.6:8080", "weight": 50}'
# Step 2: 创建 Service,指向 Upstream
curl -s -X POST http://localhost:8001/services \
-d '{
"name": "user-service",
"host": "user-upstream",
"port": 80,
"protocol": "http"
}'
# 注意:host 填的是 Upstream 名字,不是实例 IP
# Kong 内部会自动解析为 Upstream 的负载均衡节点
# Step 3: 创建 Route
curl -s -X POST http://localhost:8001/routes \
-d '{
"name": "user-route",
"service": {"name": "user-service"},
"paths": ["/api/users"],
"strip_path": false,
"methods": ["GET", "POST"]
}'
验证是否生效:用 curl 请求 http://localhost:8000/api/users,看响应是否来自后端节点。也可以查看 /routes、/services、/upstreams 的列表接口确认。
4.6 避坑指南
| 坑 | 现象 | 解决方法 |
|---|---|---|
| Service 的 host 写成了实例 IP 而不是 Upstream 名 | 负载均衡不生效,流量只转发到一个节点 | 检查 Service 的 host 字段,应填 Upstream 的 name |
Route 的 strip_path 设置错误 |
后端收到路径与实际不符,404 | 根据后端期望的路径决定是否裁剪 |
| Upstream 目标节点权重为 0 或超出范围 | 节点被自动忽略,流量倾斜 | 权重范围 0~65535,0 表示不接受新连接 |
| 健康检查路径配置不对 | 节点被误判为不健康 | 确保 http_path 是后端真实的健康端点 |
特别提醒:Kong 的 Upstream 目标节点更新不是实时的?其实更改后 Kong 会在几秒内生效,无需重启。但如果你改了 Upstream 的算法,建议重新请求一下路由刷新缓存。我曾经改完算法发现流量没变,后来查到是 Kong 的缓存机制,加个空请求就好了。
4.7 管理建议与总结
说真的,Service、Route、Upstream 这三个概念掌握好了,Kong 的 80% 的配置工作你就拿下了。个人习惯是先画一个流量图(就像我上面那张 SVG),明确每个路由要走到哪个后端集群,然后再动手建资源。
还有个小建议:生产环境用声明式配置(比如 decK 或 YAML),不要全靠 Admin API 手敲,否则迁移或回滚时会很痛苦。我早期就是在测试环境用 API 堆了大几十个路由,后来要导出到生产,一个个 curl 调接口,差点奔溃。
本章的内容就这些。记住——Service 是抽象服务,Route 是匹配规则,Upstream 是后端节点池。三者缺一不可,配合起来才能让 Kong 稳定地处理流量。