EMQX 是一款高性能、分布式的 MQTT 消息服务器,广泛应用于物联网、车联网等领域。在大规模消息传输场景中,限流机制对于保障系统稳定性和吞吐量至关重要。
本文基于 EMQX v5.8.2 版本,深入探讨其限流机制的实际表现和潜在问题。
notion image
 

1、SUB订阅消息的限流

EMQX 的限流机制不仅针对发布消息,同样适用于订阅消息。当客户端的订阅速率超过设定阈值时,服务器会暂停接收该客户端的消息,直至速率恢复到允许范围内。
notion image
甚至,MQTT PING包也是收限流影响。
notion image

2、限流消息的缓存处理

触发限流后,积压消息过多,会导致发布端已经离线一段时间,但接收端仍能收到消息。
当客户端发送消息的速率超过设定限制时,超出的消息不会被立即丢弃,而是暂存于服务器的缓存中。这意味着,即使发布端已离线一段时间,接收端仍可能收到之前缓存的消息。这种处理方式在一定程度上实现了“削峰填谷”,但也可能导致消息延迟或积压。
notion image

3、限流配置的生效条件

在 EMQX 后台直接修改限流配置后,新的设置不会立即对现有连接生效。需要客户端重新连接尽管后台提示可能断开现有连接,但实际上在v5.8.2版本并不会主动触发重连。
notion image
notion image
但是对于v5.3.1版本,在后台更新限流配置后,是会触发客户端断连的。
notion image

4、限流下客户端在线状态的异常

当触发限流的客户端异常断开连接(例如直接断电)后, 在EMQX后台页面,即使已经超过了心跳检测时间,仍然会显示设备在线。
notion image
notion image
直到缓存中的消息发送完后,才会提示设备下线,如果此时监听系统的设备上下线TOPIC,可以收到下线消息。
notion image

5、发布端限流速率的平滑性问题

在实际测试中,设置较低的限流速率(如每秒 5 条消息)时,EMQX 的限流器可能无法平滑工作,导致消息处理出现间歇性停顿。官方解释称,受实现限制,速率设置过低时(≤10/s),限流器难以平稳运行。可以通过下面几个例子直观看到。

5.1 端口不限制

消息流入90条/s
notion image
notion image
修改限流的客户端都是1883端口,订阅客户端连接的8883端口
notion image
 

5.2 端口限流50/s

notion image
notion image
限流一段时间后,看dashboard页面,50/s 看起来效果更像20/s
notion image
限流的触发可以通过日志查看到。
notion image
 

5.3 端口限流20/s

notion image
notion image

6、订阅方接收消息的不平滑性

当发送方触发限流时,订阅方接收到的消息可能会出现不平滑的情况,即消息会在一段时间后批量这种现象可能与消息在服务器端的缓存和处理机制有关。
notion image
 
 

附:官方的一些解释与说明

notion image
notion image
notion image
 
 

7、突发流量验证分析

在突发流量场景下,EMQX 限流机制的表现尤为关键,特别是对于物联网场景中可能出现的高频数据上传需求。以下是基于 EMQX v5.3.1 的测试结果与分析:
notion image

实验设计与现象

  1. 测试条件与预期:
      • 初始流量配置:客户端设置为首次突发 1000 条消息,然后每秒 10 条,每 10 秒突发发送 500 条消息。
      notion image
      notion image
       
      • 预期:在未触发限流的情况下,10 秒内共发送 600 条消息,符合测试预期。
notion image
  1. 调整限流配置:
  • 配置路径:/opt/emqx/data/configs/cluster.hocon
  • 配置限流参数:
 
  • 设置后:限流机制开始生效,首次触发在发送 ID 接近 500 的时候。
notion image
notion image
 
  1. 进一步测试:
  • 改小客户端突发流量:即便减少突发流量,仍然触发限流。
notion image
notion image
 
notion image
 
客户端突发流量改到100,仍然会触发限流
notion image
notion image
notion image
 
  • 删除突发流量配置:尽管移除突发配置,仍观察到限流现象,部分消息出现延迟。
notion image
notion image
notion image
 

附:突发和初始桶配置的演变分析

EMQX 的限流配置在不同版本间经历了多次演变,尤其是关于突发流量和初始桶的配置方式发生了显著变化。以下是根据官方资料对相关配置变更的时间线梳理。
1、5.0.23 之前的版本配置
允许用户对消息和字节流的突发量和初始容量进行细粒度控制。示例配置:
 
2、 5.0.23 及之后的版本限流配置字段名有修改
notion image
 
3、5.0.25 版本新增简化的流控配置
开始支持 limiter.messages_rate = 1000/s 简化的流控配置
notion image
 
4、近期版本删除对于突发流量配置说明
为了降低配置复杂度,并简化用户体验,近期在官方的所有配置文档中,都删除了关于突发流量的相关配置说明。
社区讨论: 移除突发配置说明
notion image
 

拓展总结

总体来看,EMQX 的限流功能在一定程度上能够满足基本的流量控制需求,但在物联网场景中,可能能有一些问题:
1. 限流效果有限
  • 针对物联网设备常见的低速率场景(如每秒 10 条消息)的限流需求,EMQX 的效果并不理想,表现为速率控制不平滑、消息延迟加剧等问题。
  • 当限流策略触发时,可能导致客户端重连,进一步增加服务器负载,甚至引发连锁异常问题,例如设备在线状态的不一致。
2. 延迟与消息堆积问题
  • 当前限流机制下,EMQX 缺乏直接丢弃超限消息的配置选项。所有超限消息均被存入缓存,导致延迟问题严重,特别是在突发流量较高的场景中表现尤为突出。
  • 延迟问题不仅影响用户体验,还可能对时间敏感型应用(如实时监控、告警系统)带来业务风险。
3. 突发流量控制的局限性
  • 从官方态度和实际表现来看,突发流量配置运行效果较差,未能有效解决突发情况下的流量平滑问题。更重要的是,部分突发流量控制的配置已在最新版本中移除,表明官方更倾向于简化限流策略,减少复杂配置的支持。
  • 不同版本间限流配置的变更较大,升级到新版本后可能需要重新验证配置的有效性,增加了维护和迁移成本。
4. 最新版本对限流的支持
  • 根据官方文档,最新版本已大幅简化限流配置语法,并移除了部分功能。虽然这降低了配置复杂度,但也可能限制用户的自定义能力,使其在特定场景下不再适用。
  • 对于需要细粒度流量控制的场景,如特定设备的大量突发消息处理,最新版本可能并不能很好地满足需求。
5. 添加限流配置需谨慎
  • 限流配置的目标是提升系统的稳定性,但在 EMQX 当前的实现下,错误或不当的配置可能带来更多不可预测的问题,如设备掉线、消息堆积、重连风暴等。
  • 如果确实需要添加限流配置,应在充分测试的基础上合理设置参数,同时考虑通过外围方案(如消息队列或负载均衡器)辅助分流,以降低对 EMQX 本身的压力。
6. 实践建议
  • 对于低速率和突发流量场景,建议优先考虑外围缓冲与异步处理(如 Kafka、Redis 等)。
  • 升级到新版本前,应全面评估限流配置的兼容性,并进行压力测试,验证新配置的效果。
  • 在限流策略设计中,应结合具体业务场景,权衡延迟与数据完整性之间的取舍。如果实时性要求较高,优先考虑丢弃策略替代缓存。
 
关于我最近一周用iphone前置摄像头扫描的事设备MQTT连接异常?问题定位与EMQX限流机制详解
Loading...