我需要为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映射到端口和实现。
答案 0 :(得分:3)
如果您可以使用编译时配置,则不需要JSON(或任何其他)配置文件。
您的main
软件包可以导入所有涉及的"插件",并将其处理程序映射到相应的路径。也没有必要创建多个服务器,但如果更符合您(或模块)的需求,您可以这样做。
运行时配置和插入新模块需要在运行时加载代码。这由plugin
包支持,但目前仅在linux下。
为此,您可以使用JSON配置文件,在其中列出已编译的插件(已编译插件的路径)以及映射它们所需的路径。
在main
包中,您可以读取配置文件,并加载插件,这些插件应该公开一个变量或函数,它返回处理流量(请求)的处理程序。出于性能原因,这比插件自身启动http服务器更受欢迎,但两者都可以工作(插件返回处理程序供您注册,插件启动服务器)。
请注意,也不需要进行配置"静态",主应用程序也可以在运行时接收和加载新模块(例如,通过专用处理程序,可以接收(文件)路径到新模块和映射它的路径,也可能是二进制插件代码;但不要忘记安全!)。
请注意,虽然您可以在运行时加载插件,但是无法卸载"卸载"他们。加载插件后,它将保留在内存中,直到该应用程序存在。
还有第三种解决方案,您的主应用程序将充当代理。在这里你可以开始额外的"模块"作为单独的应用程序,在特定端口上侦听localhost,主应用程序将充当代理,转发请求到其他独立应用程序侦听不同端口@localhost(甚至在其他主机上)。
标准库为您提供httputil.ReverseProxy
这样做。
这不需要运行时代码加载,因为"模块"是单独的应用程序,可以单独启动。尽管如此,这为运行时配置提供了灵活性,此解决方案也适用于所有平台。此外,此设置支持在运行时删除模块,因为您可以轻松地取消映射/关闭独立模块的应用程序。
单独的应用程序也可以单独启动,或者从主应用程序启动,两种解决方案都可行。