5.0.2x 版本 Webhook 桥接客户端上下事件状态不一致问题

你是对的,我用异步的方式复现了这个问题。

场景一

使用你提供的配置方式创建 Webhook 桥接;并使用 11个线程异步发起 clientid 为 emqtt 的连接请求,

第一列是事件到达Webserver 的时间,第二列是 clientid, 第三列是 event, 第四列是 disconnected 事件中的断开原因。

  • 可以看到由于是同名 ClientID 快速的重复登录,connected 事件和 disconnected 事件到达 Webserver 的顺序是乱序的。
  • 最后一条连接会故意保持 10s 后在掉线;这样如果倒数第二条的事件是 disconnected 那么观察到 Webserver 和 EMQX 的客户端在线状态就会表现为不一致

场景二

把 Webhook桥接配置中的
Connection Pool Size, Buffer Pool Size 都设置为 1

此时可以看到上下线顺序是正确的了

结论

在单节点的 EMQX下,EMQX 内部产生的 connected, disconnected 事件是有序的;但由于桥接在做事件转发时使用了异步+进程池的方式写入到对端服务;所以可能会导致事件到达 Webserver 时出现乱序。

解决方法

临时方案一:将 Webhook 的 Query mode 设为 sync ,以同步的方式发送事件,避免乱序。
临时方案二:Query mode 仍为异步 async,但将 Connection Pool Size, Buffer Pool Size 都设置为 1 避免多通道产生到达不一致问题。

优化建议: EMQX 可以在 Webhook Bridge 中的异步模式提供一种策略,来保证来自同一个客户端ID的消息都从同一条 HTTP 连接发送出去,避免异步和多链路产生的不一致问题。 cc @Benniu @wivwiv @stone