- 19 个接口全部实测验收通过 (2026-08-08) - 结构: main.go + core/consts + gsysctl + gtuner + server - 含 build_go.sh 官方部署结构构建脚本 (amd64/arm64 交叉编译) - 数据无缝衔接 Python 版遗留 (快照/state/审计日志) - 备份自 156:/root/goddhv (2026-08-09)
110 lines
3.5 KiB
Go
110 lines
3.5 KiB
Go
// 主入口: GMSSH「系统调优」Go 版后端服务。
|
|
// 基于官方 simplejrpc-go SDK, JSON-RPC 2.0 over Unix Socket。
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
rpc "github.com/DemonZack/simplejrpc-go"
|
|
"github.com/DemonZack/simplejrpc-go/core"
|
|
"github.com/DemonZack/simplejrpc-go/core/config"
|
|
"github.com/DemonZack/simplejrpc-go/net/gsock"
|
|
"github.com/DemonZack/simplejrpc-go/os/gpath"
|
|
"github.com/user_TGPJp0KLpNsa5TAo/ddhv/core/consts"
|
|
"github.com/user_TGPJp0KLpNsa5TAo/ddhv/server"
|
|
)
|
|
|
|
// env 运行环境(test/prod),可通过环境变量 GMSSH_ENV 覆盖
|
|
func startupEnv() string {
|
|
if e := os.Getenv("GMSSH_ENV"); e == "prod" || e == "test" {
|
|
return e
|
|
}
|
|
// 平台通常以 prod 运行正式版
|
|
return "prod"
|
|
}
|
|
|
|
func main() {
|
|
// 确保数据目录存在
|
|
consts.EnsureDirs()
|
|
|
|
var socketPath string
|
|
|
|
// 1. 优先支持环境变量显式指定(本地测试用)
|
|
if env := os.Getenv("APP_SOCKET"); env != "" {
|
|
socketPath = env
|
|
} else {
|
|
// 2. 尝试按官方 SDK 规范从 config.json 读取 socket
|
|
func() {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
log.Printf("[*] config.json 读取失败(忽略): %v", r)
|
|
}
|
|
}()
|
|
env := startupEnv()
|
|
// 设置配置基础路径: 优先 main 所在目录(与 config.json 同目录), 兜底 consts
|
|
binDir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
|
if err == nil {
|
|
gpath.GmCfgPath = binDir
|
|
} else {
|
|
gpath.GmCfgPath = consts.APP_BIN_PATH
|
|
}
|
|
if os.Getenv("CONFIG_PATH") != "" {
|
|
gpath.GmCfgPath = ""
|
|
}
|
|
core.InitContainer(config.WithConfigEnvFormatterOptionFunc(env))
|
|
val, err := core.Container.CfgFmt().GetValue("jsonrpc.sockets").String()
|
|
if err == nil && val != "" {
|
|
socketPath = val
|
|
// 若为相对路径, 从 app/bin 定位到部署根 tmp (bin -> ../.. -> /tmp)
|
|
if !filepath.IsAbs(socketPath) {
|
|
socketPath = filepath.Join(binDir, "..", "..", "tmp", filepath.Base(socketPath))
|
|
}
|
|
}
|
|
}()
|
|
|
|
// 3. 兜底用 consts 绝对路径
|
|
if socketPath == "" {
|
|
socketPath = consts.APP_SOCKET_FILE_PATH
|
|
}
|
|
}
|
|
|
|
fmt.Printf("Starting GMSSH system tuner backend, socket=%s\n", socketPath)
|
|
if err := ds0(socketPath); err != nil {
|
|
log.Fatalf("server error: %v", err)
|
|
}
|
|
}
|
|
|
|
// ds0 创建并启动 RPC 服务
|
|
func ds0(socketPath string) error {
|
|
ds := rpc.NewDefaultServer(
|
|
gsock.WithJsonRpcSimpleServiceHandler(gsock.NewJsonRpcSimpleServiceHandler()),
|
|
gsock.WithJsonRpcSimpleServiceMiddlewares(),
|
|
)
|
|
|
|
h := server.NewHandler()
|
|
ds.RegisterHandle("hello", h.Hello)
|
|
ds.RegisterHandle("ping", h.Ping)
|
|
ds.RegisterHandle("tuner_check_root", h.TunerCheckRoot)
|
|
ds.RegisterHandle("tuner_detect", h.TunerDetect)
|
|
ds.RegisterHandle("tuner_current_preset", h.TunerCurrentPreset)
|
|
ds.RegisterHandle("tuner_snapshots", h.TunerSnapshots)
|
|
ds.RegisterHandle("tuner_init_status", h.TunerInitStatus)
|
|
ds.RegisterHandle("tuner_init", h.TunerInit)
|
|
ds.RegisterHandle("tuner_create_snapshot", h.TunerCreateSnapshot)
|
|
ds.RegisterHandle("tuner_restore_snapshot", h.TunerRestoreSnapshot)
|
|
ds.RegisterHandle("tuner_presets", h.TunerPresets)
|
|
ds.RegisterHandle("tuner_apply_preset", h.TunerApplyPreset)
|
|
ds.RegisterHandle("tuner_set_swappiness", h.TunerSetSwappiness)
|
|
ds.RegisterHandle("tuner_enable_bbr", h.TunerEnableBBR)
|
|
ds.RegisterHandle("tuner_disable_bbr", h.TunerDisableBBR)
|
|
ds.RegisterHandle("tuner_get_param", h.TunerGetParam)
|
|
ds.RegisterHandle("tuner_set_param", h.TunerSetParam)
|
|
ds.RegisterHandle("tuner_dangerous_params", h.TunerDangerousParams)
|
|
ds.RegisterHandle("tuner_audit_logs", h.TunerAuditLogs)
|
|
|
|
return ds.StartServer(socketPath)
|
|
}
|