MQTT数据桥接

整体方案

当前 EMQX 中的 MQTT 通信数据均通过程序中日志打印的方式查看,查阅和筛选极其不方便;另外当数据丢失时,日志中无法体现。我们需要将经过 MQTT 服务的所有消息记录下来,做数据的持久化,方便未来的问题定位
在这里插入图片描述
新的 EMQX 开源版本(5.0.13)支持了数据桥接功能,我们通过 webhookde 的数据桥接的方式将 MQTT 消息发送到 Web 服务,由 Web 服务存入数据库中。
目前 EMQX 开源版本不支持将消息直接转存到 MySql。

桥接服务

桥接服务主要接受来自 EMQX 推送的消息,中转后存入 MySql 数据库

数据表设计

CREATE TABLE mqtt_message_log(
    id BIGINT NOT NULL   COMMENT 'ID' ,
    client_id VARCHAR(511) NULL   COMMENT '客户端ID' ,
    from_client_id VARCHAR(511) NULL   COMMENT '来源客户端ID' ,
    topic VARCHAR(511) NULL   COMMENT '主题' ,
    payload JSON NULL   COMMENT '报文内容' ,
    event VARCHAR(32) NULL   COMMENT '事件' ,
    reason VARCHAR(32) NULL   COMMENT '原因' ,
    revision INT NULL   COMMENT '乐观锁' ,
    created_by VARCHAR(32) NULL   COMMENT '创建人' ,
    created_time timestamp(3) NULL   COMMENT '创建时间' ,
    updated_by VARCHAR(32) NULL   COMMENT '更新人' ,
    updated_time timestamp(3) NULL   COMMENT '更新时间' ,
    PRIMARY KEY (id)
) COMMENT = 'MQTT消息日志 ';

BridgeController接口定义及处理

我们从 body 中获取 payload 的数据,其它信息从消息头中获取,解包方式依赖EMQX 的数据桥接配置中的数据包装,下文中会讲。

@RestController
public class BridgeController {

    @Autowired
    IMqttMessageLogService mqttMessageLogService;
    @PostMapping
    public void test(@RequestBody JSONObject payload,
                     @RequestHeader(name = "client-id") String clientId,
                     @RequestHeader(name = "topic") String topic,
                     @RequestHeader(name = "event") String event,
                     @RequestHeader(name = "from-client-id") String fromClientId,
                     @RequestHeader(name = "reason") String reason
    ) {

        MqttMessageLog message=new MqttMessageLog();
        message.setClientId(clientId);
        message.setFromClientId(fromClientId);
        message.setReason(reason);
        message.setPayload(payload);
        message.setEvent(event);
        message.setTopic(topic);
        mqttMessageLogService.save(message);
    }
}

MqttMessageLog 实体类

@Getter
@Setter
@TableName("mqtt_message_log")
@ApiModel(value = "MqttMessageLog对象", description = "")
public class MqttMessageLog implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty("ID")
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;

    @ApiModelProperty("客户端ID")
    @TableField("client_id")
    private String clientId;

    @ApiModelProperty("来源客户端ID")
    @TableField("from_client_id")
    private String fromClientId;

    @ApiModelProperty("主题")
    @TableField("topic")
    private String topic;

    @ApiModelProperty("报文内容")
    @TableField(value = "payload", typeHandler = JacksonTypeHandler.class)
    private JSONObject payload;

    @ApiModelProperty("事件")
    @TableField("event")
    private String event;

    @ApiModelProperty("原因")
    @TableField("reason")
    private String reason;

    @ApiModelProperty("乐观锁")
    @TableField("revision")
    @Version
    private Integer revision;

    @ApiModelProperty("创建人")
    @TableField(value = "created_by", fill = FieldFill.INSERT)
    private String createdBy;

    @ApiModelProperty("创建时间")
    @TableField(value = "created_time", fill = FieldFill.INSERT)
    private LocalDateTime createdTime;

    @ApiModelProperty("更新人")
    @TableField(value = "updated_by", fill = FieldFill.UPDATE)
    private String updatedBy;

    @ApiModelProperty("更新时间")
    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
    private LocalDateTime updatedTime;


}

MQTT 配置持久化

因为我们需要配置数据桥接与规则,因此这些配置信息我们需要持久化出来,否则在 EMQX 服务重启会丢失这些信息。
MQTT数据桥接与规则信息存储在/opt/emqx/data 中

mkdir -p /data/emqx
docker cp emqx:/opt/emqx/data /data/emqx
chown -R 1000:1000 /data/emqx/
chmod -R 755 /data/emqx/

卷挂载

-v /data/emqx/data:/opt/emqx/data

MQTT 数据桥接配置

配置数据桥接
在这里插入图片描述

创建规则,并选择动作(刚刚配置数据桥接)
在这里插入图片描述

桥接服务的部署

因为交接服务与 EMQX 深度依赖,因此,我们将 EMQX 和桥接服务放在同一个 pod 内,这样部署的另外一个好处是 EMQX 通过访问 127.0.0.1 即可访问桥接服务
在这里插入图片描述

参考资料

https://www.emqx.io/docs/zh/v5.0/data-integration/introduction.html#%E6%95%B0%E6%8D%AE%E6%A1%A5%E6%8E%A5
https://blog.youkuaiyun.com/qq_45894067/article/details/125045183
https://199604.com/2270

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值