MQTT客户端开发实战:C/C++/Python跨平台选型与部署对比
1. 项目概述为什么我们要实测三种语言的MQTT客户端最近在做一个需要跨平台Windows、macOS、Linux运行的物联网数据采集项目核心需求是设备端通过MQTT协议上报数据。选型时我首先想到了业界轻量级的标杆——Mosquitto。但问题来了Mosquitto官方提供了C、C和Python三种语言的客户端库libmosquittolibmosquittopppaho-mqtt到底该用哪个网上资料要么是简单的“Hello World”示例要么只谈单一语言很少有从跨平台部署、开发效率、运行时性能和资源消耗这几个维度进行横向对比的。这就像装修房子C语言是给你砖头、水泥和钢筋让你从地基开始砌C是提供了预制好的承重墙和楼板你负责组装和内部装修Python则是精装房拎包入住但你可能没法改承重墙。选择哪种取决于你的项目是摩天大楼、普通住宅还是临时样板间。因此我决定自己动手进行一次深入的实测。目标很明确不是比较语言本身的优劣而是在“使用Mosquitto库实现跨平台MQTT客户端”这个具体场景下对比三种方案的开发体验、部署复杂度和运行时表现为面临类似选择的开发者提供一个接地气的参考。实测环境覆盖了Windows 11、Ubuntu 22.04 LTS和macOS Ventura力求结论具有普适性。2. 核心需求与方案选型背后的逻辑在开始敲代码之前我们必须厘清需求这直接决定了技术栈的选型。我的项目需求可以归纳为以下几点功能核心稳定地连接MQTT Broker服务器实现主题Topic的订阅与发布并处理QoS 0/1级别的消息。需要支持TLS加密连接和用户名密码认证。跨平台性生成的客户端程序或脚本必须能在上述三个主流桌面操作系统上运行且行为一致。部署简易性对于生产环境客户端的部署过程应尽可能简单依赖少最好能做成单一可执行文件或易于打包的格式。开发效率在满足性能要求的前提下快速实现业务逻辑、调试方便是重要考量。资源占用客户端可能运行在资源受限的边缘设备或长期开机的工控机上内存和CPU占用需要可控。基于这些需求我们来看三个候选方案C客户端 (libmosquitto)这是Mosquitto项目最核心、最底层的库。它提供了纯C的异步API。选择它意味着你对最终程序的大小、内存布局和运行时行为有绝对的控制权性能理论上是最高的并且不依赖任何额外的运行时环境如C标准库的特定版本或Python解释器。但代价是你需要手动管理内存、连接状态和回调函数开发效率最低且容易引入内存泄漏和指针错误。C客户端 (libmosquittopp)这是官方提供的C封装库本质上是对libmosquitto的面向对象包装。它提供了mosquittopp类将C的回调函数封装成了虚函数如on_connect,on_message让代码组织更符合现代C开发者的习惯。它继承了C版本的高性能和低依赖同时提升了代码的可读性和可维护性。但你需要处理C的编译环境如libstdc版本和更复杂的二进制兼容性问题。Python客户端 (paho-mqtt)这是Eclipse Paho项目提供的MQTT客户端库是Python生态中的事实标准与Mosquitto Broker兼容性极佳。它的优势是压倒性的开发效率几行代码就能实现核心功能并且拥有极其丰富的生态支持如结合Web框架、数据分析库。但其劣势同样明显运行需要Python解释器部署时需要打包整个Python环境或依赖用户预装运行时性能和内存开销通常高于编译型语言。注意libmosquittopp并非独立于libmosquitto它是对后者的封装。因此在讨论部署时C和C客户端共享同一个核心依赖libmosquitto动态库或静态链接的代码。选型背后的核心权衡本质上这是在“控制力/性能”与“开发效率/部署便利性”之间做取舍。C/C站在前一阵营Python站在后一阵营。本次实测就是要量化这种取舍看看在2024年的技术环境下这个天平究竟倾斜了多少。3. 环境准备与三种客户端的“Hello MQTT”实测的第一步是在三个平台上搭建统一的测试环境。我们使用Mosquitto官方提供的测试Brokertest.mosquitto.org非加密端口1883 TLS端口8883。为了公平对比所有客户端实现相同的功能连接Broker订阅主题test/topic并向该主题发布一条消息“Hello from [Language]”同时接收自己发出的消息并打印。3.1 基础环境搭建Mosquitto Broker我们仅作为客户端测试无需自行搭建。使用公共Broker即可。C/C编译环境Windows使用MSYS2 MinGW-w64安装gcc、make和libmosquitto-devel包。也可以使用Visual Studio但为了跨平台一致性我们选择GCC工具链。Ubuntusudo apt install libmosquitto-dev g makemacOSbrew install mosquitto 这会同时安装客户端库和开发头文件。Python环境统一使用Python 3.8通过pip安装pip install paho-mqtt3.2 C客户端实现与踩坑记录C版本的代码最为原始。你需要设置一系列的回调函数并在主循环中调用mosquitto_loop来处理网络事件。#include stdio.h #include mosquitto.h void on_connect(struct mosquitto *mosq, void *obj, int rc) { if (rc 0) { printf(C Client Connected!\n); mosquitto_subscribe(mosq, NULL, test/topic, 0); } else { fprintf(stderr, Connect failed: %s\n, mosquitto_connack_string(rc)); } } void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg) { printf(C Client Received on topic %s: %s\n, msg-topic, (char*)msg-payload); } int main() { struct mosquitto *mosq NULL; int rc; mosquitto_lib_init(); mosq mosquitto_new(c-client-test, true, NULL); if (!mosq) { fprintf(stderr, Failed to create client instance\n); return 1; } mosquitto_connect_callback_set(mosq, on_connect); mosquitto_message_callback_set(mosq, on_message); rc mosquitto_connect(mosq, test.mosquitto.org, 1883, 60); if (rc ! MOSQ_ERR_SUCCESS) { mosquitto_destroy(mosq); fprintf(stderr, Failed to connect: %s\n, mosquitto_strerror(rc)); return 1; } // 发布一条消息 mosquitto_publish(mosq, NULL, test/topic, strlen(Hello from C), Hello from C, 0, false); // 主事件循环 rc mosquitto_loop_forever(mosq, -1, 1); if (rc ! MOSQ_ERR_SUCCESS) { fprintf(stderr, Loop error: %s\n, mosquitto_strerror(rc)); } mosquitto_destroy(mosq); mosquitto_lib_cleanup(); return 0; }编译命令gcc -o mqtt_c_client mqtt_c_client.c -lmosquitto实操心得与坑点内存管理mosquitto_new和mosquitto_destroy必须成对出现。所有通过mosquitto函数分配的资源如mosquitto_message结构体在回调中通常不需要手动释放但务必阅读文档确认。线程安全默认情况下libmosquitto不是线程安全的。如果你在多个线程中调用其API需要自己加锁或者使用mosquitto_threaded_set函数但文档说明有限复杂场景建议将网络循环mosquitto_loop放在一个专用线程。连接状态处理回调函数是异步执行的不能在on_connect回调中直接进行大量阻塞操作否则会阻塞网络循环。发布消息最好在连接成功后的某个业务逻辑点触发而不是写在main函数连接之后因为连接是异步的可能还没成功。上面的示例为了简单直接写在main里在实际生产代码中这不保险。3.3 C客户端实现面向对象的封装C版本使用了类继承。我们创建一个自定义类继承自mosquittopp并重写虚函数回调。#include iostream #include cstring #include mosquittopp.h class MyMosquittoClient : public mosquittopp::mosquittopp { public: MyMosquittoClient(const char *id) : mosquittopp(id) {} void on_connect(int rc) override { if (rc 0) { std::cout C Client Connected! std::endl; subscribe(NULL, test/topic); // 在连接成功后发布消息更稳妥 publish(NULL, test/topic, strlen(Hello from C), Hello from C, 0, false); } else { std::cerr Connect failed: mosquitto_connack_string(rc) std::endl; } } void on_message(const struct mosquitto_message *msg) override { std::cout C Client Received on topic msg-topic : static_castchar*(msg-payload) std::endl; } }; int main() { mosqpp::lib_init(); MyMosquittoClient client(cpp-client-test); client.connect(test.mosquitto.org, 1883, 60); // 进入事件循环 int rc client.loop_forever(); if (rc ! MOSQ_ERR_SUCCESS) { std::cerr Loop error: mosquitto_strerror(rc) std::endl; } mosqpp::lib_cleanup(); return 0; }编译命令g -o mqtt_cpp_client mqtt_cpp_client.cpp -lmosquittopp -lmosquitto实操心得与坑点编译链接注意链接顺序-lmosquittopp必须放在-lmosquitto之前因为前者依赖后者。在Windows下使用MinGW库名可能是-lmosquittopp -lmosquitto -lws2_32需要链接Windows socket库。构造函数mosquittopp类的构造函数要求传入一个客户端IDclient id。如果传入NULL库会随机生成一个但某些Broker可能有特定要求。生命周期管理C版本利用RAII资源获取即初始化特性在MyMosquittoClient对象析构时其基类会处理部分清理工作。但mosqpp::lib_init()和mosqpp::lib_cleanup()仍需手动调用它们是库的全局初始化和清理。代码组织明显比C版本更清晰。业务逻辑集中在重写的虚函数中与网络事件处理解耦更适合中大型项目。3.4 Python客户端实现极致的开发效率Python版本的代码简洁得令人发指。import paho.mqtt.client as mqtt def on_connect(client, userdata, flags, rc): if rc 0: print(Python Client Connected!) client.subscribe(test/topic) client.publish(test/topic, Hello from Python) else: print(fConnect failed with code {rc}) def on_message(client, userdata, msg): print(fPython Client Received on topic {msg.topic}: {msg.payload.decode()}) client mqtt.Client(python-client-test) client.on_connect on_connect client.on_message on_message client.connect(test.mosquitto.org, 1883, 60) client.loop_forever()运行命令python mqtt_python_client.py实操心得与坑点同步与异步paho-mqtt的loop_forever()是阻塞的。对于GUI应用或需要同时处理其他任务的程序可以使用loop_start()在后台启动一个线程或者使用loop()进行非阻塞式轮询。这是Python客户端灵活性的一大体现。异常处理网络操作可能抛出异常生产代码务必用try...except包裹connect和loop等相关调用。依赖管理虽然代码简单但部署机器上必须有Python和paho-mqtt库。用pip install安装很简单但在没有互联网或严格管控的生产环境你需要自己准备离线包或使用打包工具。4. 跨平台部署实战从源码到可分发程序开发完成只是第一步如何将你的客户端交付到目标平台运行才是真正的挑战。这部分是本次实测的重点。4.1 C/C客户端的部署静态链接 vs 动态链接C/C程序部署的核心问题是库依赖。你需要处理libmosquitto和libmosquittopp的依赖。方案一动态链接默认这是最简单的编译方式如上文的编译命令。生成的可执行文件很小几十KB但它运行时需要目标系统上存在对应版本的libmosquitto.soLinux、libmosquitto.dylibmacOS或libmosquitto.dllWindows。Linux/macOS可以通过包管理器apt,brew安装运行时库或者将动态库与可执行文件放在同一目录并通过LD_LIBRARY_PATHLinux或修改可执行文件的rpathmacOS来指定路径。痛点不同Linux发行版的库版本可能不兼容glibc版本问题macOS也存在类似问题。Windows你需要将libmosquitto.dll和可能依赖的pthread、openssl等DLL一起拷贝到可执行文件旁边。痛点收集所有正确的DLL是一件繁琐的事情尤其是依赖OpenSSL时。方案二静态链接将Mosquitto库的代码直接编译进你的可执行文件生成一个“大单体”程序。这样目标系统就不需要安装任何额外的库。如何操作这要求Mosquitto库在编译时提供了静态库.a或.lib文件。通常需要从源码编译Mosquitto并启用静态库选项。Linux/macOS./configure --enable-static然后make。编译客户端时使用-static标志并链接静态库文件如-l:libmosquitto.a。Windows (MinGW)过程类似但需要准备好依赖库如OpenSSL的静态版本。优点部署极其简单只有一个可执行文件复制过去就能运行。缺点可执行文件体积巨大从几十KB膨胀到几MB甚至十几MB。如果静态链接了GPL协议的库注意Mosquitto是EPL/EDL许可证但它的依赖如OpenSSL有其自己的许可证可能会对你的软件分发许可证产生影响需要仔细审查。失去了动态库更新的灵活性。如果库有安全更新你需要重新编译并分发整个程序。我的实测选择与建议 对于追求极致简化部署的跨平台项目我倾向于静态链接。尽管体积大但“一个文件解决所有问题”的便利性在很多时候压倒一切。我使用Musl libc在Linux上编译静态版本可以彻底摆脱glibc版本依赖实现真正的“一次编译到处运行”。在Windows上使用MSYS2环境编译静态版本虽然麻烦但一旦做好交叉编译工具链就可以批量生产。4.2 Python客户端的部署打包成独立可执行文件Python脚本的部署痛点在于Python解释器本身和第三方库。解决方案是使用打包工具。方案一依赖现有Python环境要求用户机器上安装指定版本的Python和pip然后通过requirements.txt安装依赖。这是开发期最常见的方式但对终端用户极不友好。方案二使用PyInstaller或Nuitka打包这是生产环境交付的推荐方式。PyInstaller将Python解释器、你的脚本和所有依赖库打包成一个文件夹或单个可执行文件--onefile参数。命令pyinstaller --onefile --clean mqtt_python_client.py优点简单易用兼容性好支持跨平台打包但需要在目标平台对应的系统上执行打包命令或使用交叉编译。缺点生成的单文件启动较慢需要解压到临时目录文件体积大一个简单的MQTT客户端打包后可能在30-50MB左右。并且某些涉及C扩展的库如加密相关在打包时可能会遇到问题。Nuitka将Python代码编译成C代码再编译成二进制可执行文件。命令nuitka --standalone --onefile mqtt_python_client.py优点理论上性能更好生成的是原生二进制文件。缺点编译过程更复杂对某些动态特性强的Python代码支持可能不如PyInstaller完善社区规模相对较小。我的实测选择与建议 对于小型工具或内部系统PyInstaller的单文件模式是首选。虽然体积大但用户无需关心Python环境双击即可运行体验接近原生应用。实测中一个简单的MQTT客户端在Windows下打包后约35MB在Linux下约25MB。你需要为每个目标平台Windows, Linux, macOS分别进行打包操作。部署复杂度对比表特性C客户端 (静态链接)C客户端 (静态链接)Python客户端 (PyInstaller)最终交付物单个可执行文件单个可执行文件单个可执行文件或文件夹文件体积小 (2-5 MB)小 (2-6 MB)大 (25-50 MB)外部依赖无无无已打包构建复杂度高需配置静态编译高需配置静态编译中安装PyInstaller后一条命令跨平台构建需要对应平台的工具链需要对应平台的工具链可在各自平台打包或使用交叉工具运行时性能最优优良好启动慢运行尚可适用场景资源受限设备、追求极致性能、对启动速度敏感大型跨平台应用、需要面向对象设计、性能要求高快速原型、内部工具、对开发效率要求极高、逻辑复杂且依赖丰富Python生态5. 性能与资源消耗实测对比部署问题解决了我们来看看运行时的表现。我设计了一个简单的压力测试客户端连接本地部署的Mosquitto Broker以每秒10次的频率QoS 1向一个主题发布一条1KB大小的消息持续60秒。同时订阅该主题并计数。测试在同一台机器Intel i7 16GB RAM上进行以减少系统差异。测试指标CPU占用率客户端进程的平均CPU使用率。内存占用RSS客户端进程的常驻内存集大小。消息收发延迟计算从发布到接收到的平均往返时间RTT由于是本地环回主要反映客户端库内部处理开销。代码复杂度完成相同功能所需的代码行数LoC。实测结果摘要指标C客户端C客户端Python客户端 (paho-mqtt)CPU占用 (平均)0.8% - 1.2%0.9% - 1.5%2.5% - 4.0%内存占用 (RSS)~3.5 MB~4.2 MB~28 MB(基础解释器)消息延迟 (平均)~0.15 ms~0.18 ms~0.8 ms代码行数 (功能完整)~80行~60行~15行TLS连接建立速度最快快较慢Python SSL上下文初始化开销结果分析C与C性能几乎持平两者在CPU、内存和延迟上的差异微乎其微C的额外开销主要来自其运行时类型信息和虚函数表在此类IO密集型网络应用中影响极小。选择C还是C更多是基于项目代码风格和维护性的考量而非性能。Python的资源开销显著内存占用高出一个数量级这主要是Python解释器本身的开销。CPU占用也更高因为每条消息的序列化、反序列化以及事件循环都是在Python层面处理存在解释器开销。但对于每秒10条消息的低频场景4%的CPU占用完全可接受。延迟差异在可接受范围即使是Python0.8ms的延迟对于绝大多数物联网应用如传感器数据上报控制指令下发来说也是绰绰有余的。只有在超高频每秒数万条或硬实时场景下这毫秒级的差异才需要被严肃考虑。开发效率的代价Python用5倍的内存和2-3倍的CPU开销换来了4-5倍的代码精简度。这个交易是否划算完全取决于项目约束。注意Python的内存占用并非线性增长。启动后解释器和基础库占用了大部分内存约20-25MB随着消息处理增长并不剧烈。如果你的客户端需要处理大量并发连接或维持巨大的消息缓存Python的内存管理垃圾回收可能会带来不确定的延迟而C/C的手动/半自动内存控制则更可预测。6. 高级功能与生态支持深度对比基础功能都能实现那高级特性呢这往往决定了方案的最终天花板。6.1 TLS/SSL加密支持三种客户端都支持TLS加密连接但易用性不同。C/C客户端需要手动指定CA证书、客户端证书和私钥文件路径。代码稍显繁琐并且你需要正确处理文件路径的跨平台问题尤其是Windows的反斜杠。优势是你可以精细控制TLS的版本、密码套件等参数。// C示例代码片段 mosquitto_tls_set(mosq, “ca.crt”, NULL, “client.crt”, “client.key”, NULL);Python客户端同样支持但API更简洁。并且得益于Python强大的生态你可以轻松地使用ssl模块从内存加载证书或者动态获取证书这在某些云平台或容器环境中非常有用。client.tls_set(ca_certs“ca.crt”, certfile“client.crt”, keyfile“client.key”) # 或者使用ssl上下文进行更复杂的配置 import ssl context ssl.create_default_context() client.tls_set_context(context)6.2 持久化与会话Clean SessionMQTT协议支持持久化会话当客户端断开重连后能恢复之前的订阅和未确认的QoS 1/2消息。三种客户端库都支持此功能。C/C客户端在mosquitto_new或mosquittopp构造函数中将clean_session参数设为false即可。但你需要自己管理可能到来的“遗留”消息。Python客户端在Client构造函数中设置clean_sessionFalse。paho-mqtt库会自动处理会话状态的维护。实操心得除非你有明确的断线重连且不丢失消息的需求否则建议使用clean_sessionTrue默认值这能避免Broker端堆积陈旧消息造成意料之外的行为。6.3 生态与扩展性这是Python的绝对主场。Pythonpaho-mqtt可以无缝融入整个Python数据科学和Web生态。你可以用几行代码将MQTT数据接入Pandas进行实时分析用Flask/Django搭建一个MQTT消息的Web控制面板或者用asyncio将其集成到高性能异步应用中。这种扩展性是C/C难以比拟的。C/C生态更偏向底层和性能。你可以轻松地将MQTT客户端嵌入到RTOS如FreeRTOS、Zephyr中运行在单片机MCU上这是Python做不到的。你也可以用C的客户端作为核心通信模块供上层Qt、WxWidgets等GUI框架调用构建复杂的桌面应用。7. 常见问题排查与实战避坑指南在实际开发和部署中我遇到了不少坑。这里总结一份速查表希望能帮你节省时间。问题现象可能原因解决方案C/C解决方案Python编译错误找不到mosquitto.h开发库未安装或路径不对。Linux/macOS: 确认libmosquitto-dev或mosquitto(brew) 已安装。Windows (MSYS2):pacman -S mingw-w64-x86_64-mosquitto。检查编译器-I包含路径。不适用。链接错误未定义的引用链接时找不到库文件。确保-lmosquittoC或-lmosquittopp -lmosquittoC参数正确。Windows下可能还需-lws2_32。检查库文件路径-L。不适用。运行时错误找不到动态库目标系统没有安装libmosquitto运行时库。动态链接将对应的.so/.dylib/.dll文件放到可执行文件同级目录或设置系统库路径。推荐静态链接一劳永逸。不适用。连接失败返回错误码 5拒绝连接Broker地址、端口错误或网络不通。Broker需要认证但未提供。检查mosquitto_connect参数。如果需要认证调用mosquitto_username_pw_set。使用mosquitto_strerror(rc)打印错误信息。检查connect()参数。如果需要认证在Client构造函数中传入username和password参数。能连接但收不到消息订阅的主题Topic与发布的不匹配大小写、通配符。客户端未进入事件循环。仔细核对主题字符串。确保在连接成功的回调或之后进行订阅。必须调用mosquitto_loop()系列函数如loop_forever启动网络循环。核对主题。确保loop_forever()或loop_start()被调用。检查回调函数on_message是否正确赋值。程序卡住或无反应网络循环被阻塞。在回调函数中执行了耗时操作。确保回调函数on_message,on_connect快速返回。将耗时操作放入队列由其他线程处理。考虑使用mosquitto_loop_start()在内部线程运行循环。同上。在Python中如果在on_message里进行长时间I/O如写数据库会阻塞整个事件循环。应使用线程池ThreadPoolExecutor或异步框架asyncio。内存使用缓慢增长C/C内存泄漏。未正确配对调用mosquitto_new/destroy或在回调中错误地分配了内存未释放。使用ValgrindLinux或Dr. MemoryWindows等工具检测。确保所有malloc/mosquitto_*分配都有对应的free/mosquitto_*_destroy。Python有垃圾回收但仍需注意循环引用。通常paho-mqtt自身内存管理良好。Python打包后运行报错PyInstaller未打包进某些隐式依赖或数据文件。使用pyinstaller --onefile --add-data “ca.crt;.”添加数据文件。对于隐藏导入使用--hidden-import。在打包后环境中调试 (--debug)。使用sys._MEIPASS访问打包后的资源文件路径。最重要的一个坑网络循环Loop无论是C的mosquitto_loop、C的loop还是Python的loop_forever这个函数是MQTT客户端的心脏。它负责接收网络数据、调用回调函数、维持心跳。你必须确保它在程序生命周期内持续运行。一个常见的错误是在main函数中连接后直接退出或者在一个短暂运行的线程中启动循环。在GUI程序中通常需要在一个独立的、不阻塞UI线程的worker线程中运行网络循环。8. 最终抉择我的选型建议与场景匹配经过这一轮从开发、部署到性能的完整实测我们可以得出更清晰的结论。没有“最好”的方案只有“最适合”的方案。选择 C 客户端如果你开发的是运行在极端资源受限环境如嵌入式MCU内存只有几十KB的固件。项目对启动速度和内存占用有极致要求不能容忍任何额外开销。你的团队精通C语言并且项目架构已经是纯C的。你需要将MQTT客户端作为一个小型库嵌入到其他更大的C项目中。选择 C 客户端如果你项目是大型的、跨平台的桌面或服务器端应用例如使用Qt框架的工业控制软件。你需要面向对象的设计来更好地管理复杂的连接状态、消息路由和业务逻辑。你追求接近C的性能但希望代码比纯C更易维护和扩展。你的目标平台可能没有Python环境且你不希望交付物体积像Python打包后那么大静态链接的C程序通常在10MB以内。选择 Python 客户端如果你追求极致的开发速度和原型验证能力。“想法到可运行代码”的时间至关重要。项目逻辑复杂需要快速集成数据库SQLAlchemy、Web APIRequests、数据分析Pandas或机器学习TensorFlow等丰富的第三方库。你的客户端是更庞大Python系统中的一个组件例如一个Django Web应用的后台消息处理器。部署环境你完全可控如容器化环境或者可以接受通过PyInstaller打包后较大的体积。你的团队Python技能更强且项目没有严格的实时性或硬资源限制。对于我自己的物联网数据采集项目最终我选择了C客户端静态链接的方案。原因如下项目需要部署在多种版本的Linux边缘设备上静态链接消除了所有库依赖问题运维同事只需要复制一个文件。程序需要7x24小时稳定运行对内存泄漏敏感C的RAII特性结合智能指针能提供比纯C更好的资源管理保障。性能完全满足要求每秒处理数百条消息同时代码结构比C更清晰便于后续增加数据解析、本地缓存等模块。交付物体积约5MB远小于Python打包方案便于网络传输和存储。当然在项目的管理后台和数据分析侧我大量使用了Python和paho-mqtt因为它能快速搭建起功能丰富的Web界面和实时数据看板。这就是混合架构的魅力在适合的地方使用最适合的工具。最后一个小技巧无论选择哪种语言务必在你的代码中实现完善的日志系统。MQTT是异步的很多错误发生在回调函数中没有日志你将很难在分布式部署中定位“连接时好时坏”、“偶尔收不到消息”这类幽灵问题。对于C/C可以集成spdlog对于Python标准库的logging就足够强大。清晰的日志是后期运维的救命稻草。

相关新闻

最新新闻

日新闻

周新闻

月新闻