go plugins 试用&&一些实践

go plugins 提供了go 的 plugin 开发模式,目前已经有一些框架的扩展就是基于此进行的(skipper&&krakend。。。。)
以下是一个简单的实践

项目准备

  • 基本功能
    开发一个基于go plugin 的id 生成服务(依赖shortid,当然可以调整其他的版本)
  • go mod
 
module demoapp
go 1.15
require github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect
  • plugin 代码
    一个简单的struct 同时引用了shortid进行id 生成
 
package main
import (
    "log"
    "github.com/teris-io/shortid"
)
// MyID myid
type MyID struct {
    *shortid.Shortid
}
// 此处为了方便扩展,返回了一个interface 类型
// New create myid instance
func New(workerid uint8, seed uint64) interface{} {
    shortid, err := shortid.New(workerid, shortid.DefaultABC, seed)
    if err != nil {
        log.Println("some wrong", err)
    }
    return MyID{
        Shortid: shortid,
    }
}
// GenerateID generateID
func (myid MyID) GenerateID() string {
    id, err := myid.Generate()
    if err != nil {
        log.Println("generate id error")
    }
    return id
}
  • 构建plugin
go build -buildmode=plugin -o demoapp.so app.go
  • 使用plugin
package main
import (
    "log"
    "plugin"
)
// 基于接口的定义,方便类型转换
// MyGenerateID myGenerateID
type MyGenerateID interface {
    GenerateID() string
}
var myGenerateID MyGenerateID
func init() {
    p, err := plugin.Open("./demoapp.so")
    if err != nil {
        panic(err)
    }
    // init plugin for shortid
    s, err := p.Lookup("New")
    if err != nil {
        panic("init plugin error")
    }
    // 使用interface 到类型的转换,方便使用
    myid := s.(func(workerid uint8, seed uint64) interface{})(2, 2000)
    myGenerateID = myid.(MyGenerateID)
}
func main() {
    // 因为进行了接口的类型转换,我们就可以基于方法的模式直接使用暴露的方法了
    for i := 0; i < 10; i++ {
        log.Println("generate id:", myGenerateID.GenerateID())
    }
}
  • 效果

 

 

实践说明

plugin 是插件化开发的一种模式,所以我们应该基于契约的模式进行接口定义,这样可以实现灵活的扩展,同时也
编译插件的使用,比如以上代码中,定义了MyGenerateID 接口(包含了GenerateID 方法)这样我们就可以方便的
使用插件的契约进行开发功能了

说明

go plugin 不太好的地方是go 版本的一致性(构建plugin 的与运行的版本需要一致),都会每次系统依赖golang 版本的
变动都需要重新编译(做好版本以及ci/cd 很重要),而且当前还不支持plugin的卸载。。。如果真的需要跨平台的plugin
支持hashicorp/go-plugin 是一个不错的选择

参考资料

https://golang.org/pkg/plugin/
https://github.com/hashicorp/go-plugin
https://github.com/rongfengliang/go-plugin-learning
https://github.com/vladimirvivien/go-plugin-example
https://github.com/teris-io/shortid
https://github.com/devopsfaith/krakend/blob/master/plugin/register.go

posted on   荣锋亮  阅读(707)  评论(0编辑  收藏  举报

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2018-12-28 Gravitational Teleport docker-compose简单运行
2018-12-28 Gravitational Teleport简单使用
2018-12-28 Gravitational Teleport 开源的通过ssh && kubernetes api 管理linux 服务器集群的网关
2013-12-28 使用js 文件参数 以及IHttpModule实现服务验证asp.net 版的初步实现
2013-12-28 获取js 文件传递的参数并使用json2进行json数据转换

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示