1. EMQTT概述与核心特性
EMQTT是一个基于Erlang语言实现的MQTT客户端库和命令行工具,支持MQTT v5.0/3.1.1/3.1协议。作为EMQX生态的重要组成部分,它提供了轻量级的MQTT通信能力,特别适合需要嵌入式MQTT客户端或自动化测试场景的开发需求。
在实际物联网项目中,我经常使用EMQTT进行设备模拟和协议验证。相比其他MQTT客户端,它有以下几个显著特点:
- 原生支持MQTT 5.0协议特性
- 提供命令行工具和Erlang API两种使用方式
- 支持TCP/TLS/WebSocket/QUIC多种传输协议
- 完善的QoS消息质量保障机制
2. 环境搭建与工具安装
2.1 编译安装
首先需要准备Erlang/OTP环境(建议R21+版本),然后通过源码编译:
git clone https://github.com/emqx/emqtt.git cd emqtt make如果遇到QUIC相关编译问题,可以使用以下命令禁用QUIC支持:
BUILD_WITHOUT_QUIC=1 make编译完成后,会在_build/emqtt/rel/emqtt/bin目录下生成可执行文件emqtt。
2.2 功能验证
执行帮助命令查看功能:
./emqtt --help典型输出应包含:
Usage: emqtt pub | sub [--help] emqtt pub is used to publish a single message on a topic and exit. emqtt sub is used to subscribe to a topic and print the messages that it receives.3. 命令行工具实战
3.1 消息发布
基础发布命令格式:
./emqtt pub -t "主题名" --payload "消息内容"实际案例(带认证参数):
./emqtt pub -h broker.emqx.io -p 1883 -u test -P 123456 \ -t "sensor/1/temperature" --payload "25.6" -q 1关键参数说明:
-h:MQTT服务器地址-p:服务端口(默认1883)-u/-P:认证用户名密码-q:QoS等级(0/1/2)-r:设置保留消息标志
3.2 消息订阅
基础订阅命令:
./emqtt sub -t "主题名"共享订阅示例(MQTT 5.0特性):
./emqtt sub -t '$share/group/sensor/+/status'重要提示:当订阅以$开头的主题时,必须使用单引号包裹主题名
3.3 TLS安全连接
启用SSL/TLS的发布示例:
./emqtt pub --enable-ssl=true \ --CAfile=./certs/cacert.pem \ --cert=./certs/client-cert.pem \ --key=./certs/client-key.pem \ -t "secure/topic" --payload "secret data"支持的TLS版本可通过--tls-version指定(tlsv1.3/tlsv1.2等)
4. Erlang库集成开发
4.1 项目配置
在rebar3项目的rebar.config中添加依赖:
{deps, [ {emqtt, {git, "https://github.com/emqx/emqtt", {tag, "1.14.4"}}} ]}.4.2 基础API使用
典型工作流程示例:
%% 启动客户端 {ok, ConnPid} = emqtt:start_link([{clientid, <<"test-client">>}]). %% 建立连接 {ok, _Props} = emqtt:connect(ConnPid). %% 订阅主题 SubOpts = [{qos, 1}, {rh, 0}]. {ok, _, _} = emqtt:subscribe(ConnPid, #{}, [{<<"test/topic">>, SubOpts}]). %% 发布消息 ok = emqtt:publish(ConnPid, <<"test/topic">>, #{}, <<"Hello">>, [{qos, 1}]). %% 接收消息处理 receive {publish, #{topic := Topic, payload := Payload}} -> io:format("Received ~s on ~s~n", [Payload, Topic]) after 5000 -> io:format("No message received~n") end. %% 断开连接 ok = emqtt:disconnect(ConnPid).4.3 高级特性
遗嘱消息设置:
WillProps = #{ 'Will-Delay-Interval' => 30, 'Message-Expiry-Interval' => 3600 }, emqtt:start_link([ {will_topic, <<"client/status">>}, {will_payload, <<"offline">>}, {will_qos, 1}, {will_props, WillProps} ]).自定义认证回调:
AuthCallbacks = #{ init => {fun my_auth:init/1, [InitialParams]}, handle_auth => fun my_auth:handle/3 }, emqtt:start_link([{custom_auth_callbacks, AuthCallbacks}]).5. 实战经验与问题排查
5.1 性能调优建议
- 设置
{low_mem, true}可减少内存占用 - 合理配置
{max_inflight, N}控制飞行窗口大小 - 对于高吞吐场景建议禁用自动ACK(
{auto_ack, false})
5.2 常见错误处理
连接超时:
- 检查网络连通性
- 确认
connect_timeout参数设置合理(默认60秒) - 验证协议版本兼容性
消息丢失:
- 确认QoS级别设置正确
- 检查
keepalive间隔(默认300秒) - 监控
retry_interval重试机制
TLS握手失败:
- 确保证书链完整
- 检查TLS版本兼容性
- 验证证书有效期
5.3 调试技巧
启用调试日志:
logger:set_primary_config(level, debug).网络抓包分析:
# 对于TCP连接 tcpdump -i any port 1883 -w mqtt.pcap # 对于WebSocket tcpdump -i any port 8083 -w ws.pcap6. 典型应用场景
6.1 设备模拟测试
通过脚本批量启动EMQTT实例:
[begin {ok, Pid} = emqtt:start_link([{clientid, <<"device-", N>>}]), {ok, _} = emqtt:connect(Pid), Pid end || N <- lists:seq(1, 1000)].6.2 自动化运维监控
订阅系统主题获取broker状态:
./emqtt sub -t '$SYS/brokers/+/metrics/#' -q 16.3 协议一致性测试
验证MQTT 5.0特性:
%% 测试主题别名 Props = #{'Topic-Alias-Maximum' => 10}, emqtt:publish(ConnPid, <<"long/topic/name">>, Props, <<"test">>, [{qos, 1}]). %% 测试用户属性 UserProps = #{'User-Property' => [{<<"region">>, <<"east">>}]}, emqtt:publish(ConnPid, <<"event">>, UserProps, <<"">>, []).在实际项目部署中,EMQTT的轻量级特性使其非常适合作为边缘计算场景中的通信组件。我曾在一个工业物联网项目中,使用EMQTT实现了2000+设备的并行连接测试,平均每个客户端进程仅占用约2MB内存,表现出优异的资源效率。