从 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 中查询出包含
action
permission
topics
字段的数据列表,使用方式详见 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 获取。