{"id":13630822,"url":"https://github.com/Amazingwujun/mqttx","last_synced_at":"2025-04-17T17:31:46.268Z","repository":{"id":37101193,"uuid":"246979203","full_name":"Amazingwujun/mqttx","owner":"Amazingwujun","description":"MQTTX Project 完整实现 mqttv3.1.1 协议，旨在提供易于使用且性能优异的 mqtt broker","archived":false,"fork":false,"pushed_at":"2024-09-09T08:50:26.000Z","size":782,"stargazers_count":333,"open_issues_count":0,"forks_count":103,"subscribers_count":15,"default_branch":"v1.2","last_synced_at":"2025-04-05T06:07:42.885Z","etag":null,"topics":["bridge","broker","cluster","docker","iot-application","kafka","mqtt","mqtt-broker","mqttx","netty","redis","share-topic","springboot","topic","websocket"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Amazingwujun.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-13T03:18:49.000Z","updated_at":"2025-04-04T05:36:32.000Z","dependencies_parsed_at":"2024-01-14T06:51:27.982Z","dependency_job_id":"982150ee-12e6-4f73-ae2b-19e8993ea381","html_url":"https://github.com/Amazingwujun/mqttx","commit_stats":{"total_commits":207,"total_committers":4,"mean_commits":51.75,"dds":0.07246376811594202,"last_synced_commit":"0ce55e9bce6632f9c5e869b14c500420200b8f40"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Amazingwujun%2Fmqttx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Amazingwujun%2Fmqttx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Amazingwujun%2Fmqttx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Amazingwujun%2Fmqttx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Amazingwujun","download_url":"https://codeload.github.com/Amazingwujun/mqttx/tar.gz/refs/heads/v1.2","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249360009,"owners_count":21257149,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bridge","broker","cluster","docker","iot-application","kafka","mqtt","mqtt-broker","mqttx","netty","redis","share-topic","springboot","topic","websocket"],"created_at":"2024-08-01T22:02:00.322Z","updated_at":"2025-04-17T17:31:45.947Z","avatar_url":"https://github.com/Amazingwujun.png","language":"Java","funding_links":[],"categories":["Java"],"sub_categories":[],"readme":"# MQTTX Project\n\n![license](https://img.shields.io/github/license/tensorflow/tensorflow.svg) ![language](https://img.shields.io/badge/language-java-orange.svg)\n\n中文 | [English](./readme_en.md)\n\n- [1 介绍](#1-介绍)\n    - [1.1 快速开始](#11-快速开始)\n    - [1.2 项目依赖](#12-项目依赖)\n    - [~~1.3  线上实例~~](#13-线上实例)\n- [2 架构](#2-架构)\n    - [2.1 目录结构](#21-目录结构)\n- [3 docker 启动](#3-docker-启动)\n- [4 功能说明](#4-功能说明)\n    - [4.1 qos 支持](#41-qos-支持)\n    - [4.2 topicFilter 支持](#42-topicfilter-支持)\n    - [4.3 集群支持](#43-集群支持)\n    - [4.4 ssl 支持](#44-ssl-支持)\n    - [4.5 topic 安全支持](#45-topic-安全支持)\n    - [4.6 共享主题支持](#46-共享主题支持)\n    - [4.7 websocket 支持](#47-websocket-支持)\n    - [4.8 系统主题](#48-系统主题)\n      - [4.8.1 状态主题](#481-状态主题)\n      - [4.8.2 功能主题](#482-功能主题)\n    - [4.9 消息桥接支持](#49-消息桥接支持)\n    - [4.10 主题限流支持](#410-主题限流支持)\n    - [4.11 消息持久化支持](#411-消息持久化支持)\n    - [4.12 基础认证支持](#412-基础认证支持)\n- [5 开发者说](#5-开发者说)\n- [6 附表](#6-附表)\n    - [6.1 配置项](#61-配置项)\n\n## 1 介绍\n\n`Mqttx` 基于 [MQTT v3.1.1](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html) 协议开发，旨在提供 ***易于使用*** 且 ***性能优越*** 的 **mqtt broker**。\n\n注意：分支 `v1.2` 要求 ***JDK17***, 其它分支要求 ***JDK8***\n\n关联项目: [Mqttx-Client](https://github.com/Amazingwujun/mqttx-client) 实现\u0026使用极为简单的 mqttv3.1.1 客户端.\n\n### 1.1 快速开始\n\n\u003e 想通过 docker 快速体验？见 [docker 启动](#3-docker-启动)\n\n1. 打包\n    - 开发模式：\n        1. 启动 `redis` 实例\n        2. 运行 `mvnw -P dev -DskipTests=true clean package`\n2. 运行\n\n    1. 运行命令：`java -jar mqttx-1.0.5.BETA.jar`\n\n图例：\n\n\u003cimg src=\"https://s1.ax1x.com/2020/09/27/0kJp3F.gif\" alt=\"快速开始\" style=\"zoom: 80%;\" /\u003e\n\n### 1.2 项目依赖\n\n- [x] **Redis**： 集群消息、消息持久化\n- [x] **Kafka**：桥接消息支持，集群消息（可选功能）\n\n其它说明：\n\n1. 项目使用了 **lombok**，使用 **ide** 请安装对应的插件\n\n\u003e 开发工具建议使用 [Intellij IDEA](https://www.jetbrains.com/idea/) :blush:\n\u003e\n\u003e 举例：`idea` 需要安装插件 `Lombok`, `settings \u003e Build,Execution,Deployment \u003e Compiler \u003e Annotation Processor` 开启 `Enable annotation processing`\n\n### ~~1.3 线上实例~~\n\n云服务到期，实例已经无法访问，有朋友赞助吗/(ㄒoㄒ)/~~\n\n\u003e 云端部署了一个 `mqttx` 单例服务，可供功能测试：\n\u003e\n\u003e 1. 不支持 `ssl`\n\u003e 2. 开启了 `websocket`, 可通过 http://ws.tool.tusk.link/ 测试，仅需将域名修改为：`119.45.158.51`(端口、地址不变)\n\u003e 3. 支持共享订阅功能\n\u003e 4. 部署版本 `v1.0.6.RELEASE`\n\u003e\n\u003e ![websocket](https://s1.ax1x.com/2020/09/05/wV578J.png)\n\n\n\n## 2 架构\n\n`mqttx`支持客户端认证、topic 发布/订阅鉴权功能，如果需要配套使用，建议的架构如下图：\n\n![架构图](https://s1.ax1x.com/2020/07/28/ak6KAO.png)\n\n\u003e 客户认证服务由使用者自行实现\n\n内部实现框架关系(仅列出关键项)：\n\n![ak6mB6.png](https://s1.ax1x.com/2020/07/28/ak6mB6.png)\n\n### 2.1 目录结构\n\n```\n├─java\n│  └─com\n│      └─jun\n│          └─mqttx\n│              ├─broker         # mqtt 协议实现及处理包\n│              │  ├─codec       # 编解码\n│              │  └─handler     # 消息处理器（pub, sub, connn, etc）\n│              ├─config         # 配置，主要是 bean 声明\n│              ├─constants      # 常量\n│              ├─consumer       # 集群消息消费者\n│              ├─entity         # 实体类\n│              ├─exception      # 异常类\n│              ├─service        # 业务服务（用户认证, 消息存储等）接口\n│              │  └─impl        # 默认实现\n│              └─utils          # 工具类\n└─resources                     # 资源文件（application.yml 在此文件夹）\n    ├─META-INF                  # spring-configuration 辅助配置说明\n    └─tls                       # ca 存放地址\n```\n\n## 3 docker 启动\n\n镜像已上传至  **docker-hub** , 访问：[fantasywujun/mqttx - Docker Hub](https://hub.docker.com/r/fantasywujun/mqttx) 全部镜像\n\ndocker 环境安装好后，执行 `docker-compose -f ./docker-compose.yml up` 启动, 效果见下图：\n\n![y3R3tI.md.png](https://s3.ax1x.com/2021/02/04/y3R3tI.md.png)\n\n| Docker Pull Command                    | 说明                                |\n|----------------------------------------|-----------------------------------|\n| `docker pull fantasywujun/mqttx:1.2.0` | 基于 `jdk17.0.1` 的 `mqttx:1.2.0` 版本 |\n| `docker pull fantasywujun/mqttx:1.2.1` | 基于 `jdk17.0.1` 的 `mqttx:1.2.1` 版本 |\n| `docker pull fantasywujun/mqttx:1.2.2` | 基于 `jdk17.0.1` 的 `mqttx:1.2.2` 版本 |\n| `docker pull fantasywujun/mqttx:1.2.3` | 基于 `jdk17.0.1` 的 `mqttx:1.2.3` 版本 |\n\n**docker-compose** 文件内容：\n\n```yaml\nversion: \"2\"\nservices:\n  redis:\n    container_name: redis-for-mqttx\n    image: redis\n  mqttx:\n    container_name: mqttx\n    image: fantasywujun/mqttx:1.2.2\n    environment:\n      mqttx.max-bytes-in-message: 10485760\n      mqttx.web-socket.enable: false\n    ports:\n      - 1883:1883\n```\n\n\n\n## 4 功能说明\n\n#### 4.1 qos 支持\n\n| qos0 | qos1 | qos2 |\n| ---- | ---- | ---- |\n| 支持 | 支持 | 支持 |\n\n为支持 `qos1、qos2`，引入 `redis` 作为持久层，这部分已经封装成接口，可自行替换实现（比如采用 `mysql`）。\n\n#### 4.2 topicFilter 支持\n\n1. 支持多级通配符 `#`与单级通配符 `+`\n2. 不支持以 `/`结尾的topic，比如 `a/b/`，请改为 `a/b`。\n3. 其它规则见 ***[mqtt v3.1.1](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html) 4.7 Topic Names and Topic\n   Filters***\n\n\u003e **mqttx** 仅对订阅 topicFilter 进行校验，publish 的 topic 是没有做合法性检查的，可通过开启 [4.5 topic 安全支持](#45-topic-安全支持) 限制客户端可发布的 topic。\n\n举例：\n\n| topicFilter  | match topics                  |\n| ------------ | ----------------------------- |\n| `/a/b/+`     | `/a/b/abc`,`/a/b/test`        |\n| `a/b/#`      | `a/b`, `a/b/abc`, `a/b/c/def` |\n| `a/+/b/#`    | `a/nani/b/abc`                |\n| `/+/a/b/+/c` | `/aaa/a/b/test/c`             |\n\n校验工具类为：`com.jun.mqttx.utils.TopicUtils`\n\n#### 4.3 集群支持\n\n`mqttx` 依赖消息中间件分发消息实现集群功能，目前支持的中间件：\n\n- [x] `Kafka`：可选配置。为了更好的性能，推荐 kafka 作为集群消息分发器\n- [x] `Redis`：默认配置\n\n实现原理如下图：\n\n![ak6nHK.png](https://s1.ax1x.com/2020/07/28/ak6nHK.png)\n\n1. `mqttx.cluster.enable`：功能开关，默认 `false`\n2. `mqttx.cluster.type`: 消息中间件类型，默认 `redis`\n\n注意事项：\n\n1. `v1.0.5.RELEASE` 之前的版本集群功能存在 bug，无法使用。\n\n2. 如需使用 `kafka` 实现集群消息，需要手动修改配置 `application-*.yml`, 可参考 `application-dev.yml` 中的配置示例 ***3. kafka 集群***。\n\n#### 4.4 ssl 支持\n\n开启 ssl 你首先应该有了 *ca*(自签名或购买)，然后修改 `application.yml` 文件中几个配置：\n\n1. `mqttx.ssl.enable`：功能开关，默认 `false`，同时控制 `websocket` 与 `socket`\n2. `mqttx.ssl.key-store-location`：keystore 地址，基于 `classpath`\n3. `mqttx.ssl.key-store-password`：keystore 密码\n4. `mqttx.ssl.key-store-type`：keystore 类别，如 `PKCS12`\n5. `mqttx.ssl.client-auth`：服务端是否需要校验客户端证书，默认 `NONE`\n\n\u003e `resources/tls` 目录中的 `mqttx.keystore` 仅供测试使用, 密码: `123456`\n\u003e\n\u003e 证书加载工具类：`com/jun/mqttx/utils/SslUtils.java`\n\n#### 4.5 topic 安全支持\n\n为了对 client 订阅 topic 进行限制，加入**topic 订阅\u0026发布鉴权**机制:\n\n1. `mqttx.enable-topic-sub-pub-secure`: 功能开关，默认 `false`\n\n2. broker 收到 conn 报文后，会抓取 `{clientId, username, password}` 发起请求给 `mqttx.auth.url` , 该接口返回对象中含有 `authorizedSub,authorizedPub` 存储 **client** 被授权订阅及发布的 `topic` 列表。\n\n   详见 [4.12 基础认证支持](#412-基础认证支持) \n\n3. broker 在消息订阅及发布都会校验客户端权限\n\n支持的主题类型：\n\n- [x] 普通主题\n- [x] 共享主题\n- [x] 系统主题\n\n#### 4.6 共享主题支持\n\n共享订阅是协议 `mqtt5` 规定的内容，**`MQTTX`** 参考协议标准实现。\n\n1. 格式: `$share/{ShareName}/{filter}`, `$share` 为前缀, `ShareName` 为共享订阅名, `filter` 就是非共享订阅主题过滤器。\n2. 支持如下两种消息分发规则\n   1. `round`: 轮询\n   2. `random`: 随机\n3. 支持客户端订阅按 `ShareName` 分组订阅.\n3. 详细内容请参考协议 [MQTT Version 5.0 (oasis-open.org)](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901250) \n\n下图展示了共享主题与常规主题之间的差异:\n\n![share-topic](https://s1.ax1x.com/2020/09/22/wXddnU.png)\n\n`msg-a` 消息分发策略取决于配置项 `mqttx.share-topic.share-sub-strategy`\n\n可以配合 `cleanSession = 1` 的会话，共享主题的客户端断开连接后会被服务端移除订阅，这样共享主题的消息只会分发给在线的客户端。\n\n***CleanSession*** 介绍：`mqtt3.1.1` 协议规定当 `cleanSession = 1` 时，连接断开后与会话相关联的所有状态（不含 `retained` 消息）都会被删除（`mqtt5`\n增加了会话超时设置，感兴趣的同学可以了解一下）。\n`mqttx v1.0.5.BETA` 版本后(含)，`cleanSession = 1` 的会话消息保存在内存中，具备极高的性能.\n\n\u003e If CleanSession is set to 1, the Client and Server **MUST** discard any previous Session and start a new one. This Session lasts as long as the Network Connection. State data associated with this Session **MUST NOT** be reused in any subsequent Session [MQTT-3.1.2-6].\n\u003e\n\u003e The Session state in the Client consists of:\n\u003e\n\u003e - QoS 1 and QoS 2 messages which have been sent to the Server, but have not been completely acknowledged.\n\u003e - QoS 2 messages which have been received from the Server, but have not been completely acknowledged.\n\u003e\n\u003e The Session state in the Server consists of:\n\u003e\n\u003e - The existence of a Session, even if the rest of the Session state is empty.\n\u003e - The Client’s subscriptions.\n\u003e - QoS 1 and QoS 2 messages which have been sent to the Client, but have not been completely acknowledged.\n\u003e - QoS 1 and QoS 2 messages pending transmission to the Client.\n\u003e - QoS 2 messages which have been received from the Client, but have not been completely acknowledged.\n\u003e - Optionally, QoS 0 messages pending transmission to the Client.\n\n#### 4.7 websocket 支持\n\n支持\n\n#### 4.8 系统主题\n\n**mqttx broker** 内置部分系统主题，用户可酌情使用。\n\n系统主题不支持如下特性：\n\n- 集群：系统主题不支持集群，包括消息及订阅\n- 持久化：系统主题消息不支持持久化，包括订阅关系\n- QoS: 不支持 QoS 1,2 仅支持 QoS 0\n\n**注意**：***topic 安全机制*** 同样会影响客户端订阅系统主题, 未授权客户端将无法订阅系统主题\n\n系统主题可分两种：\n\n1. 状态主题：反应 **broker** 自身状态的主题\n2. 功能主题：对外提供功能性支持的主题\n\n##### 4.8.1 状态主题\n\n客户端可通过订阅系统主题获取 **broker** 状态，目前系统支持如下状态主题：\n\n| 主题                                | 描述                                                         |\n| ----------------------------------- | ------------------------------------------------------------ |\n| `$SYS/broker/{brokerId}/status`     | 触发方式：订阅此主题的客户端会定期（`mqttx.sys-topic.interval`）收到 broker 的状态，该状态涵盖下面所有主题的状态值. \u003cbr/\u003e **注意：客户端连接断开后，订阅取消** |\n| `$SYS/broker/activeConnectCount`    | 立即返回当前的活动连接数量\u003cbr/\u003e触发：订阅一次触发一次        |\n| `$SYS/broker/time`                  | 立即返回当前时间戳\u003cbr/\u003e触发：订阅一次触发一次                |\n| `$SYS/broker/version`               | 立即返回 `broker` 版本\u003cbr/\u003e触发：订阅一次触发一次            |\n| `$SYS/broker/receivedMsg`           | 立即返回 `broker` 启动到现在收到的 `MqttMessage`, 不含 `ping`\u003cbr/\u003e触发：订阅一次触发一次 |\n| `$SYS/broker/sendMsg`               | 立即返回 `broker` 启动到现在发送的 `MqttMessage`, 不含 `pingAck`\u003cbr/\u003e触发：订阅一次触发一次 |\n| `$SYS/broker/uptime`                | 立即返回 `broker` 运行时长，单位***秒***\u003cbr/\u003e触发：订阅一次触发一次 |\n| `$SYS/broker/maxActiveConnectCount` | 立即返回 `broker` 运行至今的最大 `tcp` 连接数\u003cbr/\u003e触发：订阅一次触发一次 |\n\n系统主题 `$SYS/broker/{brokerId}/status` 中的 **brokerId** 为配置项参数（见 ***[6.1 配置项](#61-配置项)***），可通过携带通配符的主题 `$SYS/broker/+/status` 订阅。\n\n响应对象格式为 `json` 字符串：\n\n```json\n{\n    \"activeConnectCount\": 1,\n    \"maxActiveConnectCount\": 2,\n    \"receivedMsg\": 6,\n    \"sendMsg\": 77,\n    \"timestamp\": \"2021-03-23T23:05:37.035\",\n    \"uptime\": 149,\n    \"version\": \"1.0.7.RELEASE\"\n}\n```\n\n| field                   | 说明                            |\n| ----------------------- | ------------------------------- |\n| `activeConnectCount`    | 当前活跃连接数量                |\n| `maxActiveConnectCount` | 最大活跃连接数量                |\n| `receiveMsg`            | 收到消息数量，不含 **ping**     |\n| `sendMsg`               | 发送消息数量，不含 **pingAck**  |\n| `timestamp`             | 时间戳；(`yyyy-MM-dd HH:mm:ss`) |\n| `uptime`                | broker 上线时长，单位秒         |\n| `version`               | `mqttx` 版本                    |\n\n##### 4.8.2 功能主题\n\n此功能需求源自 issue: [监听MQTT客户端状态（在线、离线） · Issue #8 · Amazingwujun/mqttx (github.com)](https://github.com/Amazingwujun/mqttx/issues/8)\n\n| 主题                                                   | 描述                                                         |\n| ------------------------------------------------------ | ------------------------------------------------------------ |\n| `$SYS/broker/{borkerId}/clients/{clientId}/connected`    | 客户端上线通知主题 \u003cbr/\u003e触发：当某个客户端上线后，**broker** 会发送消息给该主题 |\n| `$SYS/broker/{borkerId}/clients/{clientId}/disconnected` | 客户端下线通知主题\u003cbr/\u003e触发：当某个客户端掉线后，**broker** 会发送消息给该主题 |\n\n这两个系统主题支持通配符，举例：\n\n1. `$SYS/broker/+/clients/#`: 匹配客户端上下线通知主题\n2. `$SYS/broker/+/clients/+/connected`: 匹配客户端上线通知主题\n3. `$SYS/broker/+/clients/+/disconnected`: 匹配客户端下线通知主题\n\n#### 4.9 消息桥接支持\n\n支持消息中间件：\n\n- [x] kafka\n\n消息桥接功能可方便的对接消息队列中间。\n\n1. `mqttx.message-bridge.enable`：开启消息桥接功能\n2. `mqttx.bridge-topics`：需要桥接消息的主题，主题必须符合 **kafka** 对 **topic** 的要求\n\n`mqttx` 收到客户端 ***发布*** 的消息后，先判断桥接功能是否开启，然后再判断主题是否是需要桥接消息的主题，最后发布消息到 ***MQ***。\n\n**仅支持单向桥接：device(client) =\u003e mqttx =\u003e MQ**\n\n#### 4.10 主题限流支持\n\n使用基于令牌桶算法的 `com.jun.mqttx.utils.RateLimiter` 对指定主题进行流量限制。\n\n\u003e 令牌桶算法参见：https://stripe.com/blog/rate-limiters\n\u003e\n\u003e 简单解释一下令牌桶概念：有一个最大容量为 `capacity` 的令牌桶，该桶以一定的速率补充令牌（`replenish-rate`），每次调用接口时消耗一定量（`token-consumed-per-acquire`）的令牌，令牌数目足够则请求通过。\n\n**主题限流仅适用于 `qos` 等于 *0*  的消息**。\n\n配置举例：\n\n```yml\nmqttx:\n  rate-limiter:\n    enable: true\n    topic-rate-limits:\n      # 例一\n      - topic: \"/test/a\"\n        capacity: 9\n        replenish-rate: 4\n        token-consumed-per-acquire: 3\n      # 例二\n      - topic: \"/test/b\"\n        capacity: 5\n        replenish-rate: 5\n        token-consumed-per-acquire: 2\n```\n\n- `capacity`: 桶容量\n- `replenish-rate`: 令牌填充速率\n- `token-consumed-per-acquire`: 每次请求消耗令牌数量\n\n`QPS` 计算公式：\n\n1. 最大并发数：公式为 `QPS = capacity ÷ token-consumed-per-acquire`\n    1. 示例一：`9 ÷ 3 = 3`\n    2. 示例二：`5 ÷ 2 = 2.5`\n2. 最大持续并发数：公式 `QPS = replenish-rate ÷ token-consumed-per-acquire`\n    1. 示例一：`4 ÷ 3 ≈ 1.3`\n    2. 示例二：`5 ÷ 2 = 2.5`\n\n#### 4.11 消息持久化支持\n\n`mqttx` 的持久化依赖 `redis` , `mqttx` 会持久化 `cleanSession = false \u0026 qos \u003e 0` 的消息, 消息被 `Serializer` 序列化为字节数组后存储在 `redis`。\n\n目前 `mqttx` 提供了两种序列化实现：\n\n1. `JsonSerializer`\n2. `KryoSerializer`\n\n默认使用 `JsonSerializer`, 这是为了和之前的项目兼容；`v1.0.6.release` 版本后 `KryoSerializer` 将成为默认序列化实现。\n\n可通过配置 `mqttx.serialize-strategy` 修改序列化实现。\n\n#### 4.12 基础认证支持\n\n`mqttx` 提供基础客户端认证服务。\n\n配置项：\n\n1. `mqttx.auth.url`: 提供认证服务的接口地址。\n2. `mqttx.auth.timeout`: `HttpClient` 请求超时\n3. `mqttx.auth.is-mandatory`: 是否强制要求校验用户名与密码\n\n用户在配置文件中声明 `mqtt.auth.url` 后，对象 `com.jun.mqttx.service.impl.DefaultAuthenticationServiceImpl` 使用 `HttpClient` 发出 `POST` 请求给 `mqttx.auth.url`。 \n\n请求内容为 `mqtt conn` 报文中的 `username, password`.\n\n```curl\nPOST / HTTP/1.1\nHost: mqttx.auth.url\nContent-Type: application/json\nContent-Length: 91\n\n{\n    \"clientId\": \"device_id_test\",\n    \"username\": \"mqttx\",\n    \"password\": \"123456\"\n}\n```\n\n认证成功后响应对象为 `json` 格式字符串:\n\n```json\n{\n    \"authorizedSub\": [\n        \"subTopic1\",\n        \"subTopic2\"\n    ],\n    \"authorizedPub\": [\n        \"pubTopic1\",\n        \"pubTopic2\"\n    ]\n}\n```\n\n认证成功返回响应可配合  [4.5 topic 安全支持](#45-topic-安全支持) 使用。\n\n注意：\n\n- 接口返回 `http status = 200` 即表明**认证成功**, 其它状态值一律为**认证失败**\n\n\n\n## 5 开发者说\n\n1. 感谢 **Jetbrains** 为开源项目提供的 License\n\n    \u003cimg src=\"https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.png\" alt=\"Jetbrains\" height=\"150\"/\u003e    \n\n2. 长期更新维护的分支\n   1. `v1.0`: 基于 `jdk8` 且 redis io 为 **blocking** 模式.\n   2. `v1.2`: 基于 `jdk17` 且 redis io 为 **non-blocking** 模式.\n\n3. 为使 ***mqttx*** 项目变得更好，请使用及学习该项目的同学主动反馈使用情况给我（提 issue 或加群反馈）\n\n4. 后续工作\n   - [ ] `v1.0.8.RELEASE` 版本开发\n   - [ ] `v1.1.0.RELEASE` 版本开发\n   - [x] `v1.2` 版本开发\n   - [ ] `v2.0` 版本开发\n   - [x] bug 修复\n\n5. `v1.2` 版本由 **JDK8** 升级至 **JDK17**\n\n6. `v2.0` 版本分支将作为 **mqttv5** 协议版本开始迭代\n\n7. 考虑使用 *gossip* 协议实现集群功能，集群功能不再依赖 *redis or kafka*\n\n8. 请作者喝杯 **丝绒拿铁** 😊\n\n   \u003cimg src=\"https://z3.ax1x.com/2021/07/15/Wm53vj.jpg\" alt=\"coffee\" height=\"300\" /\u003e\n\n9. 交流群\n\n    \u003cimg src=\"https://s1.ax1x.com/2020/10/10/0ytoSx.jpg\" alt=\"群二维码\" height=\"300\" /\u003e\n\n## 6 附表\n\n### 6.1 配置项\n\n`src/main/resources` 目录下有三个配置文件：\n\n1. `application.yml`\n2. `application-dev.yml`\n3. `application-prod.yml`\n\n后两个配置文件目的是区分不同环境下的配置，便于管理。\n\n配置项说明：\n\n| 配置                                                     | 默认值                          | 说明                                                         |\n| -------------------------------------------------------- | ------------------------------- | ------------------------------------------------------------ |\n| `mqttx.version`                                          | 取自 `pom.xml`                  | 版本                                                         |\n| `mqttx.broker-id`                                        | 取自 `pom.xml`                  | 应用标志, 唯一                                               |\n| `mqttx.heartbeat`                                        | `60s`                           | 初始心跳，会被 conn 消息中的 keepalive 重置                  |\n| `mqttx.host`                                             | `0.0.0.0`                       | 监听地址                                                     |\n| `mqttx.so-backlog`                                       | `512`                           | tcp 连接处理队列                                             |\n| `mqttx.enable-topic-sub-pub-secure`                      | `false`                         | 客户订阅/发布主题安全功能，开启后将限制客户端发布/订阅的主题 |\n| `mqttx.ignore-client-self-pub`                           | `true`                          | 忽略 client 发送给自己的消息（当 client 发送消息给自己订阅的主题） |\n| `mqttx.max-bytes-in-message`                             | `8092`                          | mqttx 允许接收的最大报文载荷，单位 `byte`.                   |\n| `mqttx.serialize-strategy`                               | `json`                          | `broker` 采用的序列化策略，**集群策略*必须*一致**。          |\n| `mqttx.redis.cluster-session-hash-key`                   | `mqttx.session.key`             | redis map key；用于集群的会话存储                            |\n| `mqttx.redis.topic-prefix`                               | `mqttx:topic:`                  | 主题前缀； topic \u003c==\u003e client 映射关系保存                    |\n| `mqttx.redis.retain-message-prefix`                      | `mqttx:retain:`                 | 保留消息前缀, 保存 retain 消息                               |\n| `mqttx.redis.pub-msg-set-prefix`                         | `mqttx:client:pubmsg:`          | client pub消息 redis set 前缀； 保存 pubmsg，当收到 puback 获取 pubrec 后删除 |\n| `mqttx.redis.pub-rel-msg-set-prefix`                     | `mqttx:client:pubrelmsg:`       | client pubRel 消息 redis set 前缀；保存 pubrel 消息 flag，收到 pubcom 消息删除 |\n| `mqttx.redis.topic-set-key`                              | `mqttx:alltopic`                | topic 集合，redis set key 值；保存全部主题                   |\n| `mqttx.redis.message-id-prefix`                          | `mqttx:messageId:`              | 非 `cleanSession` client 的 `messageId`, 使用 `redis INCR` 指令 |\n| `mqttx.redis.client-topic-set-prefix`                    | `mqttx:client:topicset:`        | client 订阅的主题 redis set 前缀; 保存 client 订阅的全部主题 |\n| `mqttx.cluster.enable`                                   | `false`                         | 集群开关                                                     |\n| `mqttx.cluster.inner-cache-consistancy-key`              | `mqttx:cache_consistence`       | 应用启动后，先查询 redis 中无此 key 值，然后在检查一致性     |\n| `mqttx.cluster.type`                                     | `redis`                         | 集群消息中间件类型                                           |\n| `mqttx.ssl.enable`                                       | `false`                         | ssl 开关                                                     |\n| `mqttx.ssl.client-auth`                                  | `NONE`                          | 客户端证书校验                                               |\n| `mqttx.ssl.key-store-location`                           | `classpath: tls/mqttx.keystore` | keyStore 位置                                                |\n| `mqttx.ssl.key-store-password`                           | `123456`                        | keyStore 密码                                                |\n| `mqttx.ssl.key-store-type`                               | `pkcs12`                        | keyStore 类别                                                |\n| `mqttx.socket.enable`                                    | `true`                          | socket 开关                                                  |\n| `mqttx.socket.port`                                      | `1883`                          | socket 监听端口                                              |\n| `mqttx.websocket.enable`                                 | `false`                         | websocket 开关                                               |\n| `mqttx.websocket.port`                                   | `8083`                          | websocket 监听端口                                           |\n| `mqttx.websocket.path`                                   | `/mqtt`                         | websocket path                                               |\n| `mqttx.share-topic.share-sub-strategy`                   | `round`                         | 负载均衡策略, 目前支持随机、轮询                             |\n| `mqttx.sys-topic.enable`                                 | `false`                         | 系统主题功能开关                                             |\n| `mqttx.sys-topic.interval`                               | `60s`                           | 定时发布间隔                                                 |\n| `mqttx.message-bridge.enable`                            | `false`                         | 消息桥接功能开关                                             |\n| `mqttx.message-bridge.topics`                            | `null`                          | 需要桥接消息的主题列表                                       |\n| `mqttx.rate-limiter.enable`                              | `false`                         | 主题限流开关                                                 |\n| `mqttx.rate-limiter.token-rate-limit`                    |                                 | 参见 [主题限流支持](#410-主题限流支持) 配置举例说明          |\n| `mqttx.auth.url`                                         | `null`                          | mqtt conn username/password 认证服务接口地址                 |\n| `mqttx.auth.timeout`                                     | `3s`                            | readTimeout                                                  |\n| `mqttx.auth.is-mandatory`                                | `false`                         | 是否必须验证 `conn` 报文中的用户名与密码                     |\n| `mqttx.sharable-payload.payload-key-prefix`              | `mqttx:sharable-payload:`       | 共享载荷存储 *redis key prefix*                              |\n| `mqttx.sharable-payload.unique-id-client-ids-set-prefix` | `mqttx:unique-id:client-ids:`   | 共享载荷关联的客户端 *id* 列表                               |\n| `mqttx.sharable-payload.clean-work-interval`             | `1m`                            | 清洗定时间隔。共享载荷清理任务之间的间隔                     |\n| `mqttx.sharable-payload.threshould-in-message`           | `128`                           | 共享载荷生效阈值；大于配置项阈值时，载荷共享。               |\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAmazingwujun%2Fmqttx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAmazingwujun%2Fmqttx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAmazingwujun%2Fmqttx/lists"}