本文最后更新于:June 30, 2023 pm
本文作者:[wangwenhai] # 概要:本文主要介绍EMQX插件开发中的一些细节.
1. 背景概述
本文主要讲一下最新版的EMQX的插件开发.关于插件开发环境准备,请看之前的文章,这里讲讲插件开发中的高级功能:自定义参数配置.
2. 案例学习
在此时前我们先看下几个典型的插件:
1. Mysql插件
大概熟悉一下插件的基本结构:其实我们发现EMQX的插件就是一个很普通的OTP应用,其中代码在src目录下,配置在etc下.
我们首先看下Mysql插件的的配置:
## MySQL server address.
## 为了节省篇幅,我把不重要的全部删了,留下关键几个配置
auth.mysql.server = 127.0.0.1:3306
auth.mysql.pool = 8
auth.mysql.username =
auth.mysql.password =
auth.mysql.database = mqtt
这些配置主要用来配置Mysql的Host,端口,密码等等,我们可以很容易集成进我们的应用中.
2. MongoDb插件
其中MongoDB插件和Mysql插件没区别,结构都是完全一样的,因此我们可以按照这个结构来设计插件.
下面是MongoDb插件的配置:
## MongoDB Topology Type.
## 为了节省篇幅,我把不重要的全部删了,留下关键几个配置
auth.mongo.type = single
auth.mongo.server = 127.0.0.1:27017
auth.mongo.pool = 8
同样和Mysql一样,都是方便用户自定义配置参数进来.
4. 自定义插件
看完了上面两个插件的配置以后,我们发现个规律:配置文件基本都是满足Key-Value这种形式,Key作为配置项,Value作为参数值.理解了这种格式以后,我们可在自定义插件开发中加入进来.
因为EMQX的参数配置使用了一个库:cuttlefish,大家可以去github上找找文档,这个库中文文档比较少,建议大家直接看库文档即可.
1. 新建插件
## 如果没安装插件模板,先安装插件模板
wget https://s3.amazonaws.com/rebar3/rebar3 && chmod +x rebar3
./rebar3 local install
mkdir -p ~/.config/rebar3/templates
git clone https://github.com/emqx/rebar3_emqx_plugin ~/.config/rebar3/templates
## 如果上面的工作都已经完成的话,直接新建插件模板
rebar3 new emqx-plugin <plugin-name>
经过上述步骤,我们已经新建了一个插件模板,比如我新建了一个:advisory_plugin.项目结构如下:
2. 配置插件
接下来我们把插件配置进EMQX里面.
首先需要clone下emqx-rel项目,这个是编译EMQX的入口.
git clone https://github.com/emqx/emqx-rel.git emqx-rel
cd emqx-rel && make
./_build/emqx/rel/emqx/bin/emqx console
确认没问题以后,我们开始配置插件.在配置插件之前,记得把代码提交到git服务器上,这里我用gitee做演示,因为国内速度比较快.
打开rebar.config文件,在
deps
节点找到合适的位置加入自己的插件地址:{ advisory_plugin, { git , "https://gitee.com/lagrangewang/advisory_plugin.git" , {branch, "master"} } }
在relx节点找到合适的位置,加入以下内容:
{advisory_plugin, load}
到此为止我们的插件就装好了.我们按照EMQX的官网文档,编译完成,启动EMQX,可以看到如下:
3. 配置参数
接下来进入比较重要的环节:自定义插件参数.我们在本案例里面演示了如何配置单个或者,多个URL地址.
首先打开插件目录下的etc目录,找到conf文件,加入我们自己的配置项:
# 单个配置项
advisory_plugin.destination = http://localhost:2500/ezlinker/data/in
# 多个配置项
advisory_plugin.server.1 = http://1:2500/ezlinker/data/in
advisory_plugin.server.2 = http://2:2500/ezlinker/data/in
这里需要注意的是,单个配置项一般为K-V键值对的形式.而多个项需要满足如下格式:
k.${name}
其中${name}是个占位符,可以自定义表示多个参数的序号,或者名字,建议用序号来表示.
4. 映射参数
接下来,最后一个环节,映射自定义参数:
打开priv目录下的schema文件,首先映射我们的单配置项:
%% advisory_plugin config
{mapping, "advisory_plugin.destination", "advisory_plugin.destination", [
{datatype, string}
]}.
其中:mapping表示参数映射,第二个参数表示etc下的conf文件中的名称,第三个参数表示配置文件的键,用来在程序中获取.
5. 转换参数
多项参数比较麻烦,还需要一个转换器,同样在schema文件中,定义一个转换器:
{translation,
"advisory_plugin.server",
fun(Conf) ->
Urls = cuttlefish_variable:filter_by_prefix("advisory_plugin.server", Conf),
[ Url || Url <- Urls]
end
}.
这段代码可以理解为:获取配置中advisory_plugin.server对应的值,返回一个列表,配置文件之间的关系如图所示:
6. 获取参数
- 单项参数获取
%%参数说明
%%?APP:插件模块
%%destination:mapping的第二个参数的Key
%%"http://127.0.0.1":如果获取失败的默认值
Url = application:get_env(?APP, destination, "http://127.0.0.1")
多项参数获取
Urls = application:get_env(?APP, server, "http://127.0.0.1"), lists:foreach(fun(U) -> {[_N,_K,_S],Url} = U, io:format("Url is : ~p~n", [Url]) end, Urls),
7.总结
本文主要讲了以下知识点:
创建插件
注册插件
编译测试
自定义开发
单项参数的配置和获取
多项参数的定义和获取
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!