mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-10 20:50:25 +08:00
优化配置重载程序
This commit is contained in:
@@ -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 cachePoliciesChanged {
|
||||||
|
// copy
|
||||||
|
this.oldHTTPCachePolicies = []*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 {
|
if len(config.HTTPCachePolicies) > 0 {
|
||||||
caches.SharedManager.UpdatePolicies(config.HTTPCachePolicies)
|
caches.SharedManager.UpdatePolicies(config.HTTPCachePolicies)
|
||||||
} else {
|
} else {
|
||||||
caches.SharedManager.UpdatePolicies([]*serverconfigs.HTTPCachePolicy{})
|
caches.SharedManager.UpdatePolicies([]*serverconfigs.HTTPCachePolicy{})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WAF策略
|
// WAF策略
|
||||||
waf.SharedWAFManager.UpdatePolicies(config.FindAllFirewallPolicies())
|
var allFirewallPolicies = config.FindAllFirewallPolicies()
|
||||||
|
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)
|
iplibrary.SharedActionManager.UpdateActions(config.FirewallActions)
|
||||||
|
}
|
||||||
|
|
||||||
// 统计指标
|
// 统计指标
|
||||||
|
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)
|
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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
|||||||
26
internal/utils/jsonutils/utils_test.go
Normal file
26
internal/utils/jsonutils/utils_test.go
Normal 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))
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user