音视频和AI推理服务的流量特征非常特殊:单请求耗时长、带宽占用大、对延迟极其敏感,同时涉及转码、识别、合成等昂贵计算资源。这类服务一旦直接暴露给客户端,后果往往是被恶意刷接口、密钥泄露或者后端GPU节点被打爆。API网关作为所有请求的唯一入口,需要在鉴权、限流和负载均衡三个环节做针对性设计,而不是简单套用普通Web服务的通用配置。

鉴权设计:从静态密钥到短期签名令牌
最不可取的做法是把长期有效的API Key直接放在客户端请求参数里传递。音视频客户端往往运行在浏览器、手机App甚至嵌入式设备上,任何抓包或反编译都能拿到密钥,一旦泄露就需要全量更换,影响所有用户。成熟的方案是参照云厂商的对象存储鉴权模式,采用HMAC签名配合短期令牌。
具体流程是:客户端向业务服务器申请一个有时效的凭证,凭证中包含过期时间戳、允许访问的资源路径和权限范围,服务端用密钥对这些信息做HMAC-SHA256签名后下发。客户端每次调用网关时携带凭证,网关用同样的密钥重新计算签名并校验时效。这样即使凭证被截获,攻击窗口也只有几分钟。下面是一个用Python生成签名凭证的示例:
import hmac
import hashlib
import time
import base64
SECRET = "your_server_side_secret"
def generate_token(user_id, resource, expire_seconds=300):
expire = int(time.time()) + expire_seconds
message = f"{user_id}|{resource}|{expire}".encode("utf-8")
digest = hmac.new(SECRET.encode("utf-8"), message, hashlib.sha256).digest()
return base64.urlsafe_b64encode(digest).decode(), expire
def verify_token(user_id, resource, expire, signature):
if expire < int(time.time()):
return False # 令牌已过期
message = f"{user_id}|{resource}|{expire}".encode("utf-8")
expected = base64.urlsafe_b64encode(
hmac.new(SECRET.encode("utf-8"), message, hashlib.sha256).digest()
).decode()
return hmac.compare_digest(expected, signature)
需要注意两点:一是签名内容必须覆盖资源路径,防止用户拿A资源的凭证去访问B资源;二是校验时使用hmac.compare_digest而不是普通的字符串相等比较,避免时序攻击。另外,密钥应存储在网关侧的配置中心或KMS中,定期轮换,并保留至少两把同时有效的密钥以实现平滑过渡。
限流策略:针对流媒体特征的算法选择
通用接口的限流常用固定窗口计数,比如每分钟最多100次请求。但音视频接口有两个特殊性:一是单请求成本差异巨大,一次实时转码调用的资源消耗可能是一次音频切片的一百倍;二是流式连接持续时间长,按请求数限流意义有限。因此限流维度需要从请求数扩展到并发数、带宽和令牌消耗。
推荐采用令牌桶算法结合多维度计数。令牌桶允许突发流量,符合音视频推流时短暂的高码率突增;同时按用户维度维护并发连接数上限,防止单个用户长期占用推流通道。如果网关基于OpenResty或Kong,可以用lua-resty-limit-traffic库实现组合限流:
local limit_req = require "resty.limit.req"
local limit_count = require "resty.limit.count"
-- 每秒允许100个请求,突发容量200
local lim1, err = limit_req.new("limit_req_store", 100, 200)
-- 每用户每分钟最多60次AI识别调用
local lim2, err = limit_count.new("limit_count_store", 60, 60)
local user_id = ngx.var.arg_uid
local delay, err1 = lim1:incoming(user_id, true)
local count, err2 = lim2:incoming("ai_api_" .. user_id, true)
if not delay or not count then
ngx.status = 429
ngx.say("rate limit exceeded, retry later")
return ngx.exit(429)
end
对于AI推理类接口,还可以引入成本计费式限流:每次调用根据模型类型和时长消耗不同数量的配额,配额存储在Redis中用Lua脚本原子扣减。这样做的好处是把限流粒度对齐到真实成本,避免出现轻量请求被严格限制、重量请求却大量放行的情况。同时务必为不同等级的用户或租户设置独立限额,网关侧按API Key前缀路由到不同的限流规则。
负载均衡:会话保持与就近调度
音视频服务对负载均衡的第一要求不是绝对均匀,而是会话一致性。一个RTMP推流连接或一个WebRTC会话一旦建立,后续数据包必须持续发往同一后端节点,否则会话状态丢失会导致断流。因此轮询策略只适合无状态的API请求,对长连接流量应采用一致性哈希,哈希键可以选用户ID或会话ID。
第二个关键点是容量感知调度。AI音视频后端通常是异构的:有的节点带GPU跑推理,有的只是CPU节点做转发。网关需要从后端健康检查接口中获取实时负载指标,比如GPU显存占用、当前并发流数量,然后按权重分配。以Nginx配置为例:
upstream media_backend {
# 一致性哈希保持会话
hash $arg_session_id consistent;
# GPU节点承载更高权重
server 10.0.1.10:8080 weight=5 max_conns=200;
server 10.0.1.11:8080 weight=5 max_conns=200;
server 10.0.1.12:8080 weight=1 max_conns=500;
# 健康检查失败自动摘除
server 10.0.1.13:8080 backup;
}其中max_conns限制单节点最大并发连接数,超出后新请求自动转移到其他节点,这是保护GPU节点不被压垮的最后一道防线。此外,如果服务覆盖多地域用户,应在DNS或全局负载均衡层做地理就近接入,将拉流请求调度到边缘节点,只把AI推理等必须回源的计算请求转发到中心集群,这样能把端到端延迟降低几十到上百毫秒。
最后提醒一个容易被忽视的问题:网关自身的过载保护。当后端整体过载时,网关应主动启用排队或快速失败机制,返回明确的错误码和Retry-After头,而不是无限堆积请求导致自身内存耗尽。把鉴权、限流、负载均衡三个环节串联起来形成完整的流量防护链路,AI音视频服务才能在高并发场景下保持稳定。