首页 > 解决方案 > 如何强制 go 子进程加载插件?

问题描述

我想编写一个小型 Go 程序来监视另一个 Go 程序,报告有关它的定期遥测。但是,我想在不需要被监控程序包含监控代码或显式加载监控代码的情况下执行此操作。

例如,给定以下惊人的服务器程序:

服务器.go:

package main

import (
    "fmt"
    "time"
)

func main() {
    for {
        fmt.Println("ping")
        time.Sleep(2 * time.Second)
    }
}

以及以下很棒的监控代码,构建为插件:

监视器.go:

package main

import (
    "fmt"
    "time"
)

func init() {
    go func() {
        for {
            fmt.Println("doing monitoring stuff...")
            time.Sleep(1 * time.Second)
        }
    }()
}

我想通过exec调用或其他方式启动服务器二进制文件,强制服务器进程monitor.so作为插件加载(它运行监视器的init()功能),之后服务器继续做它通常会做的事情,就好像什么都没发生一样。

最终结果将是它server仍然在做它的常规 ping 操作,但是当通过我的小程序启动时,还有一个正在运行的 goroutine 进行监控。当从源代码构建它时,服务器根本不需要知道监视器(即我不需要重建服务器二进制文件来添加这个功能)。

我的问题是:

  1. 我将如何在 Go 中执行此操作(这样我至少可以在调试环境中运行它,即使它有点不稳定)?

  2. 我将如何在 Go 中安全地执行此操作以便我可以在生产环境中运行它而无需启动所有核武器)?

标签: goplugins

解决方案


默认情况下,已构建的 Go 应用程序不支持加载“预定义”或其他插件。你必须改变应用程序,你必须让它搜索或期望插件被加载。

如果 go 工具会生成一个查找“default.so”插件或命令行标志的二进制文件,那么这样的事情很容易实现-autoload=pluginname,但事实并非如此。

大多数库通过要求应用程序导入它们来解决这个问题,这会启动他们想要的任何监控过程。这对大多数用途都很好。


推荐阅读