1. 从一次压测说起traefik 性能测试到底测什么traefik 作为 Kubernetes 集群的统一入口很多团队上线前都会问一句它会不会成为瓶颈我见过最常见的做法是拿 ab 或 wrk 随便打几千个请求看到 QPS 数字还行就收工。但真正做过一轮完整压测后你会发现traefik 性能测试要回答的不是它能跑多快而是在什么并发下延迟开始劣化、瓶颈到底在网关还是在后端。这篇内容聚焦 traefik 作为统一入口时的性能测试方法覆盖并发连接、延迟分布与吞吐量三类指标。我会给出可复制的 wrk/k6 压测脚本、traefik 关键配置片段与 Prometheus 指标采集规则并演示如何通过 TaoToken 统一 Key 通道发起测试请求、对比不同路由策略下的结果最后输出一份可复现的验证清单。适合正在做网关选型、或者已经上了 traefik 但没系统测过的后端和 SRE。先说一个我踩过的坑早期压测只盯着 QPS结果并发从 100 拉到 1000 时 QPS 几乎没变但平均响应时间从 48ms 涨到 486ms。如果只看吞吐量你会误以为系统很稳只有把延迟分布和并发连接数一起看才能发现请求其实在排队。所以三类指标缺一不可——吞吐量看上限延迟分布看体验并发连接看资源水位。测试环境我用的是一套 6 节点集群3 master 3 worker每台 12 核traefik 以 Deployment 方式部署后端业务服务 3 个 Pod每个 limit 4 CPU / 2G 内存。这个配置不算大但足够暴露路由层的问题。下面所有脚本和配置都可以直接搬到你的环境里改改就用。2. TaoToken 前置统一 Key 通道怎么接入压测链路在讲压测脚本之前先解决一个实际问题压测请求打到哪里、用什么凭证。很多团队的后端接口需要鉴权如果每个压测脚本都硬编码一堆 Key管理起来很乱。我的做法是用 TaoToken 作为统一 Key 通道压测流量统一从它这里拿凭证再转发到 traefik 入口这样切换环境、对比不同路由策略时不用改脚本。TaoToken 的定位是统一模型与 API 调用的 Key 管理通道官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。它的价值在于你不需要在压测脚本里散落多个 Key而是通过一个统一通道发起请求方便做 A/B 对比。具体接入分三步。第一步在控制台创建一个 Key地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 创建后在 API Keys 页面复制出来页面在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。第二步确认你要压测的模型或接口 ID可以在模型对话页先手动发一条请求验证通道是否通地址 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。第三步把 Base URL 和 Key 写进压测脚本的环境变量。这里要强调一个配置三件套的概念无论你用 wrk、k6 还是 Claude Code 这类工具接入任何统一通道都需要 Base URL、Key、Model ID 三个东西齐全。少一个就会报 401 或者 model not found。比如 Base URL 填 https://taotoken.net/api Key 填你复制的那串Model ID 填你在模型列表里看到的名称。这三件套在后面的脚本里会反复出现。如果你是要做长期编码或 Agent 类压测可以考虑 Coding Plan入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 它更适合持续性的调用场景。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 遇到参数问题先查这里。需要说明的是TaoToken 在这里的角色是压测流量的凭证与转发通道不是替代 traefik。traefik 仍然是集群入口负责路由和负载均衡TaoToken 负责让压测请求带着统一凭证进来。两者是上下游关系不要混淆。3. 可复制配置traefik 关键参数与压测脚本这一节是全文最实操的部分。先给 traefik 的关键配置片段再给 wrk 和 k6 两套压测脚本最后给 Prometheus 采集规则。所有片段都可以直接复制。3.1 traefik 关键配置片段traefik 的性能相关配置主要集中在 entryPoints、serversTransport 和负载均衡策略上。下面是一份 TOML 配置路径按你实际部署调整# traefik.toml [entryPoints] [entryPoints.web] address :80 [entryPoints.websecure] address :443 [serversTransport] # 后端连接复用减少握手开销 maxIdleConnsPerHost 200 forwardingTimeouts.dialTimeout 5s forwardingTimeouts.responseHeaderTimeout 30s forwardingTimeouts.idleConnTimeout 90s [providers] [providers.kubernetesIngress] endpoint https://kubernetes.default.svc # 关闭不必要的 watch降低控制面压力 throttleDuration 2s如果你用 Kubernetes CRD 方式负载均衡策略可以在 IngressRoute 的 service 里指定apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: demo-route spec: entryPoints: - web routes: - match: Host(demo.example.com) kind: Rule services: - name: demo-svc port: 8080 strategy: RoundRobin # 也可以换成 Weighted 做灰度对比这里有个细节maxIdleConnsPerHost默认值偏小高并发下会频繁建连压测时延迟抖动明显。我把它调到 200 后P99 延迟稳定了不少。strategy字段是后面做路由策略对比的关键RoundRobin 和 Weighted 的结果差异会在第 4 节展示。3.2 wrk 压测脚本wrk 适合快速打吞吐量脚本用 Lua 写。下面这个脚本会带上 TaoToken 的 Key 作为请求头-- stress.lua wrk.method POST wrk.headers[Content-Type] application/json wrk.headers[Authorization] Bearer .. os.getenv(TAOTOKEN_KEY) wrk.body {model:your-model-id,messages:[{role:user,content:ping}]} function response(status, headers, body) if status ~ 200 then io.write(non-200: , status, \n) end end运行命令export TAOTOKEN_KEY你的Key wrk -t12 -c200 -d60s --latency -s stress.lua https://traefik.example.com/v1/chat/completions-t12是 12 个线程对应 12 核-c200是 200 并发连接-d60s跑 60 秒--latency输出延迟分布。跑完你会看到 Latency 分位数和 Requests/sec这就是吞吐量和延迟两类指标。3.3 k6 压测脚本k6 更适合做阶梯式并发能画出延迟随并发变化的曲线。下面这个脚本从 50 并发逐步升到 1000// stress.js import http from k6/http; import { check, sleep } from k6; export const options { stages: [ { duration: 30s, target: 50 }, { duration: 30s, target: 200 }, { duration: 30s, target: 500 }, { duration: 30s, target: 1000 }, { duration: 30s, target: 0 }, ], thresholds: { http_req_duration: [p(95)500], }, }; const BASE_URL __ENV.BASE_URL || https://traefik.example.com; const KEY __ENV.TAOTOKEN_KEY; export default function () { const payload JSON.stringify({ model: your-model-id, messages: [{ role: user, content: ping }], }); const params { headers: { Content-Type: application/json, Authorization: Bearer ${KEY}, }, }; const res http.post(${BASE_URL}/v1/chat/completions, payload, params); check(res, { status is 200: (r) r.status 200 }); sleep(0.1); }运行export TAOTOKEN_KEY你的Key k6 run --out jsonresult.json stress.jsk6 的thresholds里p(95)500表示 95 分位延迟要低于 500ms不满足会返回非零退出码方便接 CI。3.4 Prometheus 指标采集规则traefik 自带 Prometheus 指标需要在配置里打开[metrics] [metrics.prometheus] entryPoint traefik addEntryPointsLabels true addServicesLabels true然后在 Prometheus 里加抓取规则scrape_configs: - job_name: traefik static_configs: - targets: [traefik:8080] metrics_path: /metrics关键指标有这几个traefik_entrypoint_requests_total看总请求数traefik_entrypoint_request_duration_seconds_bucket看延迟分布traefik_service_requests_total看后端服务维度的请求量。用 Grafana 画板时延迟用 histogram_quantile 算 P95/P99histogram_quantile(0.95, sum(rate(traefik_entrypoint_request_duration_seconds_bucket[5m])) by (le))这套配置跑起来后压测时你就能同时看到 wrk/k6 的客户端指标和 traefik 的服务端指标两边对得上才说明数据可信。4. 验证请求从单实例到多实例的结果对比配置就绪后我按单实例、多实例、路由策略对比三轮做了验证。下面把过程和结果说清楚你可以照着复现。4.1 单实例基线traefik 单 Pod业务服务 3 Pod每个 limit 4 CPU / 2G。用 wrk 固定 20 万请求量逐步提高并发结果如下并发数总耗时QPS平均响应时间20207s98120ms50106s199725ms100111s189552ms500100s2094238ms100098s2148465ms3000104s19551534ms这张表信息量很大。并发从 20 到 500QPS 从 981 涨到 2094说明吞吐量在爬坡但并发超过 500 后 QPS 基本卡在 2100 左右而平均响应时间从 238ms 一路涨到 1534ms。这就是典型的吞吐量到顶、延迟劣化——请求在排队网关或后端处理不过来。同时看 CPU 利用率master 节点在 22% 到 35% 之间worker 节点在 10% 到 45% 之间没有任何一台打满。12 核机器上单 traefik 实例 CPU 最多不到 2 核。这说明瓶颈不在 CPU。4.2 多实例扩展把 traefik 扩到 3 实例业务服务扩到 6 节点重新分配节点确保负载均衡。结果性能没有明显变化。QPS 还是 2000 出头延迟曲线几乎重合。这个现象值得琢磨。按理说实例翻倍吞吐量应该上去。但 CPU 依然打不满nginx、traefik、业务 Pod 的 CPU 都上不去。分析下来接口内部请求了 Redis这个接口不是 CPU 密集型任务性能瓶颈在 Redis 的处理速度、网络延迟、序列化反序列化上。换句话说网关不是瓶颈后端依赖才是。4.3 路由策略对比为了确认 traefik 本身的开销我做了三组对比走 traefik 入口、直连 svc、仅走 nginx。traefik 3 实例业务 6 节点20 万请求量并发数走 traefik QPS直连 svc QPS走 nginx QPS10020441393208120022051354221950021881226217410002057120620402000196511922009结论很清晰走 traefik 的 QPS 比直连 svc 高出一大截和走 nginx 基本持平。原因是 traefik 的负载均衡优化让请求分发更均匀而直连 svc 时客户端可能命中同一个 Pod。延迟方面走 traefik 在并发 100 时平均 48ms和 nginx 的 48ms 一致并发 2000 时 traefik 是 1017msnginx 是 995ms差异在噪声范围内。这轮验证说明traefik 不会降低接口性能反而因为负载均衡做得更好比直连 svc 表现更优。真正的瓶颈在 Redis 那侧扩展网关实例解决不了。4.4 用 TaoToken 通道发起对比上面几轮请求都是通过 TaoToken 统一 Key 通道发起的。具体做法是把 Base URL 指向 traefik 入口Key 用 TaoToken 控制台创建的凭证Model ID 用模型列表里的名称。这样切换路由策略时只需要改 traefik 的 IngressRoute 配置压测脚本一行不用动。如果你想验证模型层面的响应可以先用模型对话页手动发一条确认通道通了再上压测。地址是 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。这一步能帮你排除 Key 或 Model ID 配错的问题。5. 常见报错排查401、local proxy failed 与 OAuth压测过程中最容易卡住的不是脚本本身而是接入配置。下面按真实报错逐个排查。5.1 401 Unauthorized这是最常见的。报错长这样{error:{message:Unauthorized,type:invalid_request_error}}原因通常是三件套没配齐。检查顺序Base URL 是不是 https://taotoken.net/api Key 是不是从 API Keys 页面复制的完整串Model ID 是不是模型列表里的准确名称。特别注意 Key 有没有多余空格环境变量有没有 export 成功。用echo $TAOTOKEN_KEY确认一下。如果 Key 确认没问题还是 401检查请求头格式。必须是Authorization: Bearer keyBearer 后面有一个空格。wrk 脚本里我用的是Bearer .. os.getenv(TAOTOKEN_KEY)k6 里是模板字符串都别漏空格。5.2 local proxy failed这个报错通常出现在你本地配了转发规则但目标不可达时local proxy failed: dial tcp 127.0.0.1:7890: connect: connection refused排查方向确认你的压测机到 traefik 入口的网络是通的用curl -v https://traefik.example.com/health试一下。如果是集群内压测确认 Service 和 IngressRoute 的 match 规则对得上。另外检查环境变量里有没有残留的 HTTP_PROXY / HTTPS_PROXY 指向一个不存在的本地端口有的话 unset 掉。5.3 reading choices 类错误如果你压的是模型接口可能遇到error reading choices: unexpected end of JSON input这通常是响应体被截断或返回了非 JSON 内容。先用 curl 手动打一次看原始返回curl -s -X POST https://traefik.example.com/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_KEY \ -H Content-Type: application/json \ -d {model:your-model-id,messages:[{role:user,content:ping}]}如果返回的是 HTML 错误页说明请求没到后端被 traefik 或中间层拦了。检查 IngressRoute 的 match 规则和 service port 是否正确。5.4 OAuth 相关报错如果你用 Claude Code 或类似工具接入可能遇到 OAuth 报错。这类工具需要走 Anthropic 兼容入口配置三件套时 Base URL 要填对应的兼容地址Key 用 TaoToken 的凭证Model ID 填 Claude 系列名称。Claude Code 的接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有完整的 settings 配置示例。如果你用 CC Switch 或 Cline MCP 这类工具同样要保证 Base URL、Key、Model ID 三件套齐全。CC Switch 的配置一般在 settings.json 里Cline MCP 在 MCP 配置里Codex 在 auth.json 里。任何一个缺失都会导致鉴权失败。5.5 压测数据对不上还有一种情况wrk 报的 QPS 和 traefik 的 Prometheus 指标对不上。先检查时间窗口是否一致wrk 跑 60 秒Prometheus 查询用rate(...[1m])才对齐。再检查 traefik 的 metrics entryPoint 是否配对了如果 metrics 走的是单独的 entryPointPrometheus 抓取端口要和它一致。6. 可复现验证清单与后续接入把上面所有步骤整理成一份清单你可以照着逐项打勾。环境准备确认集群节点数和 CPU 核数记录 traefik 部署方式和副本数确认后端服务 Pod 数和资源 limit。这一步是为了后面分析瓶颈时有基线数据。接入配置在 TaoToken 控制台创建 Key确认 Base URL 为 https://taotoken.net/api 确认 Model ID。三件套写进环境变量用 curl 手动验证一次请求返回 200。traefik 配置打开 Prometheus metrics设置 serversTransport 的 maxIdleConnsPerHost确认 IngressRoute 的 strategy 字段。重启 traefik 后访问 /metrics 确认指标可抓取。压测执行先用 wrk 跑单并发基线再用 k6 跑阶梯并发记录每个并发档位的 QPS 和延迟分位数。同时打开 Grafana 看 traefik 服务端指标两边对齐。对比验证切换 IngressRoute 的 strategy 从 RoundRobin 到 Weighted重跑同一套脚本对比 QPS 和延迟差异。再对比走 traefik、直连 svc、走 nginx 三种路径。瓶颈定位如果 QPS 到顶但 CPU 打不满检查后端依赖数据库、缓存、外部 API的处理能力。用kubectl top node和kubectl top pod看资源水位确认瓶颈不在网关。这份清单跑完你对 traefik 在自己环境里的性能边界就有数了。后续如果要做长期编码或 Agent 类压测可以走 Coding Plan入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。需要管理多个 Key 或查看调用量去控制台 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。接入过程中遇到参数问题先查文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 大部分报错那里都有说明。最后说一个实用技巧压测脚本里的并发档位不要只跑一两个点至少覆盖 50、200、500、1000、2000 五档这样才能看出吞吐量拐点和延迟劣化的起点。我见过太多人只跑一个并发就下结论结果上线后并发一上来就崩。把曲线画出来瓶颈自然就暴露了。
阅读完成 · 觉得有帮助?