优化配置重载程序

This commit is contained in:
刘祥超
2022-11-25 10:50:57 +08:00
parent e82f207935
commit a64047a934
4 changed files with 138 additions and 29 deletions

View File

@@ -10,6 +10,7 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeNode/internal/caches" "github.com/TeaOSLab/EdgeNode/internal/caches"
"github.com/TeaOSLab/EdgeNode/internal/configs" "github.com/TeaOSLab/EdgeNode/internal/configs"
"github.com/TeaOSLab/EdgeNode/internal/conns" "github.com/TeaOSLab/EdgeNode/internal/conns"
@@ -25,6 +26,7 @@ import (
"github.com/TeaOSLab/EdgeNode/internal/trackers" "github.com/TeaOSLab/EdgeNode/internal/trackers"
"github.com/TeaOSLab/EdgeNode/internal/utils" "github.com/TeaOSLab/EdgeNode/internal/utils"
_ "github.com/TeaOSLab/EdgeNode/internal/utils/clock" // 触发时钟更新 _ "github.com/TeaOSLab/EdgeNode/internal/utils/clock" // 触发时钟更新
"github.com/TeaOSLab/EdgeNode/internal/utils/jsonutils"
"github.com/TeaOSLab/EdgeNode/internal/waf" "github.com/TeaOSLab/EdgeNode/internal/waf"
"github.com/andybalholm/brotli" "github.com/andybalholm/brotli"
"github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/Tea"
@@ -59,9 +61,13 @@ type Node struct {
sock *gosock.Sock sock *gosock.Sock
locker sync.Mutex locker sync.Mutex
maxCPU int32 oldMaxCPU int32
maxThreads int oldMaxThreads int
timezone string oldTimezone string
oldHTTPCachePolicies []*serverconfigs.HTTPCachePolicy
oldHTTPFirewallPolicies []*firewallconfigs.HTTPFirewallPolicy
oldFirewallActions []*firewallconfigs.FirewallActionConfig
oldMetricItems []*serverconfigs.MetricItemConfig
updatingServerMap map[int64]*serverconfigs.ServerConfig updatingServerMap map[int64]*serverconfigs.ServerConfig
@@ -74,8 +80,8 @@ type Node struct {
func NewNode() *Node { func NewNode() *Node {
return &Node{ return &Node{
sock: gosock.NewTmpSock(teaconst.ProcessName), sock: gosock.NewTmpSock(teaconst.ProcessName),
maxThreads: -1, oldMaxThreads: -1,
maxCPU: -1, oldMaxCPU: -1,
updatingServerMap: map[int64]*serverconfigs.ServerConfig{}, updatingServerMap: map[int64]*serverconfigs.ServerConfig{},
} }
} }
@@ -195,7 +201,7 @@ func (this *Node) Start() {
} }
} }
sharedNodeConfig = nodeConfig sharedNodeConfig = nodeConfig
this.onReload(nodeConfig) this.onReload(nodeConfig, true)
// 发送事件 // 发送事件
events.Notify(events.EventLoaded) events.Notify(events.EventLoaded)
@@ -601,7 +607,7 @@ func (this *Node) syncConfig(taskVersion int64) error {
remotelogs.Println("NODE", "loading config ...") remotelogs.Println("NODE", "loading config ...")
} }
this.onReload(nodeConfig) this.onReload(nodeConfig, true)
// 发送事件 // 发送事件
events.Notify(events.EventReload) events.Notify(events.EventReload)
@@ -977,15 +983,16 @@ func (this *Node) listenSock() error {
} }
// 重载配置调用 // 重载配置调用
func (this *Node) onReload(config *nodeconfigs.NodeConfig) { func (this *Node) onReload(config *nodeconfigs.NodeConfig, reloadAll bool) {
nodeconfigs.ResetNodeConfig(config) nodeconfigs.ResetNodeConfig(config)
sharedNodeConfig = config sharedNodeConfig = config
// 缓存策略 // 不需要每次都全部重新加载
caches.SharedManager.MaxDiskCapacity = config.MaxCacheDiskCapacity if !reloadAll {
caches.SharedManager.MaxMemoryCapacity = config.MaxCacheMemoryCapacity return
caches.SharedManager.MainDiskDir = config.CacheDiskDir }
// 缓存策略
var subDirs = config.CacheDiskSubDirs var subDirs = config.CacheDiskSubDirs
for _, subDir := range subDirs { for _, subDir := range subDirs {
subDir.Path = filepath.Clean(subDir.Path) subDir.Path = filepath.Clean(subDir.Path)
@@ -995,23 +1002,75 @@ func (this *Node) onReload(config *nodeconfigs.NodeConfig) {
return subDirs[i].Path < subDirs[j].Path return subDirs[i].Path < subDirs[j].Path
}) })
} }
var cachePoliciesChanged = !jsonutils.Equal(caches.SharedManager.MaxDiskCapacity, config.MaxCacheDiskCapacity) ||
!jsonutils.Equal(caches.SharedManager.MaxMemoryCapacity, config.MaxCacheMemoryCapacity) ||
!jsonutils.Equal(caches.SharedManager.MainDiskDir, config.CacheDiskDir) ||
!jsonutils.Equal(caches.SharedManager.SubDiskDirs, subDirs) ||
!jsonutils.Equal(this.oldHTTPCachePolicies, config.HTTPCachePolicies)
caches.SharedManager.MaxDiskCapacity = config.MaxCacheDiskCapacity
caches.SharedManager.MaxMemoryCapacity = config.MaxCacheMemoryCapacity
caches.SharedManager.MainDiskDir = config.CacheDiskDir
caches.SharedManager.SubDiskDirs = subDirs caches.SharedManager.SubDiskDirs = subDirs
if len(config.HTTPCachePolicies) > 0 { if cachePoliciesChanged {
caches.SharedManager.UpdatePolicies(config.HTTPCachePolicies) // copy
} else { this.oldHTTPCachePolicies = []*serverconfigs.HTTPCachePolicy{}
caches.SharedManager.UpdatePolicies([]*serverconfigs.HTTPCachePolicy{}) err := jsonutils.Copy(&this.oldHTTPCachePolicies, config.HTTPCachePolicies)
if err != nil {
remotelogs.Error("NODE", "onReload: copy HTTPCachePolicies failed: "+err.Error())
}
// update
if len(config.HTTPCachePolicies) > 0 {
caches.SharedManager.UpdatePolicies(config.HTTPCachePolicies)
} else {
caches.SharedManager.UpdatePolicies([]*serverconfigs.HTTPCachePolicy{})
}
} }
// WAF策略 // WAF策略
waf.SharedWAFManager.UpdatePolicies(config.FindAllFirewallPolicies()) var allFirewallPolicies = config.FindAllFirewallPolicies()
iplibrary.SharedActionManager.UpdateActions(config.FirewallActions) if !jsonutils.Equal(allFirewallPolicies, this.oldHTTPFirewallPolicies) {
// copy
this.oldHTTPFirewallPolicies = []*firewallconfigs.HTTPFirewallPolicy{}
err := jsonutils.Copy(&this.oldHTTPFirewallPolicies, allFirewallPolicies)
if err != nil {
remotelogs.Error("NODE", "onReload: copy HTTPFirewallPolicies failed: "+err.Error())
}
// update
waf.SharedWAFManager.UpdatePolicies(allFirewallPolicies)
}
if !jsonutils.Equal(config.FirewallActions, this.oldFirewallActions) {
// copy
this.oldFirewallActions = []*firewallconfigs.FirewallActionConfig{}
err := jsonutils.Copy(&this.oldFirewallActions, config.FirewallActions)
if err != nil {
remotelogs.Error("NODE", "onReload: copy FirewallActionConfigs failed: "+err.Error())
}
// update
iplibrary.SharedActionManager.UpdateActions(config.FirewallActions)
}
// 统计指标 // 统计指标
metrics.SharedManager.Update(config.MetricItems) if !jsonutils.Equal(this.oldMetricItems, config.MetricItems) {
// copy
this.oldMetricItems = []*serverconfigs.MetricItemConfig{}
err := jsonutils.Copy(&this.oldMetricItems, config.MetricItems)
if err != nil {
remotelogs.Error("NODE", "onReload: copy MetricItemConfigs failed: "+err.Error())
}
// update
metrics.SharedManager.Update(config.MetricItems)
}
// max cpu // max cpu
if config.MaxCPU != this.maxCPU { if config.MaxCPU != this.oldMaxCPU {
if config.MaxCPU > 0 && config.MaxCPU < int32(runtime.NumCPU()) { if config.MaxCPU > 0 && config.MaxCPU < int32(runtime.NumCPU()) {
runtime.GOMAXPROCS(int(config.MaxCPU)) runtime.GOMAXPROCS(int(config.MaxCPU))
remotelogs.Println("NODE", "[CPU]set max cpu to '"+types.String(config.MaxCPU)+"'") remotelogs.Println("NODE", "[CPU]set max cpu to '"+types.String(config.MaxCPU)+"'")
@@ -1021,11 +1080,11 @@ func (this *Node) onReload(config *nodeconfigs.NodeConfig) {
remotelogs.Println("NODE", "[CPU]set max cpu to '"+types.String(threads)+"'") remotelogs.Println("NODE", "[CPU]set max cpu to '"+types.String(threads)+"'")
} }
this.maxCPU = config.MaxCPU this.oldMaxCPU = config.MaxCPU
} }
// max threads // max threads
if config.MaxThreads != this.maxThreads { if config.MaxThreads != this.oldMaxThreads {
if config.MaxThreads > 0 { if config.MaxThreads > 0 {
debug.SetMaxThreads(config.MaxThreads) debug.SetMaxThreads(config.MaxThreads)
remotelogs.Println("NODE", "[THREADS]set max threads to '"+types.String(config.MaxThreads)+"'") remotelogs.Println("NODE", "[THREADS]set max threads to '"+types.String(config.MaxThreads)+"'")
@@ -1033,7 +1092,7 @@ func (this *Node) onReload(config *nodeconfigs.NodeConfig) {
debug.SetMaxThreads(nodeconfigs.DefaultMaxThreads) debug.SetMaxThreads(nodeconfigs.DefaultMaxThreads)
remotelogs.Println("NODE", "[THREADS]set max threads to '"+types.String(nodeconfigs.DefaultMaxThreads)+"'") remotelogs.Println("NODE", "[THREADS]set max threads to '"+types.String(nodeconfigs.DefaultMaxThreads)+"'")
} }
this.maxThreads = config.MaxThreads this.oldMaxThreads = config.MaxThreads
} }
// timezone // timezone
@@ -1042,7 +1101,7 @@ func (this *Node) onReload(config *nodeconfigs.NodeConfig) {
timeZone = "Asia/Shanghai" timeZone = "Asia/Shanghai"
} }
if this.timezone != timeZone { if this.oldTimezone != timeZone {
location, err := time.LoadLocation(timeZone) location, err := time.LoadLocation(timeZone)
if err != nil { if err != nil {
remotelogs.Error("NODE", "[TIMEZONE]change time zone failed: "+err.Error()) remotelogs.Error("NODE", "[TIMEZONE]change time zone failed: "+err.Error())
@@ -1051,7 +1110,7 @@ func (this *Node) onReload(config *nodeconfigs.NodeConfig) {
remotelogs.Println("NODE", "[TIMEZONE]change time zone to '"+timeZone+"'") remotelogs.Println("NODE", "[TIMEZONE]change time zone to '"+timeZone+"'")
time.Local = location time.Local = location
this.timezone = timeZone this.oldTimezone = timeZone
} }
// product information // product information
@@ -1118,7 +1177,7 @@ func (this *Node) reloadServer() {
} }
} }
this.onReload(newNodeConfig) this.onReload(newNodeConfig, false)
err = sharedListenerManager.Start(newNodeConfig) err = sharedListenerManager.Start(newNodeConfig)
if err != nil { if err != nil {

View File

@@ -7,7 +7,7 @@ import (
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
) )
func MapToObject(m maps.Map, ptr interface{}) error { func MapToObject(m maps.Map, ptr any) error {
if m == nil { if m == nil {
return nil return nil
} }
@@ -18,7 +18,7 @@ func MapToObject(m maps.Map, ptr interface{}) error {
return json.Unmarshal(mJSON, ptr) return json.Unmarshal(mJSON, ptr)
} }
func ObjectToMap(ptr interface{}) (maps.Map, error) { func ObjectToMap(ptr any) (maps.Map, error) {
if ptr == nil { if ptr == nil {
return maps.Map{}, nil return maps.Map{}, nil
} }
@@ -33,3 +33,12 @@ func ObjectToMap(ptr interface{}) (maps.Map, error) {
} }
return result, nil return result, nil
} }
func Copy(destPtr any, srcPtr any) error {
data, err := json.Marshal(srcPtr)
if err != nil {
return err
}
err = json.Unmarshal(data, destPtr)
return err
}

View File

@@ -3,11 +3,12 @@
package jsonutils package jsonutils
import ( import (
"bytes"
"encoding/json" "encoding/json"
"testing" "testing"
) )
func PrintT(obj interface{}, t *testing.T) { func PrintT(obj any, t *testing.T) {
data, err := json.MarshalIndent(obj, "", " ") data, err := json.MarshalIndent(obj, "", " ")
if err != nil { if err != nil {
t.Log(err) t.Log(err)
@@ -15,3 +16,17 @@ func PrintT(obj interface{}, t *testing.T) {
t.Log(string(data)) t.Log(string(data))
} }
} }
func Equal(obj1 any, obj2 any) bool {
data1, err := json.Marshal(obj1)
if err != nil {
return false
}
data2, err := json.Marshal(obj2)
if err != nil {
return false
}
return bytes.Equal(data1, data2)
}

View File

@@ -0,0 +1,26 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package jsonutils_test
import (
"github.com/TeaOSLab/EdgeNode/internal/utils/jsonutils"
"github.com/iwind/TeaGo/assert"
"github.com/iwind/TeaGo/maps"
"testing"
)
func TestEqual(t *testing.T) {
var a = assert.NewAssertion(t)
{
var m1 = maps.Map{"a": 1, "b2": true}
var m2 = maps.Map{"b2": true, "a": 1}
a.IsTrue(jsonutils.Equal(m1, m2))
}
{
var m1 = maps.Map{"a": 1, "b2": true, "c": nil}
var m2 = maps.Map{"b2": true, "a": 1}
a.IsFalse(jsonutils.Equal(m1, m2))
}
}