官网安装教程
下载emqx broker安装包解压
移动到emqx的安装包下 启动开启命令
./bin/emqx start
如果开启成功的话会显示
EMQ X Broker v4.0.0 is started successfully!
查看localhost:18083会显示界面,默认账号是admin,默认密码是public,
默认是英文版本,中文版本去系统里设置一下就好了。
下载kuiper且安装(kuiper只能安装在linux系统下,不支持windows)
kuiper官网地址
kuiper官网的安装说明还是比较通俗易懂的。
移动到kuiper文件夹
./bin/server //启动kuiper
默认监听mqtt配置,端口就是主机的1883端口
如果开启了emqx broker就会连接到emqx broker
想改ip和端口的可以去kuiper文件夹下etc/mqtt_source.yaml的配置文件中修改
kuiper插件开发主要是针对source输入源和sink输出源
官网给了以mysql当sink输出源的插件kuiper以mysql的开发教程
现在需要开发mongodb的插件为示例
因为kuiper底层都是用Go语言开发的,所以我们开发需要安装Go环境且版本需要是go 1.13版本,低版本都会报错不匹配。
创建一个开发包文件夹
plugin_project // 文件夹目录名称
sources //源(source)插件源代码目录 输入源
mysource.go
sinks //目标(sink)插件源代码目录 输出源
mysink.go
functions //函数(function)插件源代码目录
myfunction.go
target //编译结果目录
go.mod //go module文件
go.mod是需要下载一些go的依赖包
最基本的go.mod
module samplePlugin
go 1.13
require (
github.com/emqx/kuiper v0.0.0-20200323140757-60d00241372b
)
那个v.0.0.0是版本号,我的是v.0.4.0,这个根据你们自己的版本定义。
以mongodb为sink输出源的开发插件mongodb.go代码如下
package main
import (
"fmt"
"github.com/emqx/kuiper/xstream/api"
"gopkg.in/mgo.v2"
)
type Person struct {
Name string
Phone string
}
type mongodbSink struct{
url string
database string
collection string
}
func (m *mongodbSink) Configure(props map[string]interface{}) error{
if i, ok := props["url"]; ok{
if i, ok := i.(string); ok{
m.url = i
}
}
if i, ok := props["database"]; ok{
if i, ok := i.(string); ok{
m.database = i
}
}
if i, ok := props["collection"]; ok{
if i, ok := i.(string); ok{
m.collection = i
}
}
return nil
}
func (m *mongodbSink) Open(ctx api.StreamContext) (err error) {
logger := ctx.GetLogger()
logger.Debug("Opening mongodb sink")
return
}
func (m *mongodbSink) Collect(ctx api.StreamContext, item interface{}) error {
logger := ctx.GetLogger()
session, err := mgo.Dial(m.url)
if err != nil {
panic(err)
}
// Optional. Switch the session to a monotonic behavior.
session.SetMode(mgo.Monotonic, true)
c := session.DB(m.database).C(m.collection)
defer session.Close()
if v, ok := item.([]byte); ok {
logger.Debugf("mongodb sink receive %s", item)
vi := string(v)
err = c.Insert(&Person{"boy1",vi})
if err != nil {
return err
}
} else {
logger.Debug("mongodb sink receive non byte data")
}
return nil
}
func (m *mongodbSink) Close(ctx api.StreamContext) error {
return nil
}
func mongodb_collection(url,database,collection string) {
session, err := mgo.Dial(url)
if err != nil {
panic(err)
}
// Optional. Switch the session to a monotonic behavior.
session.SetMode(mgo.Monotonic, true)
}
var Mongodb mongodbSink
git clone https://github.com/emqx/kuiper.git
本文主要讲本地编译插件,官网有docker编译我这不介绍了。
make
运行go mod edit -replace github.com/emqx/kuiper=$kuiperPath
使得 Kuiper 依赖指向本地 Kuiper
$kuiperPath是你git kuiper的源代码的文件夹目录
我的示例
go mod edit -replace github.com/emqx/kuiper=/home/hadoop/kuiper
编译插件mongodb.go到git kuiper的源代码文件夹下
go build --buildmode=plugin -o $kuiperPath/_build/$build/plugins/sinks/[email protected] ./sinks/mongodb.go
$build其实是源代码内自带的一个kuiper软件,后续需要在$build中启动kuiper
我的示例
go build --buildmode=plugin -o /home/hadoop/kuiper/_build/kuiper--linux-x86_64/plugins/sinks/[email protected] ./sinks/mongodb.go
路径红色部分就是$build,这个看各自文件夹下的名称,也可以自己修改
最后你可以在/home/hadoop/kuiper/_build/kuiper--linux-x86_64/plugins/sinks这个路径下看得到[email protected]文件。
[email protected]中v1.0.0是版本控制,编译时会执行高版本,比如[email protected]和[email protected]会执行v1.0.2的代码。
启动kuiper连接emqx
移动到一开始下的源代码里面/kuiper/_build/kuiper--linux-x86_64目录下
然后我们开启kuiper
./bin/server
创建流
./bin/cli create stream demo '(temperature float, humidity bigint) WITH (FORMAT="JSON", DATASOURCE="demo")'
查看流状态
./bin/cli show streams
创建流规则
./bin/cli create rule ruleDemo -f myRule
ruleDemo是规则名称
myRule是规则文件
规则文件代码
{
"id": "ruleDemo",
"sql": "SELECT * from demo",
"actions": [
{
"log": {},
"mongodb":{
"url": "localhost:27017",
"database": "test",
"collection": "test"
}
}
]
}
id一定要跟规则名称相同,或则不要id
创建好流规则需要查看流规则是否正常
./bin/cli show rules
这样才是正常的。我的id时fanrule
失败的会报错。
然后我们打开mqttbox连接emqx端口创建topic
topic一定要以流名称相同不然接收不到数据,然后要以定义流时创建的
'(temperature float, humidity bigint) WITH (FORMAT="JSON", DATASOURCE="demo")'
这个为基础的格式发数据
最后就可以到mongodb查看到数据了
1.kuiper是以go语言开发的,环境一定要以go 1.13为准
2.go语言的特性,没使用过的变量编译会报错
3.以sink插件开发为例,插件开发主要是要重写这四个方法
Open(ctx api.StreamContext) (err error){}
Configure(props map[string]interface{}){}
Collect(ctx api.StreamContext, item interface{}) error{}
Close(ctx api.StreamContext) error{}
主程序启动会调用这四个方法,item是接收到的数据
里面逻辑可以自己添加修改
4.上述的item是接口数据,源码只提供[ ]byte类型接口数据,不能进行接口数据强转,需要加一个变量代替转为string类型;
例如:value := string(item.([ ]byte))
5.流规则定义时,mongodb选项需要小写
6.topic名称和流的名称需要一致,topic发布的数据需要与定义流时语句规则相同。