浅谈 Golang 插件机制
我们知道类似 Java 等半编译半解释型语言编译生成的都是类似中间态的字节码,所以在 Java 里面我们想要实现程序工作的动态扩展,可以通过 Java 的字节码编辑技术([[动态代理#ASM]]/[[动态代理#CGLIB]]),并结合 JVM 的 [[字节码动态加载#^bc6dd8]] 实现动态修改和加载字节码。
但是 Golang 是编译型语言,编译后直接生成的是可执行文件,但是如果我们又需要在不发布版本的情况下实现程序功能的动态扩展,我们可以通过什么方式来实现呢?下面主要介绍 Golang 里面实现程序功能动态扩展的两种方式:Golang 原生插件和 go-plugin 插件。
Golang 原生插件
Golang 原生插件使用流程如下:

将代码编译成 .so 文件
package main
const Name = "PluginName"
func GetName() string {
return Name
}
将以上代码使用 go build -buildmode=plugin 命令即可编译成插件。
使用插件示例
func main() {
// 加载插件
open, err := plugin.Open("~/plg.so")
if err != nil {
panic(err)
}
// 查找标识符
lookup, err := open.Lookup("GetName")
if err != nil {
panic(err)
}
res := lookup.(func() string)()
fmt.Printf("%v", res)
}
原生插件的弱点
- 编译的 Go 版本必须完全一致 - 事实上这个插件都可以不是由同一个人编写,要求编译的 Go 版本一致显然有点要求太高了
- 双方依赖的公共第三方库版本必须完全一致
- GOPATH 也得保持一致 - 不过这一点可以在编译时候使用 trimpath 参数解决
- 插件加载之后无法卸载
go-plugin
鉴于 Golang 原生插件框架的问题,所以包括 Terraform、Grafana 等系统使用的是 go-plugin 这个框架。go-plugin 使用流程如下。

️ 使用的时候注意复用客户端,因为每次初始化实际上是启动了一个子进程,这样会消耗非常多的内存和 CPU 资源。
我们看 go-plugin 的使用流程,可以发现其实 go-plugin 是通过在应用内部启动一个服务端子进程,应用通过 rpc 的方式和服务端子进程进行交互来实现插件的动态加载。这样其实几乎可以作为一个编译型语言实现动态加载的通用方案,实际上不是对应用本身做了扩展,而是对应用依赖的接口做了相关的扩展。
go-plugin 的具体使用可以参考文章最后的链接。
参考
浅谈 Golang 插件机制的更多相关文章
- 浅谈ecmall插件机制
插件是独立于原系统的程序模块,目的是在不修改原程序的情况下对系统进行扩展,便于修改和管理.目前web开发中大多是使用钩子形式来定义插件, 比较典型的有 wordpress, drupal系统 ecma ...
- 浅谈Nutch插件机制(含开发实例)
plugin(插件)为nutch提供了一些功能强大的部件,举个例子,HtmlParser就是使用比较普遍的用来分析nutch抓取的html文件的插件. 为什么nutch要使用这样的plugin系统? ...
- 浅谈JVM线程调度机制及主要策略
在之前有说过线程,应该都知道,所谓线程就是进程中的一个子任务,一个进程有多个线程.今天的话主要就是谈一谈JVM线程调度机制.我们结合线程来说,当我们在做多线程的案例时,如一个经典案例,火车站卖票. * ...
- 浅谈java发射机制
目录 什么是反射 初探 初始化 类 构造函数 属性 方法 总结 思考 什么是反射 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意 ...
- 浅谈java反射机制
目录 什么是反射 初探 初始化 类 构造函数 属性 方法 总结 思考 什么是反射 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意 ...
- 浅谈android binder机制
binder机制 是谷歌优化在android上更适合终端的IPC(多进程通信方式),满足系统对通信方式,传输性能和安全性的要求. 特性: 1. 用驱动程序来推进进程间的通信.2. 通过共享内存来提高性 ...
- 浅谈Java回调机制
像许多网上介绍回调机制的文章一样,我这里也以一个现实的例子开头:假设你公司的总经理出差前需要你帮他办件事情,这件事情你需要花些时间去做,这时候总经理肯定不能守着你做完再出差吧,于是就他告诉你他的手机号 ...
- 浅谈java编译机制和运行机制
源文件和字节码的组成方式 源文件: 拓展名后跟java的文件即java的源文件. Java 源码编译由以下三个过程组成: 1.分析和输入到符号表 2.注解处理 3.语义分析和生成class文件 流程图 ...
- 浅谈利用同步机制解决Java中的线程安全问题
我们知道大多数程序都不会是单线程程序,单线程程序的功能非常有限,我们假设一下所有的程序都是单线程程序,那么会带来怎样的结果呢?假如淘宝是单线程程序,一直都只能一个一个用户去访问,你要在网上买东西还得等 ...
随机推荐
- 多校B层冲刺NOIP20211111模拟12
题面:PDFhttp://xn--gwt928b.accoders.com/pdf/10248/10248.pdfhttp://xn--gwt928b.accoders.com/pdf/10248/1 ...
- 转换流的原理和OutputStreamWriter介绍&代码实现
转换流的原理 OutputStreamWriter介绍&代码实现 package com.yang.Test.ReverseStream; import java.io.FileNotFoun ...
- Docker默认桥接网络是如何工作的
1. 启动一个Docker容器 一般来说,我们起一个容器比如一个简单的nginx服务会向这样 docker run -d --rm nginx:XXX OK容器起来了,但是并不能通过宿主机被外面的机器 ...
- Nginx 配置静态资源防盗链
# 什么是静态资源盗链: # 你服务器上的一张图片,127.0.0.1/images/a.png # 别人的html页面可以直接通过<img src="127.0.0.1/images ...
- 将Nginx配置成系统开机启动服务
# 如何将nginx配置成我们的系统服务 # 1.在/usr/lib/systemd/system目录下面配置nginx.service内容 # 如果想要详细了解制作的过程:https://blog. ...
- Changes in GreatSQL 8.0.25-16(2022-5-16)
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 目录 1.新增特性 1.1 新增仲裁节点(投票节点)角色 1.2 新增快速单主模式 1.3 新增MGR网络开销阈值 1.4 ...
- BZOJ1787/Luogu4281: [Ahoi2008]Meet 紧急集合
画画图可知,三点\(lca\)必有两相同,\(a,b,c\)距离为\(dis_a + dis_b + dis_c - dis_{lca(a,b)} - dis_{lca(b,c)} - dis_{lc ...
- java学习第七天注解.day19
注解 可以使用注解来修饰类中的成员信息 "注解,可以看作是对 一个 类/方法 的一个扩展的模版 元注解 注解:用来贴在类/方法/变量等之上的一个标记,第三方程序可以通过这个标记赋予一定功能 ...
- PHP代码审计——文件操作漏洞
梦想CMS(lmxcms)任意文件删除 1. 漏洞详情--CNVD-2020-59469 2. 漏洞描述称后台Ba***.cl***.php文件存在任意文件删除,查看cms源码,只有BackdbA ...
- VS Code 之KoroFileHeader插件
设置 在vscode左下角点击设置按钮,选择"设置",然后输入"fileheader", 文件头部注释:Fileheader:custom Made 函数注释: ...