zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    MINIX文件系统
    Cmd Markdown 语法
    asp.net mvc 4 json大数据异常 提示JSON字符长度超出限制的异常[转载]
    echart 拖拽
    搭建django开发环境
    Django 1.11.7+django_pyodbc_azure-1.11.0.0+pyodbc 连接mssql 数据库
    二、PyCharm 创建Django 第一个项目
    一、Django 安装
    python 连接各类主流数据库简单示例【转载】
    Python 3.6 连接mssql数据库(pymssql 方式)
  • 原文地址:https://www.cnblogs.com/rongfengliang/p/14200836.html
Copyright © 2011-2022 走看看