Azure API Management WebSocket限流及日志需求咨询
Azure API Management 中 WebSocket 连接与消息管控方案
针对你提出的三个WebSocket管控需求,Azure API Management(APIM)均可通过内置策略或组合策略实现,具体方案如下:
1. 限制每个用户/API密钥的并发WebSocket连接数
APIM没有直接的内置并发连接计数功能,但可以通过缓存策略结合握手阶段的逻辑判断实现该需求:
- 在WebSocket握手请求(
onHandshake触发器)中,提取用户标识(如API密钥对应的订阅ID、用户ID)作为缓存键 - 从APIM内置缓存中查询当前用户的连接计数,若未达到上限则递增计数并允许握手;若已达上限则拒绝连接
- 在连接关闭时(
onClose触发器),递减缓存中的计数,释放连接配额
示例策略片段:
<policies> <inbound> <base /> <!-- 提取用户标识,这里用订阅ID作为示例 --> <set-variable name="userId" value="@(context.Subscription.Id)" /> <!-- 查询当前连接数 --> <cache-lookup-value key="@(context.Variables["userId"])" variable-name="currentConnections" default-value="0" /> <!-- 判断是否超过连接上限(示例设为5) --> <choose> <when condition="@(int.Parse(context.Variables["currentConnections"].ToString()) >= 5)"> <set-status code="429" reason="Too Many Connections" /> <return-response> <set-body>{"error": "Maximum concurrent connections exceeded"}</set-body> </return-response> </when> <otherwise> <!-- 递增连接数并存入缓存,过期时间设为连接超时时间(示例30分钟) --> <cache-store-value key="@(context.Variables["userId"])" value="@(int.Parse(context.Variables["currentConnections"].ToString()) + 1)" duration="1800" /> </otherwise> </choose> </inbound> <outbound> <base /> </outbound> <on-close> <!-- 连接关闭时递减计数 --> <cache-lookup-value key="@(context.Subscription.Id)" variable-name="currentConnections" default-value="1" /> <cache-store-value key="@(context.Subscription.Id)" value="@(int.Parse(context.Variables["currentConnections"].ToString()) - 1)" duration="1800" /> </on-close> </policies>
2. 限制单条WebSocket连接的消息发送速率
APIM的rate-limit-by-key策略可用于针对单条连接限制消息速率,核心是将连接ID(context.ConnectionId)作为限流的唯一键,在onMessage触发器中应用该策略:
示例策略片段:
<policies> <on-message> <base /> <!-- 限制单条连接每分钟最多发送10条消息 --> <rate-limit-by-key calls="10" renewal-period="60" counter-key="@(context.ConnectionId)"> <set-status code="429" reason="Message Rate Limit Exceeded" /> <return-response> <set-body>{"error": "Message rate limit exceeded"}</set-body> </return-response> </rate-limit-by-key> </on-message> </policies>
注意:若需更精细的速率控制(如令牌桶算法),可结合自定义策略或外部速率控制服务实现。
3. 提取并记录WebSocket消息到EventHub
APIM的log-to-eventhub策略可直接在onMessage触发器中捕获消息内容,并发送至预先配置的EventHub:
- 先在APIM中创建EventHub类型的日志记录器,配置好EventHub连接字符串和名称
- 在
onMessage触发器中编写策略,序列化消息内容、用户信息、连接ID等元数据后发送至EventHub
示例策略片段:
<policies> <on-message> <base /> <!-- 将消息内容及元数据序列化后发送到EventHub --> <log-to-eventhub logger-id="my-eventhub-logger"> @{ return Newtonsoft.Json.JsonConvert.SerializeObject(new { MessageContent = context.Request.Body.As<string>(), ConnectionId = context.ConnectionId, UserId = context.User?.Id ?? "anonymous", Timestamp = DateTime.UtcNow.ToString("o") }); } </log-to-eventhub> </on-message> </policies>
该策略会自动将每条非握手阶段的WebSocket消息结构化记录到EventHub,后续可通过Azure Monitor、Stream Analytics等服务进行分析或持久化存储。
内容的提问来源于stack exchange,提问作者Shunsuke
相关产品推荐
相关产品推荐

