将插件添加到go程序中

时间:2017-11-09 16:46:49

标签: go plugins

我需要为Go程序提供可插拔功能。 这个想法是第三方可以为给定路径添加功能,即

/alive映射到http://localhost:9876,或 /branding映射到http://localhost:9877,依此类推。

我首先尝试将其视为添加JSON配置文件,其中每个此类插件都有一个条目,例如:

{
  "Uri": "alive",
  "Address":"http://localhost:9876",
  "Handler":"github.com/user/repo/path/to/implementation"
},

这虽然公然显示Java思考 - 并且感觉完全不适合Go - Go中没有类加载器的概念,加载这意味着必须使用来自loader工具的golang个包。

有关如何以更Go - 特殊方式执行此操作的建议?最后,我只需要能够将URI映射到端口和实现。

1 个答案:

答案 0 :(得分:3)

编译时配置

如果您可以使用编译时配置,则不需要JSON(或任何其他)配置文件。

您的main软件包可以导入所有涉及的"插件",并将其处理程序映射到相应的路径。也没有必要创建多个服务器,但如果更符合您(或模块)的需求,您可以这样做。

运行时配置

运行时配置和插入新模块需要在运行时加载代码。这由plugin包支持,但目前仅在linux下。

为此,您可以使用JSON配置文件,在其中列出已编译的插件(已编译插件的路径)以及映射它们所需的路径。

main包中,您可以读取配置文件,并加载插件,这些插件应该公开一个变量或函数,它返回处理流量(请求)的处理程序。出于性能原因,这比插件自身启动http服务器更受欢迎,但两者都可以工作(插件返回处理程序供您注册,插件启动服务器)。

请注意,也不需要进行配置"静态",主应用程序也可以在运行时接收和加载新模块(例如,通过专用处理程序,可以接收(文件)路径到新模块和映射它的路径,也可能是二进制插件代码;但不要忘记安全!)。

请注意,虽然您可以在运行时加载插件,但是无法卸载"卸载"他们。加载插件后,它将保留在内存中,直到该应用程序存在。

单独的多应用程序

还有第三种解决方案,您的主应用程序将充当代理。在这里你可以开始额外的"模块"作为单独的应用程序,在特定端口上侦听localhost,主应用程序将充当代理,转发请求到其他独立应用程序侦听不同端口@localhost(甚至在其他主机上)。

标准库为您提供httputil.ReverseProxy这样做。

这不需要运行时代码加载,因为"模块"是单独的应用程序,可以单独启动。尽管如此,这为运行时配置提供了灵活性,此解决方案也适用于所有平台。此外,此设置支持在运行时删除模块,因为您可以轻松地取消映射/关闭独立模块的应用程序。

单独的应用程序也可以单独启动,或者从主应用程序启动,两种解决方案都可行。