mica-mqtt 1.2.0 发布完善集群功能

一、简介

mica-mqtt 基于 t-io 实现的简单低延迟高性能 的 mqtt 物联网开源组件。使用详见 mica-mqtt gitee 源码 mica-mqtt-example 模块

mica-mqtt 更加易于集成到已有服务和二次开发,降低自研物联网平台开发成本。

二、功能

  • 支持 MQTT v3.1、v3.1.1 以及 v5.0 协议。
  • 支持 websocket mqtt 子协议(支持 mqtt.js)。
  • 支持 http rest api,http api 文档详见
  • 支持 MQTT client 客户端。
  • 支持 MQTT server 服务端。
  • 支持 MQTT 遗嘱消息。
  • 支持 MQTT 保留消息。
  • 支持自定义消息(mq)处理转发实现集群。
  • MQTT 客户端 阿里云 mqtt 连接 demo。
  • 支持 GraalVM 编译成本机可执行程序。
  • 支持 Spring boot 项目快速接入(mica-mqtt-spring-boot-starter)。
  • mica-mqtt-spring-boot-starter 支持对接 Prometheus + Grafana。
  • 基于 redis pub/sub 实现集群,详见 mica-mqtt-broker 模块

三、使用场景

  • 物联网(云端)
  • 物联网(边缘端)
  • 群组类 IM
  • 消息推送

四、待办

  • 优化处理 mqtt session,以及支持部分 mqtt v5.0 新特性。
  • 基于 easy-rule + druid sql 解析,实现规则引擎。

五、更新记录

  • :sparkles: mqtt-mqtt-core client IMqttClientConnectListener 添加 onDisconnect 方法。gitee #I4JT1D 感谢 @willianfu 同学反馈。
  • :sparkles: mica-mqtt-core server IMqttMessageListener 接口调整,不兼容老版本。
  • :sparkles: mica-mqtt-broker 调整上下行消息通道。
  • :sparkles: mica-mqtt-broker 添加节点管理,抽象业务层,方便接入,后续版本会对接规则引擎。
  • :sparkles: mica-mqtt-broker 调整默认的 Message 序列化方式,不兼容老版本。
  • :sparkles: mica-mqtt-broker 优化设备上下线,处理节点停机的情况。
  • :sparkles: 抽取 mica-mqtt-model 模块,方便后期支持消息桥接,Message 添加默认的消息序列化。 gitee #I4ECEO
  • :sparkles: mica-mqtt-model 完善 Message 消息模型,方便集群。
  • :bug: mica-mqtt-core MqttClient 修复 ssl 没有设置,感谢 @hjkJOJO 同学反馈。
  • :bug: 修复 websocket mqtt.js 需要拆包 gitee #I4JYJX 感谢 @Symous 同学反馈。
  • :memo: 完善 mica-mqtt-broker README.md,添加二开说明。
  • :memo: 统一 mica-mqtt server ip 文档。
  • :memo: 更新 README.md
  • :arrow_up: 升级 tio 到 3.7.5.v20211028-RELEASE AioDecodeException 改为 TioDecodeException,

六、重要更新说明

6.1 客户端 IMqttClientConnectListener 添加 onDisconnect 方法

public interface IMqttClientConnectListener {

    /**
     * 监听到消息
     *
     * @param context     ChannelContext
     * @param isReconnect 是否重连
     */
    void onConnected(ChannelContext context, boolean isReconnect);

    /**
     * 连接关闭前触发本方法
     *
     * @param channelContext the channelContext
     * @param throwable      the throwable 有可能为空
     * @param remark         the remark 有可能为空
     * @param isRemove       is removed
     */
    void onDisconnect(ChannelContext channelContext, Throwable throwable, String remark, boolean isRemove);

}
复制代码

6.2 服务端 IMqttMessageListener onMessage 参数调整

@FunctionalInterface
public interface IMqttMessageListener {

    /**
     * 监听到消息
     *
     * @param context  ChannelContext
     * @param clientId clientId
     * @param message  Message
     */
    void onMessage(ChannelContext context, String clientId, Message message);

}
复制代码

6.3 Message 对象添加更多属性

为了以后版本更方便的对接规则引擎对 Message 中的属性进行了扩充,并且内置 DefaultMessageSerializer 序列化,基于 ByteBuffer 进行的类协议解析的方式,速度更快,报文更小。

byte[] data = DefaultMessageSerializer.INSTANCE.serialize(message);
Message message1 = DefaultMessageSerializer.INSTANCE.deserialize(data);
复制代码

七、Spring boot 快速接入

7.1 添加依赖

<dependency>
    <groupId>net.dreamlu</groupId>
    <artifactId>mica-mqtt-spring-boot-starter</artifactId>
    <version>1.2.0</version>
</dependency>
复制代码

7.2 服务端配置示例

