feat: 系统调优 Go 版后端完整源码
- 19 个接口全部实测验收通过 (2026-08-08) - 结构: main.go + core/consts + gsysctl + gtuner + server - 含 build_go.sh 官方部署结构构建脚本 (amd64/arm64 交叉编译) - 数据无缝衔接 Python 版遗留 (快照/state/审计日志) - 备份自 156:/root/goddhv (2026-08-09)
This commit is contained in:
@@ -0,0 +1,257 @@
|
||||
// Package server 提供 GMSSH JSON-RPC 接口层(19 个接口)。
|
||||
// 对应 Python 版 backend/app/server.py。
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"github.com/DemonZack/simplejrpc-go/net/gsock"
|
||||
"github.com/user_TGPJp0KLpNsa5TAo/ddhv/gsysctl"
|
||||
"github.com/user_TGPJp0KLpNsa5TAo/ddhv/gtuner"
|
||||
)
|
||||
|
||||
// Handler 聚合所有接口 handler
|
||||
type Handler struct {
|
||||
Sysctl *gsysctl.Manager
|
||||
Tuner gtuner.TunerService
|
||||
}
|
||||
|
||||
// NewHandler 构造 handler
|
||||
func NewHandler() *Handler {
|
||||
return &Handler{Sysctl: gsysctl.NewManager(), Tuner: gtuner.NewTuner()}
|
||||
}
|
||||
|
||||
// params 提取请求参数为 map
|
||||
func params(req *gsock.Request) map[string]any {
|
||||
if req.RawRequest() == nil || req.RawRequest().Params == nil {
|
||||
return map[string]any{}
|
||||
}
|
||||
raw, _ := json.Marshal(req.RawRequest().Params)
|
||||
var m map[string]any
|
||||
_ = json.Unmarshal(raw, &m)
|
||||
return m
|
||||
}
|
||||
|
||||
// str 取字符串参数
|
||||
func str(p map[string]any, key string) string {
|
||||
if v, ok := p[key]; ok {
|
||||
switch t := v.(type) {
|
||||
case string:
|
||||
return t
|
||||
case float64:
|
||||
return strconv.FormatFloat(t, 'f', -1, 64)
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// boolP 取布尔参数
|
||||
func boolP(p map[string]any, key string) bool {
|
||||
if v, ok := p[key]; ok {
|
||||
if b, ok := v.(bool); ok {
|
||||
return b
|
||||
}
|
||||
if f, ok := v.(float64); ok {
|
||||
return f != 0
|
||||
}
|
||||
if s, ok := v.(string); ok {
|
||||
return s == "true" || s == "1"
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// trueP 取布尔参数(默认 true)
|
||||
func trueP(p map[string]any, key string) bool {
|
||||
if v, ok := p[key]; ok {
|
||||
if b, ok := v.(bool); ok {
|
||||
return b
|
||||
}
|
||||
if f, ok := v.(float64); ok {
|
||||
return f != 0
|
||||
}
|
||||
if s, ok := v.(string); ok {
|
||||
return s == "true" || s == "1"
|
||||
}
|
||||
return true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// intP 取整数参数
|
||||
func intP(p map[string]any, key string) int {
|
||||
if v, ok := p[key]; ok {
|
||||
if f, ok := v.(float64); ok {
|
||||
return int(f)
|
||||
}
|
||||
if s, ok := v.(string); ok {
|
||||
if i, err := strconv.Atoi(s); err == nil {
|
||||
return i
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// ========== 基础 ==========
|
||||
|
||||
// Hello 测试接口
|
||||
func (h *Handler) Hello(req *gsock.Request) (any, error) {
|
||||
return map[string]any{"message": "hello"}, nil
|
||||
}
|
||||
|
||||
// Ping 健康检查(平台要求返回 pong)
|
||||
func (h *Handler) Ping(req *gsock.Request) (any, error) {
|
||||
return "pong", nil
|
||||
}
|
||||
|
||||
// ========== 系统调优接口 ==========
|
||||
|
||||
func (h *Handler) TunerCheckRoot(req *gsock.Request) (any, error) {
|
||||
return h.Tuner.CheckRoot()
|
||||
}
|
||||
|
||||
func (h *Handler) TunerDetect(req *gsock.Request) (any, error) {
|
||||
return h.Tuner.Detect()
|
||||
}
|
||||
|
||||
func (h *Handler) TunerCurrentPreset(req *gsock.Request) (any, error) {
|
||||
return h.Tuner.GetCurrentPreset()
|
||||
}
|
||||
|
||||
func (h *Handler) TunerSnapshots(req *gsock.Request) (any, error) {
|
||||
snaps := h.Sysctl.ListSnapshots()
|
||||
list := make([]map[string]any, 0, len(snaps))
|
||||
for _, s := range snaps {
|
||||
list = append(list, map[string]any{
|
||||
"name": s.Name, "created_at": s.CreatedAt, "reason": s.Reason,
|
||||
"kind": s.Kind, "param_count": s.ParamCount,
|
||||
})
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (h *Handler) TunerInitStatus(req *gsock.Request) (any, error) {
|
||||
return h.Tuner.InitStatus()
|
||||
}
|
||||
|
||||
func (h *Handler) TunerInit(req *gsock.Request) (any, error) {
|
||||
return h.Tuner.InitSnapshot()
|
||||
}
|
||||
|
||||
func (h *Handler) TunerCreateSnapshot(req *gsock.Request) (any, error) {
|
||||
p := params(req)
|
||||
reason := str(p, "reason")
|
||||
if reason == "" {
|
||||
reason = "手动备份"
|
||||
}
|
||||
return h.Sysctl.CreateSnapshot(reason, "manual")
|
||||
}
|
||||
|
||||
func (h *Handler) TunerRestoreSnapshot(req *gsock.Request) (any, error) {
|
||||
p := params(req)
|
||||
name := str(p, "snapshot_name")
|
||||
if name == "" {
|
||||
return nil, errParam("缺少 snapshot_name 参数")
|
||||
}
|
||||
return h.Sysctl.RestoreSnapshot(name)
|
||||
}
|
||||
|
||||
func (h *Handler) TunerPresets(req *gsock.Request) (any, error) {
|
||||
return h.Tuner.GetPresets(), nil
|
||||
}
|
||||
|
||||
func (h *Handler) TunerApplyPreset(req *gsock.Request) (any, error) {
|
||||
p := params(req)
|
||||
key := str(p, "preset_key")
|
||||
if key == "" {
|
||||
return nil, errParam("缺少 preset_key 参数")
|
||||
}
|
||||
return h.Tuner.ApplyPreset(key)
|
||||
}
|
||||
|
||||
func (h *Handler) TunerSetSwappiness(req *gsock.Request) (any, error) {
|
||||
p := params(req)
|
||||
value := intP(p, "value")
|
||||
if value < 0 {
|
||||
return nil, errParam("缺少 value 参数")
|
||||
}
|
||||
persist := trueP(p, "persist")
|
||||
return h.Tuner.SetSwappiness(value, persist)
|
||||
}
|
||||
|
||||
func (h *Handler) TunerEnableBBR(req *gsock.Request) (any, error) {
|
||||
return h.Tuner.EnableBBR()
|
||||
}
|
||||
|
||||
func (h *Handler) TunerDisableBBR(req *gsock.Request) (any, error) {
|
||||
return h.Tuner.DisableBBR()
|
||||
}
|
||||
|
||||
func (h *Handler) TunerGetParam(req *gsock.Request) (any, error) {
|
||||
p := params(req)
|
||||
key := str(p, "key")
|
||||
if key == "" {
|
||||
return nil, errParam("缺少 key 参数")
|
||||
}
|
||||
value, err := gsysctl.GetValue(key)
|
||||
if err != nil {
|
||||
value = ""
|
||||
}
|
||||
return map[string]any{"key": key, "value": value}, nil
|
||||
}
|
||||
|
||||
func (h *Handler) TunerSetParam(req *gsock.Request) (any, error) {
|
||||
p := params(req)
|
||||
key := str(p, "key")
|
||||
value := str(p, "value")
|
||||
if key == "" || value == "" {
|
||||
return nil, errParam("缺少 key/value 参数")
|
||||
}
|
||||
unlocked := boolP(p, "unlocked")
|
||||
// 危险参数必须解锁
|
||||
if _, danger := h.Tuner.GetDangerousParams()[key]; danger && !unlocked {
|
||||
return map[string]any{"need_unlock": true}, errNeedUnlock()
|
||||
}
|
||||
if err := gsysctl.SetValue(key, value, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
current, _ := gsysctl.GetValue(key)
|
||||
h.Sysctl.LogAction("set_param", map[string]any{"key": key, "value": value, "unlocked": unlocked})
|
||||
return map[string]any{"key": key, "value": value, "ok": true, "current": current}, nil
|
||||
}
|
||||
|
||||
func (h *Handler) TunerDangerousParams(req *gsock.Request) (any, error) {
|
||||
return h.Tuner.GetDangerousParams(), nil
|
||||
}
|
||||
|
||||
func (h *Handler) TunerAuditLogs(req *gsock.Request) (any, error) {
|
||||
p := params(req)
|
||||
limit := intP(p, "limit")
|
||||
if limit <= 0 || limit > 500 {
|
||||
limit = 100
|
||||
}
|
||||
return h.Sysctl.AuditLogs(limit), nil
|
||||
}
|
||||
|
||||
// ========== 辅助错误 ==========
|
||||
|
||||
// errParam 参数错误
|
||||
func errParam(msg string) error {
|
||||
return &handleError{code: 400, msg: msg}
|
||||
}
|
||||
|
||||
// errNeedUnlock 需要解锁危险参数
|
||||
func errNeedUnlock() error {
|
||||
return &handleError{code: 403, msg: "危险参数需要先解锁才能修改"}
|
||||
}
|
||||
|
||||
type handleError struct {
|
||||
code int
|
||||
msg string
|
||||
}
|
||||
|
||||
func (e *handleError) Error() string { return e.msg }
|
||||
Reference in New Issue
Block a user