EMQX Golang 集成 Jmeter 性能测试

上一篇博客介绍了MQTT服务器的安装,客户端工具的使用,以及MQTT协议常用的一些特性。这篇博客从开发的角度去学习下程序如何接入MQTT数据,如服务器监控数据、消息订阅、数据桥接等。

监控数据

EMQX 提供了管理监控 REST API,这些 API 遵循 OpenAPI (Swagger) 3.0 规范。EMQX 服务启动后,您可以访问 http://localhost:18083/api-docs/index.html 来 查看 API 的文档。

在这里插入图片描述

上图所示,操作Swagger API文档需要授权,创建授权的步骤如下:

前提条件,修改默认账号密码:

  • 登录Dashboard,默认密码( 默认的访问用户名是 admin 密码是 public)建议您立即修改。登录EMQX 的 HTTP API 的账号密码跟Dashboard登录账号信息一致。
  • 使用命令号修改密码
emqx ctl admins passwd admin new-password

创建授权账号

API文档的创建认证方式有两种,操作方式如下

  1. 在 Dashboard “系统设置” -> “API 密钥” 界面点击创建

在这里插入图片描述

  1. 通过调用API创建 参数如下
curl -u 'admin:123qwe' \
     -X 'POST' 'http://localhost:18083/api/v5/api_key' \
     -H 'accept: application/json' \
     -H 'Content-Type: application/json' \
     -d '{
            "name": "EMQX-API-KEY-5",
            "expired_at": "2022-12-05T02:01:34.186Z",
            "desc": "for testing",
            "enable": true,
            "expired": true
        }' | jq
# | jq 含义: 结果重定向格式化输出

返回秘钥信息

{
  "api_key": "eada7c83e86c53b4",
  "api_secret": "f2559BifAzriy9C3E9AksNe7sy9CILflK278dHAYw9AYFGhA",
  "created_at": "2022-10-16T04:23:18+00:00",
  "desc": "for testing",
  "enable": true,
  "expired": false,
  "expired_at": "2022-12-05T02:01:34+00:00",
  "name": "EMQX-API-KEY-5"
}

小细节,从官网看到的的调用代码,直接复用的话在我的电脑会报错,原因是多了个符号

在这里插入图片描述

在这里插入图片描述

API 授权

REST API 认证方式截图

在这里插入图片描述

在 Username / Password 处输入api_key / api_secret (之前返回的认证信息) 点击授权,即可

"api_key": "eada7c83e86c53b4",
"api_secret": "f2559BifAzriy9C3E9AksNe7sy9CILflK278dHAYw9AYFGhA",

随便选择一个API接口,点击执行即可,测试效果图如下

在这里插入图片描述

应用场景

通过EMQX服务器暴露的REST API, 开发人员可以通过HTTP接口获取EMQX运行信息,如节点信息、运行状态、服务器运行指标、主题信息、设备在线情况等等,其目的是:产品可以根据业务侧重选取一些关键性的业务指标,集成到统一的运维监管平台

消息订阅

在物联网业务系统中,通过消息订阅的方式获取智能设备实时/定时上报的数据,从而做相应的业务处理,以下Demo 使用golang语言订阅消息。

安装依赖

go get github.com/eclipse/paho.mqtt.golang

在这里插入图片描述

在这里插入图片描述

普通主题

package main

import (
	"fmt"
	mqtt "github.com/eclipse/paho.mqtt.golang"
	"log"
	"os"
	"time"
)

var f mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
	//fmt.Printf("TOPIC: %s\n", msg.Topic())
	//fmt.Printf("MSG: %s\n", msg.Payload())

	fmt.Println("--------------------- subscribe message info ", msg.Topic(), string(msg.Payload()))
}

func main() {
	mqtt.DEBUG = log.New(os.Stdout, "", 0)
	mqtt.ERROR = log.New(os.Stdout, "", 0)

	opts := mqtt.NewClientOptions().AddBroker("tcp://localhost:1883").SetClientID("golang_client")
	opts.SetKeepAlive(60 * time.Second)
	//设置消息回调处理函数
	opts.SetDefaultPublishHandler(f)
	opts.SetPingTimeout(1 * time.Second)
	client := mqtt.NewClient(opts)
	if token := client.Connect(); token.Wait() && token.Error() != nil {
		panic(token.Error())
	}

	fmt.Println("--------------------- start to subscribe test Topic")
	time.Sleep(10 * time.Second)
	if token := client.Subscribe("test", 0, nil); token.Wait() && token.Error() != nil {
		fmt.Println(token.Error())
		os.Exit(1)
	}

	// 发布消息
	token := client.Publish("hello1", 0, false, "Hello golang")
	token.Wait()

	time.Sleep(60 * time.Second)

	// 取消订阅
	if token := client.Unsubscribe("test"); token.Wait() && token.Error() != nil {
		fmt.Println(token.Error())
		os.Exit(1)
	}

	// 断开连接
	client.Disconnect(250)
	time.Sleep(1 * time.Second)

}

执行结果如下,可以看到订阅的消息,发送的消息都有收到。

在这里插入图片描述

系统主题订阅

EMQX 周期性发布自身运行状态、消息统计、客户端上下线事件到以 $SYS/ 开头系统主题。因此可以通过订阅系统主题消息来获取服务器的状态(跟REST API 主动调用的方式不同),通过消息订阅的模式,系统之间解耦,架构更加优雅。

但是系统主题跟普通主题在安全控制上有所不同,请看以下代码

package main

import (
	"fmt"
	mqtt "github.com/eclipse/paho.mqtt.golang"
	"log"
	"os"
	"time"
)

