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

环境

  • EMQX 版本:5.0.X
  • 操作系统版本:

我使用了5.0.2X 任意版本 webhook的上下线都会通知不稳定,我应该怎么修复?或者怎么配置下?
附上日志:

1 个赞

看日志是和 Webhook 没有关系的。你是怎么判断上下线通知不稳定的?

  1. 指定了上下线后webhook:

    SELECT * FROM
    “$events/client_connected”,
    “$events/client_disconnected”

  2. 发送给web服务端 clientId 和 event
    {
    “clientId”:“${clientid}”,
    “event”:“${event}”
    }
    3.服务端接收后
    判断如果event==client.connected 就是上线
    判断如果event==client.disconnected就是下线

如果我登录dashaboard控制台立马把客户端全部踢掉,重新登录上去,webhook都是正确的值,但是就是半夜机器的重新连接,给的值就是错误的

这个总是不准确,是event给的值不准确吗?需要获取其他值?

我现在怀疑是webhook发送没问题,但是发送的event值有问题,还可以加什么辅助判断吗?

稍等还需要在检查下

  1. 方便在给下具体的 EMQX 版本号、Webhook和规则 所有配置的截图么?
  2. EMQX 部署的方式(是几个节点集群、然后前面做负载均衡么?)
  3. Webhook 的请求方式(配置的 webhook 地址到服务端是只有一个节点么?还是多个节点做了负载均衡)
  1. 目前版本号5.0.24(5.0.21 22 我都使用过,同样的问题)
    数据桥接配置基本都是默认,只修改了HTTP URL 和请求体

规则:

  1. 部署方式docker部署,单体,没有集群
  2. webhook只有一个节点,而且都是在同一个服务器环境

注意:请求模式是异步,异步容易出问题,昨天晚上改成同步后暂时没发现问题了。

1 个赞

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

场景一

使用你提供的配置方式创建 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