去年在微服务架构升级过程中,我们选择Kong作为API网关解决方案。这个决定主要基于Kong的插件生态和性能表现,但在实际部署过程中却遭遇了一系列意料之外的问题。最突出的有两个:一是部分请求会无故卡死,客户端长时间得不到响应;二是限流插件的错误提示全是英文,不符合我们的本地化需求。
请求卡死的问题尤其棘手,它出现的时机毫无规律——有时连续几个小时运行正常,有时却在流量高峰突然爆发。客户端表现为连接超时,而Kong的日志里却查不到任何错误记录。更麻烦的是,这个问题在开发环境几乎无法复现,只有在生产环境的特定条件下才会显现。
我们首先建立了问题复现的最小环境。通过tcpdump抓包发现,卡死的请求都停留在TCP握手阶段。奇怪的是,Kong明明已经收到了SYN包,却没有返回SYN-ACK。这提示问题可能出在操作系统层面而非应用层。
关键排查命令:
bash复制# 监控TCP连接状态
watch -n 1 'ss -s | grep -E "TIME-WAIT|ESTAB"'
# 查看连接跟踪表
conntrack -L | grep UNREPLIED
我们的Kong运行在Docker Swarm集群中,进一步检查发现了致命配置:
yaml复制# 错误的网络配置示例
services:
kong:
networks:
- kong-net
sysctls:
net.ipv4.tcp_tw_recycle: 1 # 这个参数在现代Linux中已废弃
net.ipv4.tcp_timestamps: 0 # 关闭时间戳会导致NAT问题
问题根源在于:
最终采取的解决方案包括:
yaml复制sysctls:
net.ipv4.tcp_tw_reuse: 1
net.ipv4.ip_local_port_range: "1024 65535"
net.netfilter.nf_conntrack_max: 131072
nginx复制worker_processes auto;
worker_rlimit_nofile 4096;
events {
worker_connections 2048;
multi_accept on;
}
bash复制echo 60 > /proc/sys/net/ipv4/tcp_fin_timeout
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
重要提示:在Kubernetes环境中,还需要特别注意kube-proxy的conntrack设置,建议将
--conntrack-max-per-core调大到32768。
Kong的限流插件(rate-limiting)默认返回如下英文提示:
json复制{
"message": "API rate limit exceeded"
}
通过分析插件源码发现,提示信息硬编码在插件的handler.lua文件中。传统做法是直接修改源码,但这会导致升级困难。
我们采用更优雅的OpenResty阶段处理方案:
lua复制-- /usr/local/share/lua/5.1/kong/templates/rate-limiting.lua
local _M = {}
_M["zh-CN"] = {
["API rate limit exceeded"] = "请求频率超过限制",
-- 其他翻译项...
}
return _M
nginx复制init_by_lua_block {
local i18n = require "kong.i18n"
i18n.set_locale(function(ctx)
return ctx.headers["Accept-Language"] or "en"
end)
}
bash复制docker volume create kong-i18n
dockerfile复制FROM kong:3.0
COPY i18n/ /usr/local/share/lua/5.1/kong/templates/
yaml复制services:
kong:
volumes:
- kong-i18n:/usr/local/share/lua/5.1/kong/templates
针对高并发场景的额外建议配置:
nginx复制http {
lua_shared_dict kong_rate_limiting_counters 12m;
lua_socket_pool_size 512;
resolver_timeout 5s;
}
基于此次经验总结的插件开发建议:
推荐的Prometheus监控指标:
yaml复制- pattern: 'kong_http_status{code=~"5.."}'
name: "kong_5xx_errors"
action: "record"
- alert: "HighErrorRate"
expr: "rate(kong_5xx_errors[1m]) > 5"
| 错误现象 | 可能原因 | 解决方案 |
|---|---|---|
| 502 Bad Gateway | 上游服务不可达 | 检查DNS解析和服务健康状态 |
| 503 Service Unavailable | 工作进程崩溃 | 检查内存限制和core dump |
| 504 Gateway Timeout | 上游响应超时 | 调整proxy_read_timeout |
bash复制# 查看工作进程状态
kong health
# 分析OpenResty性能
resty -e 'print(require("jit.v").on())'
这次深度排查让我深刻体会到,即使是成熟的中间件产品,在生产环境部署时也需要充分考虑基础设施的特定约束。特别是在容器化环境中,网络栈的默认配置往往需要针对实际流量模式进行调优。对于国际化需求,建议在插件开发初期就建立i18n支持机制,而不是事后补救。