mqtt:
  server:
    enabled: true               # 是否开启,默认:true
    ip: 0.0.0.0                 # 服务端 ip 默认:0.0.0.0
    port: 5883                  # 端口,默认:1883
    name: Mica-Mqtt-Server      # 名称,默认:Mica-Mqtt-Server
    buffer-allocator: HEAP      # 堆内存和堆外内存,默认:堆内存
    heartbeat-timeout: 120000   # 心跳超时,单位毫秒,默认: 1000 * 120
    read-buffer-size: 8092      # 接收数据的 buffer size,默认:8092
    max-bytes-in-message: 8092  # 消息解析最大 bytes 长度,默认:8092
    debug: true                 # 如果开启 prometheus 指标收集建议关闭
    websocket-enable: true      # 开启 websocket 子协议,默认开启
    websocket-port: 8083        # websocket 端口,默认:8083
复制代码

7.3 服务端可实现接口(注册成 Spring Bean 即可)

接口 是否必须 说明
IMqttServerUniqueIdService 用于 clientId 不唯一时,自定义实现唯一标识,后续接口使用它替代 clientId
IMqttServerAuthHandler 用于服务端认证
IMqttServerSubscribeValidator 1.1.3 新增,用于服务端订阅校验
IMqttMessageListener 消息监听
IMqttConnectStatusListener 连接状态监听
IMqttSessionManager session 管理
IMqttMessageStore 集群是,单机否 遗嘱和保留消息存储
AbstractMqttMessageDispatcher 集群是,单机否 消息转发,(遗嘱、保留消息转发)
IpStatListener t-io ip 状态监听

7.4 Prometheus + Grafana 监控对接

得益于 t-io 良好的设计,监控指标直接对接的 t-iostat,目前支持下列指标,后期会不断完善。

支持得指标 说明
mqtt_connections_accepted 共接受过连接数
mqtt_connections_closed 关闭过的连接数
mqtt_connections_size 当前连接数
mqtt_messages_handled_packets 已处理消息数
mqtt_messages_handled_bytes 已处理消息字节数
mqtt_messages_received_packets 已接收消息数
mqtt_messages_received_bytes 已处理消息字节数
mqtt_messages_send_packets 已发送消息数
mqtt_messages_send_bytes 已发送消息字节数

mqtt监控1.jpg

关于 mica-mqtt-spring-boot-starter 更多请查看文档:gitee.com/596392912/m…

八、普通 java 项目接入

8.1 maven 依赖

 <dependency>
   <groupId>net.dreamlu</groupId>
   <artifactId>mica-mqtt-core</artifactId>
   <version>1.2.0</version>
 </dependency>
复制代码

8.2 mica-mqtt 客户端

 // 初始化 mqtt 客户端
 MqttClient client = MqttClient.create()
     .ip("127.0.0.1")
     .port(1883)                     // 默认:1883
     .username("admin")
     .password("123456")
     .version(MqttVersion.MQTT_5)    // 默认:3_1_1
     .clientId("xxxxxx")             // 默认:MICA-MQTT- 前缀和 36进制的纳秒数
     .connect();                     // 连接
 
     // 消息订阅,同类方法 subxxx
     client.subQos0("/test/#", (topic, payload) -> {
         logger.info(topic + '\t' + ByteBufferUtil.toString(payload));
     });
     // 取消订阅
     client.unSubscribe("/test/#");
 
     // 发送消息
     client.publish("/test/client", ByteBuffer.wrap("mica最牛皮".getBytes(StandardCharsets.UTF_8)));
 
     // 断开连接
     client.disconnect();
     // 重连
     client.reconnect();
     // 停止
     client.stop();
复制代码

8.3 mica-mqtt 服务端

// 注意:为了能接受更多链接(降低内存),请添加 jvm 参数 -Xss129k
MqttServer mqttServer = MqttServer.create()
    // 默认:0.0.0.0
    .ip("0.0.0.0")
    // 默认:1883
    .port(1883)
    // 默认为: 8092(mqtt 默认最大消息大小),为了降低内存可以减小小此参数,如果消息过大 t-io 会尝试解析多次(建议根据实际业务情况而定)
    .readBufferSize(512)
    // 消息监听
    .messageListener((context, clientId, message) -> {
        logger.info("clientId:{} message:{} payload:{}", clientId, message, ByteBufferUtil.toString(message.getPayload()));
    })
    .debug() // 开启 t-io debug 信息日志
    .start();

// 发送给某个客户端
mqttServer.publish("clientId","/test/123", ByteBuffer.wrap("mica最牛皮".getBytes()));

// 发送给所有在线监听这个 topic 的客户端
mqttServer.publishAll("/test/123", ByteBuffer.wrap("mica最牛皮".getBytes()));

// 停止服务
mqttServer.stop();
复制代码

九、集群演示视频

mica-mqtt集群.gif

关注《mica微服务专栏》,更多精彩内容每天等你来发现!

猜你喜欢

转载自juejin.im/post/7035986652719742989