
前言系列写到现在我们搭建了网关集群、拆解了热更新原理、手写了限流插件。但很多同学问了一个更实际的问题“我们后端人手少能不能把认证、安全、日志这些通用逻辑全丢网关层后端只写业务”答案是能而且应该这样做。这篇文章我梳理了10 个高频场景对应的网关插件方案。每个方案都是一套可落地的配置放网关层处理后端零改动。本文用网关 G代称所有插件名为 demo 名称。总览一张图看懂┌──────────────────────────────────────────────────┐ │ 客户端请求 │ └─────────────────────┬────────────────────────────┘ ↓ ┌──────────────────────────────────────────────────┐ │ API 网关层 │ │ │ │ ① 安全防护层IP 黑白名单 → CORS → WAF │ │ ② 认证鉴权层Token/JWT/Key-Auth │ │ ③ 流量控制层限流 → 熔断 → 降级 │ │ ④ 协议转换层HTTP ↔ gRPC ↔ WebSocket │ │ ⑤ 内容改写层URL重写 → 请求/响应改写 │ │ ⑥ 可观测层日志 → 指标 → 链路追踪 │ │ │ ├──────────────────────────────────────────────────┤ │ 后端服务只写业务逻辑 │ └──────────────────────────────────────────────────┘六个层次十个核心插件全部配置即生效。场景一IP 黑白名单——把攻击挡在门外后端传统做法# 每个服务都要写一遍ALLOWED_IPS{10.0.0.0/8,172.16.0.0/12}ifrequest.remote_addrnotinALLOWED_IPS:return403,Forbidden问题每个服务都要写、IP 变更要改代码重启、无法统一管理。网关方案curlhttp://127.0.0.1:9080/apisix/admin/routes/demo-admin\-HX-API-KEY: demo-admin-key\-XPATCH-d { plugins: { ip-restriction: { whitelist: [ 10.0.0.0/8, 172.16.0.0/12, 203.0.113.50 ] } } }效果不在白名单内的请求直接返回 403后端感知不到这些请求。白名单外请求客户端 → 网关 → 403 → 到不了后端 白名单内请求客户端 → 网关 → 放行 → 后端正常处理场景二CORS 跨域——前端不再报红后端传统做法# 每个响应都要手动加 CORS 头response.headers[Access-Control-Allow-Origin]*response.headers[Access-Control-Allow-Methods]GET,POST,PUT,DELETEresponse.headers[Access-Control-Allow-Headers]Content-Type,Authorization问题一旦漏了一个接口前端就 CORS 报错排查半天。网关方案curlhttp://127.0.0.1:9080/apisix/admin/routes/demo-api\-HX-API-KEY: demo-admin-key\-XPATCH-d { plugins: { cors: { allow_origins: https://demo-app.example.com, allow_methods: GET,POST,PUT,DELETE,OPTIONS, allow_headers: Authorization,Content-Type,X-Request-Id, expose_headers: X-Request-Id,X-Response-Time, max_age: 3600, allow_credential: true } } }省掉的后端代码量每个接口 4-6 行 × N 个接口 几百行代码 无尽的调试时间。场景三JWT 认证——统一鉴权后端传统做法# 每个接口都要校验 Tokentokenrequest.headers.get(Authorization,).replace(Bearer ,)try:payloadjwt.decode(token,SECRET_KEY,algorithms[HS256])request.user_idpayload[sub]exceptjwt.ExpiredSignatureError:return401,Token expiredexceptjwt.InvalidTokenError:return401,Invalid token网关方案curlhttp://127.0.0.1:9080/apisix/admin/routes/demo-api\-HX-API-KEY: demo-admin-key\-XPATCH-d { plugins: { jwt-auth: { key: demo-jwt-key, secret: demo-secret-key-2026-xxxxxxxxxxxxxxxxxx } } }效果无 Token 或 Token 无效 → 网关直接返回 401 Token 有效 → 网关把 user_id 注入请求头 → 后端直接读 header后端代码简化为app.route(/api/user/profile)defprofile():user_idrequest.headers.get(X-User-Id)# 网关已经帮你验过了returnget_user_profile(user_id)省掉的后端代码量每个需要鉴权的接口 8-15 行 × 几十个接口 JWT 工具类维护。场景四Key-Auth——开放 API 的钥匙对外暴露给合作伙伴的 API用 JWT 太重了一个 API Key 就够。# 先创建消费者curlhttp://127.0.0.1:9080/apisix/admin/consumers\-HX-API-KEY: demo-admin-key\-XPUT-d { username: partner-demo, plugins: { key-auth: { key: demo-api-key-xxxxxxxxxxxxxx } } }# 路由上启用 key-authcurlhttp://127.0.0.1:9080/apisix/admin/routes/demo-open-api\-HX-API-KEY: demo-admin-key\-XPATCH-d { plugins: { key-auth: {} } }客户端只需curlhttp://demo-gateway.example.com/open-api/query\-Hapikey: demo-api-key-xxxxxxxxxxxxxx比在后端写 Key 验证省了多少一套 Key 管理后台 SQL 表 CRUD 接口 → 网关三行配置搞定。场景五统一限流——防止接口被刷这个我们在第四篇详细讲过这里直接给生产配置curlhttp://127.0.0.1:9080/apisix/admin/routes/demo-public-api\-HX-API-KEY: demo-admin-key\-XPATCH-d { plugins: { limit-count: { count: 100, time_window: 60, key_type: var, key: remote_addr, rejected_code: 429, rejected_msg: 请求太频繁请 60 秒后再试 }, limit-conn: { conn: 10, burst: 5, default_conn_delay: 0.5, key_type: var, key: remote_addr } } }两层限流limit-count请求频率限流100 次/分钟limit-conn并发连接数限流同时最多 10 个连接后端零代码接口安全防护一步到位。场景六熔断降级——保护后端不被压垮后端传统做法# 需要引入熔断器库比如 PyBreakercircuit_breaker(fail_max3,timeout30)defcall_downstream_service():returnrequests.get(http://other-service/api/data)网关方案curlhttp://127.0.0.1:9080/apisix/admin/upstreams/demo-upstream\-HX-API-KEY: demo-admin-key\-XPATCH-d { checks: { active: { type: http, http_path: /health, timeout: 3, concurrency: 10, healthy: { interval: 5, successes: 2 }, unhealthy: { interval: 5, http_failures: 3, timeouts: 3 } } }, retries: 2, retry_timeout: 5 }效果后端节点连续失败 3 次 → 网关自动标记为不可用不可用期间请求自动路由到健康的节点节点恢复后自动上线后端一行不用改高可用由网关保障。场景七URL 重写——平滑迁移旧接口后端要重构接口但前端没法同步改网关帮你无缝切换curlhttp://127.0.0.1:9080/apisix/admin/routes/demo-legacy-api\-HX-API-KEY: demo-admin-key\-XPUT-d { uri: /v1/users/*, plugins: { proxy-rewrite: { uri: /api/v2/users/$1, regex_uri: [/v1/users/(.*), /api/v2/users/$1] } }, upstream: { type: roundrobin, nodes: { demo-backend-v2:8080: 1 } } }映射关系客户端请求网关转发给后端/v1/users/123/api/v2/users/123/v1/users/456/profile/api/v2/users/456/profile前端不用改、客户端不用升级、后端自由重构。场景八响应改写——数据脱敏 统一格式后端返回的数据需要脱敏不需要改业务代码curlhttp://127.0.0.1:9080/apisix/admin/routes/demo-user-api\-HX-API-KEY: demo-admin-key\-XPATCH-d { plugins: { response-rewrite: { body: [ { action: regex_replace, regex: \\phone\\:\\([0-9]{3})([0-9]{4})([0-9]{4})\\, replace: \\phone\\:\\$1****$3\\ } ], headers: { add: { X-Response-Time: $upstream_response_time, X-Served-By: demo-gateway-node-1, X-Content-Type-Options: nosniff }, remove: [ X-Powered-By, Server, X-Internal-Debug ] } } } }效果后端返回{phone: 13812345678, ...} ↓ 网关脱敏 客户端收到{phone: 138****5678, ...}同时自动注入的响应头请求耗时、网关节点、安全头——后端一行代码都没写。场景九统一日志——请求审计不留死角后端每个接口写日志太麻烦网关一次搞定curlhttp://127.0.0.1:9080/apisix/admin/routes/demo-audit-api\-HX-API-KEY: demo-admin-key\-XPATCH-d { plugins: { http-logger: { uri: http://demo-log-service:8000/ingest, batch_max_size: 100, max_retry_count: 3, retry_delay: 1, include_req_body: true, include_resp_body: false }, file-logger: { path: /var/log/demo-gateway/access.log, log_format: { time: $time_iso8601, remote_addr: $remote_addr, method: $request_method, uri: $uri, status: $status, upstream_addr: $upstream_addr, request_time: $request_time, upstream_response_time: $upstream_response_time, user_agent: $http_user_agent, request_id: $http_x_request_id } } } }每条请求自动记录{time:2026-06-05T10:30:1208:00,remote_addr:203.0.113.100,method:POST,uri:/api/users,status:201,upstream_addr:demo-backend-1:8080,request_time:0.045,upstream_response_time:0.038,user_agent:Demo-Client/2.0,request_id:a1b2c3d4e5f6}后端需要写什么零。网关把审计日志投递到日志服务后端甚至不知道日志的存在。场景十简易灰度发布——新版本先跑 10% 流量不需要 Service Mesh不用改 K8s 配置网关直接搞定curlhttp://127.0.0.1:9080/apisix/admin/routes/demo-canary\-HX-API-KEY: demo-admin-key\-XPUT-d { uri: /demo/product/*, upstream: { type: chash, hash_on: header, key: X-Canary-User, nodes: { demo-backend-stable:8080: 9, demo-backend-canary:8080: 1 } } }流量分配90% 走稳定版10% 走金丝雀版本。配合条件路由还能做得更精细# 规则 1优先匹配——白名单用户走金丝雀curlhttp://127.0.0.1:9080/apisix/admin/routes/demo-canary-beta\-HX-API-KEY: demo-admin-key\-XPUT-d { uri: /demo/product/*, vars: [[http_x_canary_user, , true]], priority: 10, upstream: { nodes: {demo-backend-canary:8080: 1} } }# 规则 2兜底匹配——普通用户走稳定版curlhttp://127.0.0.1:9080/apisix/admin/routes/demo-canary-default\-HX-API-KEY: demo-admin-key\-XPUT-d { uri: /demo/product/*, priority: 0, upstream: { nodes: {demo-backend-stable:8080: 1} } }进阶按用户 ID 哈希的金丝雀curlhttp://127.0.0.1:9080/apisix/admin/routes/demo-canary-uid\-HX-API-KEY: demo-admin-key\-XPATCH-d { upstream: { type: chash, hash_on: header, key: X-User-Id, nodes: { demo-backend-stable:8080: 90, demo-backend-canary:8080: 10 } } }同一用户始终落在同一版本不会出现同一用户一会儿看到新版、一会儿看到旧版的问题。一张表总结十个场景 vs 后端代码量场景网关插件配置行数省掉的后端代码IP 黑白名单ip-restriction8 行每个服务一个中间件~30行 × N 个服务CORScors7 行每个接口手动加头~6行 × 几十个接口JWT 认证jwt-auth5 行装饰器/中间件 JWT 工具类~100行API Keykey-auth3 行Key 管理后台 校验逻辑~200行限流limit-count8 行每个接口的限流逻辑~20行 × N 个接口熔断降级active health check15 行熔断器库引入 集成代码~80行URL 重写proxy-rewrite6 行Nginx 配置变更 后端兼容代码响应改写response-rewrite10 行每个接口的脱敏/格式化代码统一日志http-logger12 行每个接口的日志打点~5行 × N 个接口灰度发布chash upstream8 行K8s Istio 配置 / 自研流量调度系统合计10 个插件~80 行配置数百到数千行后端代码组合实战一条路由挂 5 个插件把上面多个场景拼在一起一条路由搞定安全 鉴权 限流 日志 版本分流curlhttp://127.0.0.1:9080/apisix/admin/routes/demo-full-stack\-HX-API-KEY: demo-admin-key\-XPUT-d { name: demo-full-stack-route, uri: /api/business/*, methods: [GET, POST, PUT, DELETE], plugins: { ip-restriction: { whitelist: [10.0.0.0/8] }, cors: { allow_origins: https://demo-app.example.com, allow_methods: GET,POST,PUT,DELETE, allow_headers: Authorization,Content-Type }, jwt-auth: { key: demo-jwt-key, secret: demo-jwt-secret }, limit-count: { count: 200, time_window: 60, key_type: var, key: http_x_user_id }, response-rewrite: { headers: { add: { X-Request-Id: $request_id, X-Response-Time: $upstream_response_time }, remove: [X-Powered-By, Server] } } }, upstream: { type: roundrobin, nodes: { demo-backend-stable:8080: 9, demo-backend-canary:8080: 1 } } }请求到达网关后的处理顺序1. IP 校验 → 不在白名单 → 403后端无感知 2. CORS 处理 → 跨域请求自动响应 OPTIONS 3. JWT 鉴权 → Token 无效 → 401 4. 限流检查 → 超阈值 → 429提示稍后重试 5. 金丝雀分流 → 10% 流量走 canary 版本 6. 响应头注入 → X-Request-Id / X-Response-Time后端只收到合法、未超限、已完成分流的请求。它要做的只有业务逻辑。运维小贴士1. 插件执行顺序调试如果不确定插件的执行顺序可以在网关日志中开启 debug 模式nginx_config:error_log_level:debug日志中会看到每个插件的执行记录[debug] plugin: ip-restriction, phase: access, result: allow [debug] plugin: cors, phase: access, result: allow [debug] plugin: jwt-auth, phase: rewrite, result: allow [debug] plugin: limit-count, phase: access, result: allow (count12/200)2. 插件性能关注并非所有插件都零开销以下插件对性能影响较大需要关注插件类型性能影响原因复杂正则路由匹配低前缀树已优化JWT 验证低毫秒级限流计数极低纯内存操作请求体日志高需要缓冲请求体大正则响应改写高需要缓冲并扫描响应体WAF 规则中正则匹配开销3. 插件全局启用 vs 路由级启用# 全局规则所有路由都生效curlhttp://127.0.0.1:9080/apisix/admin/global_rules/1\-HX-API-KEY: demo-admin-key\-XPUT-d { plugins: { prometheus: {}, response-rewrite: { headers: { add: { X-Gateway-Node: demo-gateway-01 } } } } }原则全局监控指标、通用安全头、统一响应头路由级认证、限流、灰度发布不同路由策略不同总结这篇文章的核心观点就一句话让网关做基础设施的事让后端做业务的事。十个场景的配置我都写好了直接改参数就能用到你们的项目里。不用感谢点赞收藏就是最好的鼓励如果这篇文章让你少写了两百行代码请务必点赞 收藏 关注三连