前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >go: 官方插件(plugin)初探

go: 官方插件(plugin)初探

作者头像
超级大猪
发布2024-01-17 09:30:34
960
发布2024-01-17 09:30:34
举报
文章被收录于专栏:大猪的笔记大猪的笔记

写一个最简单的插件

在实践中学习,动动手指

ch.go

代码语言:javascript
复制
package main

import "common/greeterinterface"

type ChineseGreeter struct {
}

func (g *ChineseGreeter) Greet() string {
    return "世界你好"
}

// 这个就是可导出的函数,插件在lookup这个函数
func NewGreeter() greeterinterface.Greeter {
    return new(ChineseGreeter)
}

编译插件

代码语言:javascript
复制
go build -buildmode=plugin -o ./ch.so ch.go

在主程序中载入并运行插件

代码语言:javascript
复制
package plug

import (
    "plugin"
    "common/greeterinterface" // 主程序中,仍然引用了这个接口,它是对插件的桥梁
    "log"
)


func Load() (err error) {
    // 打开插件
    plug, err := plugin.Open("./ch.so")
    if err!=nil{
        log.Fatalf("load plugin failed:%v", err)
    }

    // 寻找对象
    greeterObj, err := plug.Lookup("NewGreeter")
    if err!=nil{
        log.Fatalf("look up failed :%v", err)
    }

    // 转换对象的格式
    creator := greeterObj.(func() greeterinterface.Greeter)
    
    greeter := creator() // 此时调用的是插件中的函数
    greeter.Greet() // 创建的结构和直接写代码new的无区别

    return nil
}

几点建议

太棒了,现在你已经获得了写插件的新技能。这里有几点实现插件的不成熟建议:

  1. 插件需要定义在main包。按通常的方式编写函数和结构体即可。
  2. 定义接口在第三方的module中,插件实现这个接口。比如下面的common/greeterinterface
  3. 在插件中定义构造函数,如下面的NewGreeter
  4. 在主程序中,引用插件中的构造函数即可创建对象。

有哪些坑

  1. go的插件只支持open,不支持close。这样会有内存泄露。
  2. go的插件,相同的module name只支持加载一次。
  3. 一定要使用go.mod进行项目管理,插件和主程序的所有相同的依赖版本要相同,建议用主程序的go.mod内容同步到插件的go.mod。否则在open的时候将直接报错。
  4. 测试发现,调用无业务的Greet函数,原生 go 比插件性能快5倍,但只有纳秒级的区别。原生go执行1000万次函数耗时3ms,插件耗时 16ms。 而执行带业务的函数,性能差距则并不明显

为什么要使用插件

  1. 隐藏业务的代码实现。有时候多部门合作时,需要隐藏业务的实现。
    1. 平台方提供平台主程序和接口协议,具体业务由不同的部门实现。类似Linux的版本是开源的,但ko的实现则不一定。
    2. 插件和主程序共同引用的第三方包版本必须完全相同,这里为协作带来了不小的麻烦
  2. 分离业务实现,避免频繁的编译主程序框架。显然,将业务以文件的形式分离提供了更大的灵活性,但这种灵活性在实践中有这几个问题:
    1. 插件的体积很大。因为go的特点,每个插件so占用的内存和磁盘在20M以上。
    2. 版本管理不方便。so的版本以文件方式会有管理成本。
    3. 主程序仍然需要重启加载插件。因为插件只能Load而不能Close,且不能重复加载,目前没有很好的动态加载/卸载插件的方法

总体来说,plugin 包还有相当大的提升空间,但这似乎并不是go团队的关注重点。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-08-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写一个最简单的插件
    • ch.go
    • 在主程序中载入并运行插件
    • 几点建议
    • 有哪些坑
    • 为什么要使用插件
    相关产品与服务
    项目管理
    CODING 项目管理(CODING Project Management,CODING-PM)工具包含迭代管理、需求管理、任务管理、缺陷管理、文件/wiki 等功能,适用于研发团队进行项目管理或敏捷开发实践。结合敏捷研发理念,帮助您对产品进行迭代规划,让每个迭代中的需求、任务、缺陷无障碍沟通流转, 让项目开发过程风险可控,达到可持续性快速迭代。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档