var f mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
	//fmt.Printf("TOPIC: %s\n", msg.Topic())
	//fmt.Printf("MSG: %s\n", msg.Payload())

	fmt.Println("--------------------- subscribe message info ", msg.Topic(), string(msg.Payload()))
}

func main() {
	mqtt.DEBUG = log.New(os.Stdout, "", 0)
	mqtt.ERROR = log.New(os.Stdout, "", 0)

	opts := mqtt.NewClientOptions().AddBroker("tcp://localhost:1883").SetClientID("golang_client")
	opts.SetKeepAlive(60 * time.Second)
	//设置消息回调处理函数
	opts.SetDefaultPublishHandler(f)
	opts.SetPingTimeout(1 * time.Second)
	client := mqtt.NewClient(opts)
	if token := client.Connect(); token.Wait() && token.Error() != nil {
		panic(token.Error())
	}

	fmt.Println("--------------------- start to subscribe system Topic")
	if token := client.Subscribe("$SYS/brokers/#", 0, nil); token.Wait() && token.Error() != nil {
		fmt.Println(token.Error())
		os.Exit(1)
	}

	time.Sleep(1 * time.Hour)

	// 取消订阅
	if token := client.Unsubscribe("$SYS/brokers/#"); token.Wait() && token.Error() != nil {
		fmt.Println(token.Error())
		os.Exit(1)
	}

	// 断开连接
	client.Disconnect(250)
	time.Sleep(1 * time.Second)

}

运行以上代码,操作MQTTX工具频繁的操作客户端上/下线接收不到任何的数据。究其原因是由于EMQX服务的安全控制机制导致的,EMQX 默认只允许本机的 MQTT 客户端订阅 $SYS 主题(服务器用docker安装,因此跟宿主机不是同一台机器),拒绝其他机器订阅系统主题。

可以通过修改默认规则,来解决此类问题。登录DashBoard, 在 "认证 -> 授权"菜单中,点击设置按钮.默认为deny,改成allow 允许,然后更新配置。

在这里插入图片描述

再次运行代码,操作客户端上/下线,查看控制台输出

在这里插入图片描述

WebHook

Webhook 是 EMQX 向 HTTP 服务发送消息的通道。通过 Webhook,用户可以选择某个本地主题,将消息 发送到远程 HTTP 服务,也可以将规则的输出发送到 HTTP 服务。

HTTP服务器代码

启动HTTP服务器程序

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"time"
)

func main() {
	http.HandleFunc("/webhook", postRequest)
	s := &http.Server{
		Addr:           ":8888",
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}
	err := s.ListenAndServe()
	if err != nil {
		log.Fatal("listenAndServe: ", err)
	}
}

func postRequest(w http.ResponseWriter, r *http.Request) {
	var bodyBytes []byte
	if r.Body != nil {
		bodyBytes, _ = ioutil.ReadAll(r.Body)
	}
	defer r.Body.Close()
	fmt.Println("request args : ", string(bodyBytes))
	w.Header().Set("Content-Type", "application/json")
	reply := "{\"result\": \"ok\", \"message\": \"success\"}"
	w.Write([]byte(reply))
}

创建 Webhook 并关联到规则

  1. 现在我们访问 Dashboard,选择左边栏 “数据集成” - “数据桥接”:

image

  1. 然后点击创建,选择 Webhook,点击 “下一步”:

image

  1. 将 Webhook 命名为 my_webhook,URL 为 http://192.168.0.17:8888/webhook(docker安装EMQX 不能填写localhost):

在这里插入图片描述

  1. 点击 “创建”,然后在弹出来的对话框里选择创建关联规则:

image

  1. 在规则的创建页面,填入如下 SQL 语句,其余参数保持默认值:
SELECT * FROM "tt/#"

在这里插入图片描述

点击页面下方的 “创建” 按钮。

发送数据进行测试

接下来我们使用 MQTTX 发送一条数据到 tt/2`

在这里插入图片描述

性能测试

emqtt_bench

是基于 Erlang 编写的,一个简洁强大的 MQTT 协议性能测试工具。在安装该工具时,来来回回折腾了近2小时,到最后无赖放弃。

在这里插入图片描述

官方说明,只需要21.2以上的版本即可,实际测试发现在执行make命令编译的时候发现以下两个版本根本压根不行:

  • Erlang/OTP 21
  • Erlang/OTP 25

最后下载 Erlang/OTP 23.3.4.18 该版本才能正常执行make命令,但是事情尚未结束

[root@localhost emqtt-bench]# make
/opt/software/mqtt/emqtt-bench/rebar3 unlock
/opt/software/mqtt/emqtt-bench/rebar3 compile
===> Verifying dependencies...
===> Fetching quicer (from {git,"https://github.com/emqx/quic.git",{tag,"0.0.16"}})
===> Failed to fetch and copy dep: {git,"https://github.com/emqx/quic.git",
                                   {tag,"0.0.16"}}
make: *** [compile] Error 1

最后无奈放弃,等有时间再去研究。

Jmeter

插件安装

Jmeter MQTT插件包下载地址

将jar包放入到 $JMETER_HOME/lib/ext 目录下,启动Jmeter,在取样器里面看到MQTT相关的信息代表安装成功

在这里插入图片描述

数据测试

Jmeter MQTT插件提供4个维度的取样器进行MQTT测试

  • 连接测试
  • 断开链接
  • 消息发送
  • 消息订阅

下面测试连接、消息发送两种维度(插件目前只支持MQTT3的协议,MQTT5协议暂不支持)

在这里插入图片描述

在这里插入图片描述

选择随机发送数据,点击测试然后观察EMQX Dashboard,可以明显得看到MQTT服务器的连接数、消息流入信息。

在这里插入图片描述

Jmeter 的聚合报告如下

在这里插入图片描述

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值