从 v4 迁移到 v5
从 v4 迁移到 v5
本章节提供了从 EMQX 4.x 版本迁移至 5.0.0 版本的指南,尽管 EMQX 5.0 不保证向后兼容(Backward Compatibility),但绝大部分功能运行机制没有太大的变化,你仍然可以通过手动迁移的方式来实现升级。
日志
日志输出格式进行了调整,请参照日志。
默认监听器
默认将不再提供以下监听器:
| 监听器 | 说明 |
|---|---|
| MQTT-TCP 11883 | 后端应用使用的 MQTT 接入点 |
| Management-HTTP 8081 | REST API 端口,已合并至 18083 端口 |
插件
此前的官方插件已迁移到 EMQX 中成为内置功能,用户在 4.x 版本上开发的插件需要重新适配。以下是官方插件与现有功能对照表:
| 4.x | 5.0 |
|---|---|
| emqx_auth_http | 认证/授权 - HTTP 数据源 |
| emqx_auth_jwt | 认证 - JWT |
| emqx_auth_mnesia | 认证/授权 - 内置数据库 |
| emqx_auth_mongo | 认证/授权 - MongoDB 数据源 |
| emqx_auth_mysql | 认证/授权 - MySQL 数据源 |
| emqx_auth_pgsql | 认证/授权 - PostgreSQL 数据源 |
| emqx_auth_redis | 认证/授权 - Redis 数据源 |
| emqx_sasl | 认证/授权 - 增强认证 |
| emqx_auth_ldap | - |
| emqx_rule_engine | 数据集成功能 |
| emqx_bridge_mqtt | 数据桥接 - MQTT Sink/MQTT Source |
| emqx_web_hook | 数据桥接 - WebHook |
| emqx_coap | CoAP 网关 |
| emqx_dashboard | Dasboard |
| emqx_exhook | ExHook 功能 |
| emqx_exproto | ExProto 网关 |
| emqx_lwm2m | LwM2M 网关 |
| emqx_sn | MQTT-SN 网关 |
| emqx_stomp | STOMP 网关 |
| emqx_lua_hook | - |
| emqx_management | - |
| emqx_prometheus | Prometheus 功能 |
| emqx_psk_file | 认证 PSK (psk_authentication.enable = true) |
| emqx_recon | 通过 emqx_ctl observer 命令提供 |
| emqx_retainer | Retain 功能 |
| emqx_telemetry | 遥测功能 |
HTTP API
此前“应用”(Appication)用于管理 API 访问凭证,现已更名为“API 密钥”(API Key),且 Secret Key 仅在创建成功时返回一次后续无法再次获得。
8081 端口已被合并至 18083 端口,API 访问基础路径由 /api/v4 切换到 /api/v5,请通过此端口和路径调用 API;时间相关的数据将使用 RFC3339
(opens new window) 格式。
响应数据格式调整
成功响应时业务状态码 code 将不再随数据返回,出错时将返回对应的 4xx/5xx HTTP 状态码和错误提示, 用户可以访问 GET /error_codes 获取所有可能的错误码,以下是响应格式的对照示例:
## 4.x 成功响应
## HTTP StatusCode = 200
GET /rules/my_rule
{ "code": 0, "data": { ... } }
## 4.x 错误响应
## HTTP StatusCode = 200
GET /rules/my_rule
{ "code": 404, "message": "Not Found" }
## 5.0 成功响应
## HTTP StatusCode = 200
GET /rules/my_rule
{ ... }
## 5.0 错误响应
## HTTP StatusCode = 404
GET /rules/my_rule
{ "code": "NOT_FOUND", "message": "Rule Id Not Found" }
主要 API 变动
API 有较大变动,以下是常用的 API 变动对照表,现存的部分 API 我们做了兼容处理:
提示
兼容性说明:
- 兼容:沿用了旧版 API 路径跟参数,或者保留了旧版 API
- 部分兼容:API 路径不变,但部分 API 字段发生改变
- 不兼容:API 路径与字段都发生变化
| 4.x | 5.0 | 兼容性 | 说明 |
|---|---|---|---|
| 发布/订阅操作 | |||
POST /mqtt/publish |
POST /publish |
兼容 | |
POST /mqtt/publish_batch |
POST /publish/bulk |
兼容 | |
POST /mqtt/subscribe |
POST /clients/{clientid}/subscribe |
兼容 | |
POST /mqtt/subscribe_batch |
POST /clients/{clientid}/subscribe/bulk |
兼容 | |
POST /mqtt/unsubscribe |
POST /clients/{clientid}/unsubscribe |
兼容 | |
POST /mqtt/unsubscribe_batch |
POST /clients/{clientid}/unsubscribe/bulk |
兼容 | |
| 连接/主题/订阅 | |||
GET /clients |
GET /clients |
部分兼容 | |
GET /routes{/topic} |
GET /topics{/topic} |
不兼容 | routes 更名为 topics |
GET /subscriptions |
GET /subscriptions |
部分兼容 | |
GET /subscriptions/{clientid} |
GET /clients/{clientid}/subscriptions |
不兼容 | |
| 节点/状态/指标 | |||
GET /nodes |
GET /nodes |
部分兼容 | |
GET /brokers |
- | 不兼容 | 合并至 GET /nodes |
GET /stats |
GET /stats |
部分兼容 | |
GET /metrics |
GET /metrics |
部分兼容 | |
| 用户/告警 | |||
GET /users |
GET /users |
部分兼容 | |
GET /alarms{/activated} |
GET /alarms?activated={true,false} |
不兼容 | |
GET /alarms{/deactivated} |
GET /alarms?activated={true,false} |
不兼容 |
认证/发布订阅 ACL
认证授权插件(emqx_auth_*)已被移除,相关能力以内置功能的形式迁移到 EMQX 中,支持用户以 Dashboard 或配置文件的方式配置。
发布订阅 ACL 更名为 授权 ,认证与发布订阅 ACL 功能进行了拆分。
我们保留了 4.x 中的认证方式与支持的数据源,但使用方式上有一定调整。
固定的执行顺序
同时启用多个认证器或授权检查器时,不再按照启动顺序而是按照固定的配置顺序来执行检查,可在配置文件跟 Dashboard 中调整的执行顺序。
更换占位符变量提取语法
此前认证插件中可以使用 %u 类似的语法构造占位符以提取变量,将客户端信息动态拼接到如 SQL 语句、Redis 查询命令和 HTTP 请求中, 现在 EMQX 所有 认证跟授权检查功能中使用了新的语法 ${},如 ${username}、${clientid},该语法与规则 SQL 一致。
以下是前后版本配置对比:
## 4.x
## etc/emqx_auth_mysql.conf
auth.mysql.auth_query = select password from mqtt_user where username = '%u' limit 1
## 5.0
## emqx.conf
authentication = [
{
...
mechanism = "password_based"
backend = "mysql"
query = "SELECT password_hash, salt FROM mqtt_user where username = ${username} LIMIT 1"
}
]
认证
移除匿名认证机制
移除 allow_anonymous 配置项,默认允许所有客户端连接,添加并启用 任意一个认证器后将对所有新连接进行认证检查。
移除 bypass_auth_plugins 配置项,某个监听器需要禁用认证时,可以通过 listeners.{type}.{name}.enable_authn = true | false 配置项进行设置。
内置数据库 (Mnesia) 变动
- 为方便理解,该数据源由 Mnesia 更名为内置数据库(Built-in Database);
- 只能选定一种认证查找方式:基于用户名或基于客户端 ID;
- 数据格式与数据操作 REST API 有变动,详见
POST /authentication/{id}/users。
用户可以使用数据导入 API 将旧版本中的数据导入到 EMQX 5.0 中,详见 POST /authentication/{id}/import_users。
HTTP 变动
- 使用响应 Body 里面的 JSON 字段而非响应状态码(HTTP response status codes)判断认证结果;
- 移除超级用户(superuser)查询,如需超级用户功能请在响应 body 里面通过 JSON 设置。
成功响应状态码:
200 或 204
其他状态码或请求失败则忽略该认证器。
成功响应 Body (JSON):
| 名称 | 类型 | 必选 | 说明 |
|---|---|---|---|
| result | 枚举 | true | allow | deny | ignore |
| is_supseruser | 布尔 | false | 默认为 false |
{
"result": "allow",
"is_supseruser": true
}
MySQL/PostgreSQL 变动
- 查询结果中要求的密码字段由
password更改为password_hash,在不更改数据库列名的情况下可以在查询时使用as语法完成迁移; - 移除超级用户(superuser)查询 SQL,如需超级用户功能请确保认证 SQL 结果包含
is_superuser字段。
SELECT password as password_hash, salt, is_superuser FROM mqtt_user where username = ${username} LIMIT 1
MongoDB 变动
- 移除超级用户(superuser)查询,如需超级用户功能请在 MongoDB 认证器配置指定
is_superuser_field字段,并确保认证查询结果中包含超级用户信息。
authentication = [
{
...
mechanism = "password_based"
backend = "mongodb"
# is_superuser_field = "is_superuser"
}
]
Redis 变动
- 仅支持 Redis Hashes
(opens new window) 数据结构与 HGET、HMGET查询命令,必须使用password_hash或password(兼容 4.x)作为密码字段名; - 移除超级用户(superuser)查询,如需超级用户功能请在 Redis 查询命令中添加
is_superuser字段。
## bad
GET emqx_user:${username}
## bad
HMGET emqx_user:${username} passwd
## good
HMGET emqx_user:${username} password_hash
## good
HMGET emqx_user:${username} password_hash is_superuser
LDAP 变动
暂不支持 LDAP 认证。
JWT 变动
无变动。
授权(ACL)
ACL File 变动
- 移除
acl_file配置,基于文件的 ACL(acl.conf) 将作为授权检查器中的一种,默认添加到 EMQX 中; acl.conf文件从etc目录移动到data/authz目录,请确保 EMQX 具有该文件的读写权限;acl.conf数据文件语法有所调整,变更情况见下表:
| 4.x | 5.0.0 | 是否兼容 |
|---|---|---|
| user | username | 是 |
| client | clientid | 是 |
| pubsub | all | 否 |
内置数据库 (Mnesia) 变动
- 为方便理解,该数据源由 Mnesia 更名为内置数据库(Built-in Database);
- 数据格式与数据操作 REST API 有变动,详见
POST /authorization/built_in_database/clientid。
4.x 中的数据导出命令 ./bin/emqx_ctl data export 导出数据中包含 ACL 数据,用户可以将数据处理为 5.0 所需格式通过对应的 REST API 进行导入。
MySQL/PostgreSQL 变动
- 查询结果中不再需要
ipaddr/username/clientid字段; access字段名变为action,数据类型由整型变为字符或字符枚举,数值对应关系见下表;allow字段名变为permission,数据类型由整型变为字符或字符枚举,数值对应关系见下表。
access-action 字段数据类型映射
| 4.x (int) | 5.0.0 (varchar/enum) | 对应动作 |
|---|---|---|
| 1 | subscribe | 订阅 |
| 2 | publish | 发布 |
| 3 | all | 发布订阅 |
allow-permission 字段数据类型映射
| 4.x (int) | 5.0.0 (varchar/enum) | 对应行为 |
|---|---|---|
| 0 | deny | 拒绝 |
| 1 | allow | 允许 |
MongoDB 变动
- MongoDB 数据源可用于黑/白名单模式下,此前仅支持白名单模式,要求设置
acl_nomatch = deny; - 需要从 MongoDB 中查询出包含
actionpermissiontopics字段的数据列表,使用方式详见 AuthZ-MongoDB。
如需继续使用 4.x 中的数据,请手动迁移适配。
5.0 中数据示例
[
{
"username": "emqx_u",
"clientid": "emqx_c",
"ipaddress": "127.0.0.1",
"permission": "allow",
"action": "all",
"topics": ["#"]
}
]
Redis 变动
- Redis 数据源仍然仅支持白名单模式,要求设置
acl_nomatch = deny; access字段名变为action,数据由数字变为动作全称字符串,对应关系见下表。
| 4.x | 5.0.0 | 对应动作 |
|---|---|---|
| 1 | subscribe | 订阅 |
| 2 | publish | 发布 |
| 3 | all | 发布订阅 |
如需继续使用 4.x 中的数据,请手动迁移适配。
5.0 中数据示例
HSET mqtt_acl:emqx_u t/# subscribe
HSET mqtt_acl:emqx_u # all
HSET mqtt_acl:emqx_u a/1 publish
HTTP 变动
- 使用响应 Body 里面的 JSON 字段而非响应状态码(HTTP response status codes)判断认证结果。
成功响应状态码:
200 或 204
其他状态码或请求失败则忽略该授权检查器。
成功响应 Body (JSON):
| 名称 | 类型 | 必选 | 说明 |
|---|---|---|---|
| result | 枚举 | true | allow | deny | ignore |
{
"result": "deny"
}
规则引擎
规则引擎已更名为数据集成,包含规则与数据桥接功能。
规则 SQL 完全兼容 4.x 的语法,但规则下的动作拆分为内置动作(republish、console)与数据桥接(WebHook、MQTT Sink、MQTT Source),以便实现”动作”的复用。
WebHook
WebHook 插件(emqx_web_hook) 已被移除,请使用数据集成中的 WebHook 数据桥接功能替代。
MQTT 桥接
MQTT 桥接插件(emqx_bridge_mqtt) 已被移除,请使用数据集成中的 MQTT Sink 和 MQTT Source 数据桥接功能替代。
Prometheus
旧的 Prometheus 插件 (emqx_prometheus) 已被移除。 在5.0中,Prometheus 的数据拉取服务默认开启,且无需认证就可以拉取数据。 可以使用 curl 命令来查看:curl -f “127.0.0.1:18083/api/v5/prometheus/stats”
如果您想要使用 push-gateway,您可以在 prometheus {…} 配置块中启用它。 或者在仪表盘中修改配置并启用。
指标变动情况:
| 4.4.4 | 5.0 | 说明 |
|---|---|---|
| emqx_client_auth_success_anonymous | emqx_client_auth_anonymous | 更名 |
| emqx_client_check_acl | emqx_client_authorize counter | 更名 |
| - | emqx_mria_last_intercepted_trans | 新增 |
| - | emqx_mria_replicants | 新增 |
| - | emqx_mria_server_mql | 新增 |
| - | emqx_mria_weight | 新增 |
| emqx_routes_count | emqx_topics_count | 更名 |
| emqx_routes_max | emqx_topics_max | 更名 |
| emqx_session_takeovered | emqx_session_takenover | 更名 |
| erlang_vm_ets_tables | - | 移除 |
| - | erlang_vm_memory_dets_tables | 新增 |
| - | erlang_vm_memory_ets_tables | 新增 |
| - | erlang_vm_msacc_alloc_seconds_total | 新增 |
| - | erlang_vm_msacc_aux_seconds_total | 新增 |
| - | erlang_vm_msacc_bif_seconds_total | 新增 |
| - | erlang_vm_msacc_busy_wait_seconds_total | 新增 |
| - | erlang_vm_msacc_check_io_seconds_total | 新增 |
| - | erlang_vm_msacc_emulator_seconds_total | 新增 |
| - | erlang_vm_msacc_ets_seconds_total | 新增 |
| - | erlang_vm_msacc_gc_full_seconds_total | 新增 |
| - | erlang_vm_msacc_gc_seconds_total | 新增 |
| - | erlang_vm_msacc_nif_seconds_total | 新增 |
| - | erlang_vm_msacc_other_seconds_total | 新增 |
| - | erlang_vm_msacc_port_seconds_total | 新增 |
| - | erlang_vm_msacc_send_seconds_total | 新增 |
| - | erlang_vm_msacc_sleep_seconds_total | 新增 |
| - | erlang_vm_msacc_timers_seconds_total | 新增 |
| - | erlang_vm_statistics_dirty_cpu_run_queue_length | 新增 |
| - | erlang_vm_statistics_dirty_io_run_queue_length | 新增 |
| - | erlang_vm_wordsize_bytes | 新增 |
网关/多协议接入
其他协议(LwM2M、CoAP、STOMP、MQTT-SN)的客户端将不再映射为 MQTT 客户端,无法通过 Dashboard 客户端页面和 GET /clients API 获取。 用户可以前往网关页面详情页面或通过 GET /gateway/{name}/clients API 获取。
