v1.5.1 增强程序稳定性
This commit is contained in:
@@ -407,7 +407,7 @@ func (this *APIStream) handleCheckLocalFirewall(message *pb.NodeStreamMessage) e
|
||||
"version": version,
|
||||
}
|
||||
|
||||
var protectionConfig = sharedNodeConfig.DDoSProtection
|
||||
var protectionConfig = nodeConfig().DDoSProtection
|
||||
err = firewalls.SharedDDoSProtectionManager.Apply(protectionConfig)
|
||||
if err != nil {
|
||||
this.replyFail(message.RequestId, dataMessage.Name+" was installed, but apply DDoS protection config failed: "+err.Error())
|
||||
|
||||
@@ -71,7 +71,7 @@ func NewClientConn(rawConn net.Conn, isHTTP bool, isTLS bool, isInAllowList bool
|
||||
}
|
||||
|
||||
// 超时等设置
|
||||
var globalServerConfig = sharedNodeConfig.GlobalServerConfig
|
||||
var globalServerConfig = nodeConfig().GlobalServerConfig
|
||||
if globalServerConfig != nil {
|
||||
var performanceConfig = globalServerConfig.Performance
|
||||
conn.isDebugging = performanceConfig.Debug
|
||||
@@ -136,7 +136,7 @@ func (this *ClientConn) Read(b []byte) (n int, err error) {
|
||||
if !this.isPersistent && this.isHTTP && !this.isInAllowList && !utils.IsLocalIP(this.RawIP()) {
|
||||
// SYN Flood检测
|
||||
if this.serverId == 0 || !this.hasResetSYNFlood {
|
||||
var synFloodConfig = sharedNodeConfig.SYNFloodConfig()
|
||||
var synFloodConfig = nodeConfig().SYNFloodConfig()
|
||||
if synFloodConfig != nil && synFloodConfig.IsOn {
|
||||
if isHandshakeError {
|
||||
this.increaseSYNFlood(synFloodConfig)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/events"
|
||||
@@ -41,14 +42,14 @@ func init() {
|
||||
eventLocker.Lock()
|
||||
defer eventLocker.Unlock()
|
||||
|
||||
if sharedNodeConfig == nil {
|
||||
if nodeConfig() == nil {
|
||||
return
|
||||
}
|
||||
|
||||
_ = sharedHTTP3Manager.Update(sharedNodeConfig.HTTP3Policies)
|
||||
_ = sharedHTTP3Manager.Update(nodeConfig().HTTP3Policies)
|
||||
sharedHTTP3Manager.UpdateHTTPListener(listener)
|
||||
|
||||
listener.Reload(sharedNodeConfig.HTTP3Group())
|
||||
listener.Reload(nodeConfig().HTTP3Group())
|
||||
}()
|
||||
})
|
||||
}
|
||||
@@ -219,6 +220,12 @@ func (this *HTTP3Manager) createServer(port int) (*http3.Server, error) {
|
||||
},
|
||||
}
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
remotelogs.Error("HTTP3_MANAGER", fmt.Sprintf("goroutine panic: %v", r))
|
||||
}
|
||||
}()
|
||||
|
||||
err = server.Serve(listener)
|
||||
if err != nil {
|
||||
remotelogs.Error("HTTP3_MANAGER", "serve '"+addr+"' failed: "+err.Error())
|
||||
|
||||
@@ -95,8 +95,8 @@ Loop:
|
||||
}
|
||||
|
||||
var writeTargets *serverconfigs.AccessLogWriteTargets
|
||||
if sharedNodeConfig != nil && sharedNodeConfig.GlobalServerConfig != nil {
|
||||
writeTargets = sharedNodeConfig.GlobalServerConfig.HTTPAccessLog.WriteTargets
|
||||
if nodeConfig() != nil && nodeConfig().GlobalServerConfig != nil {
|
||||
writeTargets = nodeConfig().GlobalServerConfig.HTTPAccessLog.WriteTargets
|
||||
}
|
||||
needWriteFile := writeTargets == nil || writeTargets.NeedWriteFile()
|
||||
needReportAPI := writeTargets == nil || writeTargets.NeedReportToAPI()
|
||||
@@ -104,8 +104,8 @@ Loop:
|
||||
// 落盘 JSON Lines(Fluent Bit 采集 → ClickHouse)
|
||||
if needWriteFile {
|
||||
var clusterId int64
|
||||
if sharedNodeConfig != nil {
|
||||
clusterId = sharedNodeConfig.GroupId
|
||||
if nodeConfig() != nil {
|
||||
clusterId = nodeConfig().GroupId
|
||||
}
|
||||
accesslogs.SharedFileWriter().WriteBatch(accessLogs, clusterId)
|
||||
}
|
||||
|
||||
@@ -63,6 +63,11 @@ func (this *HTTPAccessLogViewer) Start() error {
|
||||
var connId = this.nextConnId()
|
||||
this.connMap[connId] = conn
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
remotelogs.Error("ACCESS_LOG", fmt.Sprintf("goroutine panic: %v", r))
|
||||
}
|
||||
}()
|
||||
this.startReading(conn, connId)
|
||||
}()
|
||||
this.locker.Unlock()
|
||||
|
||||
@@ -275,9 +275,9 @@ func (this *HTTPCacheTaskManager) simplifyErr(err error) error {
|
||||
func (this *HTTPCacheTaskManager) httpClient() *http.Client {
|
||||
var timeout = serverconfigs.DefaultHTTPCachePolicyFetchTimeout
|
||||
|
||||
var nodeConfig = sharedNodeConfig // copy
|
||||
if nodeConfig != nil {
|
||||
var cachePolicies = nodeConfig.HTTPCachePolicies // copy
|
||||
var cfg = nodeConfig()
|
||||
if cfg != nil {
|
||||
var cachePolicies = cfg.HTTPCachePolicies // copy
|
||||
if len(cachePolicies) > 0 && cachePolicies[0].FetchTimeout != nil && cachePolicies[0].FetchTimeout.Count > 0 {
|
||||
var fetchTimeout = cachePolicies[0].FetchTimeout.Duration()
|
||||
if fetchTimeout > 0 {
|
||||
|
||||
@@ -144,7 +144,7 @@ func (this *HTTPClientPool) Client(req *HTTPRequest,
|
||||
maxConnections *= 8
|
||||
idleConns *= 8
|
||||
idleTimeout *= 4
|
||||
} else if sharedNodeConfig != nil && sharedNodeConfig.Level > 1 {
|
||||
} else if nodeConfig() != nil && nodeConfig().Level > 1 {
|
||||
// Ln节点可以适当增加连接数
|
||||
maxConnections *= 2
|
||||
idleConns *= 2
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/metrics"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/stats"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/utils/bytepool"
|
||||
@@ -168,12 +167,6 @@ func (this *HTTPRequest) Do() {
|
||||
return
|
||||
}
|
||||
|
||||
// 调试:JS 请求是否命中加密配置
|
||||
if strings.HasSuffix(strings.ToLower(this.Path()), ".js") {
|
||||
encryptionOn := this.web.Encryption != nil && this.web.Encryption.IsOn && this.web.Encryption.IsEnabled()
|
||||
remotelogs.Println("HTTP_REQUEST_ENCRYPTION", fmt.Sprintf("JS request matched - URL: %s, Host: %s, ServerID: %d, encryptionOn=%v", this.URL(), this.ReqHost, this.ReqServer.Id, encryptionOn))
|
||||
}
|
||||
|
||||
// 是否为低级别节点
|
||||
this.isLnRequest = this.checkLnRequest()
|
||||
|
||||
|
||||
@@ -160,14 +160,14 @@ func (this *HTTPRequest) doCC() (block bool) {
|
||||
|
||||
var targetURL = this.RawReq.URL.Query().Get("url")
|
||||
|
||||
var realURLKey = stringutil.Md5(sharedNodeConfig.Secret + "@" + targetURL + "@" + remoteAddr)
|
||||
var realURLKey = stringutil.Md5(nodeConfig().Secret + "@" + targetURL + "@" + remoteAddr)
|
||||
if urlKey != realURLKey {
|
||||
this.ccForbid(2)
|
||||
return true
|
||||
}
|
||||
|
||||
// 校验时间
|
||||
if timestampKey != stringutil.Md5(sharedNodeConfig.Secret+"@"+timestamp) {
|
||||
if timestampKey != stringutil.Md5(nodeConfig().Secret+"@"+timestamp) {
|
||||
this.ccForbid(3)
|
||||
return true
|
||||
}
|
||||
@@ -196,8 +196,8 @@ func (this *HTTPRequest) doCC() (block bool) {
|
||||
return true
|
||||
}
|
||||
|
||||
var urlKey = stringutil.Md5(sharedNodeConfig.Secret + "@" + this.URL() + "@" + remoteAddr)
|
||||
var timestampKey = stringutil.Md5(sharedNodeConfig.Secret + "@" + types.String(currentTime))
|
||||
var urlKey = stringutil.Md5(nodeConfig().Secret + "@" + this.URL() + "@" + remoteAddr)
|
||||
var timestampKey = stringutil.Md5(nodeConfig().Secret + "@" + types.String(currentTime))
|
||||
|
||||
// 跳转到验证URL
|
||||
this.DisableStat()
|
||||
|
||||
@@ -25,28 +25,23 @@ func (this *HTTPRequest) processPageEncryption(resp *http.Response) error {
|
||||
// 首先检查是否是 /waf/loader.js,如果是则直接跳过(不应该被加密)
|
||||
// 这个检查必须在所有其他检查之前,确保 loader.js 永远不会被加密
|
||||
if strings.Contains(this.URL(), "/waf/loader.js") {
|
||||
remotelogs.Debug("HTTP_REQUEST_ENCRYPTION", "skipping /waf/loader.js, should not be encrypted, URL: "+this.URL())
|
||||
return nil
|
||||
}
|
||||
|
||||
if this.web.Encryption == nil {
|
||||
remotelogs.Debug("HTTP_REQUEST_ENCRYPTION", "encryption config is nil for URL: "+this.URL())
|
||||
return nil
|
||||
}
|
||||
|
||||
if !this.web.Encryption.IsOn {
|
||||
remotelogs.Debug("HTTP_REQUEST_ENCRYPTION", "encryption switch is off for URL: "+this.URL())
|
||||
return nil
|
||||
}
|
||||
|
||||
if !this.web.Encryption.IsEnabled() {
|
||||
remotelogs.Debug("HTTP_REQUEST_ENCRYPTION", "encryption is not enabled for URL: "+this.URL())
|
||||
return nil
|
||||
}
|
||||
|
||||
// 检查 URL 白名单
|
||||
if this.web.Encryption.MatchExcludeURL(this.URL()) {
|
||||
remotelogs.Debug("HTTP_REQUEST_ENCRYPTION", "URL is in exclude list: "+this.URL())
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -66,7 +61,6 @@ func (this *HTTPRequest) processPageEncryption(resp *http.Response) error {
|
||||
strings.Contains(urlLower, ".js&")
|
||||
|
||||
if !isHTML && !isJavaScript {
|
||||
remotelogs.Debug("HTTP_REQUEST_ENCRYPTION", "content type not match, URL: "+this.URL()+", Content-Type: "+contentType)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -101,47 +95,37 @@ func (this *HTTPRequest) processPageEncryption(resp *http.Response) error {
|
||||
|
||||
// 处理 JavaScript 文件
|
||||
if isJavaScript {
|
||||
remotelogs.Debug("HTTP_REQUEST_ENCRYPTION", "processing JavaScript file, URL: "+this.URL())
|
||||
|
||||
// 检查是否需要加密独立的 JavaScript 文件
|
||||
if this.web.Encryption.Javascript == nil {
|
||||
remotelogs.Debug("HTTP_REQUEST_ENCRYPTION", "Javascript config is nil for URL: "+this.URL())
|
||||
resp.Body = io.NopCloser(bytes.NewReader(bodyBytes))
|
||||
return nil
|
||||
}
|
||||
|
||||
if !this.web.Encryption.Javascript.IsOn {
|
||||
remotelogs.Debug("HTTP_REQUEST_ENCRYPTION", "Javascript encryption is not enabled for URL: "+this.URL())
|
||||
resp.Body = io.NopCloser(bytes.NewReader(bodyBytes))
|
||||
return nil
|
||||
}
|
||||
|
||||
// 检查 URL 匹配
|
||||
if !this.web.Encryption.Javascript.MatchURL(this.URL()) {
|
||||
remotelogs.Debug("HTTP_REQUEST_ENCRYPTION", "URL does not match patterns for URL: "+this.URL())
|
||||
resp.Body = io.NopCloser(bytes.NewReader(bodyBytes))
|
||||
return nil
|
||||
}
|
||||
|
||||
// 跳过 Loader 文件(必须排除,否则 loader.js 会被错误加密)
|
||||
// 跳过 Loader 文件
|
||||
if strings.Contains(this.URL(), "/waf/loader.js") ||
|
||||
strings.Contains(this.URL(), "waf-loader.js") ||
|
||||
strings.Contains(this.URL(), "__WAF_") {
|
||||
remotelogs.Debug("HTTP_REQUEST_ENCRYPTION", "skipping loader file, URL: "+this.URL())
|
||||
resp.Body = io.NopCloser(bytes.NewReader(bodyBytes))
|
||||
return nil
|
||||
}
|
||||
|
||||
// 加密 JavaScript 文件
|
||||
remotelogs.Println("HTTP_REQUEST_ENCRYPTION", "encrypting JavaScript file, URL: "+this.URL())
|
||||
encryptedBytes, err = this.encryptJavaScriptFile(bodyBytes, resp)
|
||||
if err != nil {
|
||||
remotelogs.Warn("HTTP_REQUEST_ENCRYPTION", "encrypt JavaScript file failed: "+err.Error())
|
||||
// 加密失败,恢复原始响应体
|
||||
resp.Body = io.NopCloser(bytes.NewReader(bodyBytes))
|
||||
return nil
|
||||
}
|
||||
remotelogs.Println("HTTP_REQUEST_ENCRYPTION", "JavaScript file encrypted successfully, URL: "+this.URL())
|
||||
} else if isHTML {
|
||||
// 加密 HTML 内容
|
||||
encryptedBytes, err = this.encryptHTMLScripts(bodyBytes, resp)
|
||||
|
||||
@@ -34,9 +34,9 @@ func (this *HTTPRequest) doMismatch() {
|
||||
}
|
||||
|
||||
// 根据配置进行相应的处理
|
||||
var nodeConfig = sharedNodeConfig // copy
|
||||
if nodeConfig != nil {
|
||||
var globalServerConfig = nodeConfig.GlobalServerConfig
|
||||
var cfg = nodeConfig()
|
||||
if cfg != nil {
|
||||
var globalServerConfig = cfg.GlobalServerConfig
|
||||
if globalServerConfig != nil && globalServerConfig.HTTPAll.MatchDomainStrictly {
|
||||
var statusCode = 404
|
||||
var httpAllConfig = globalServerConfig.HTTPAll
|
||||
|
||||
@@ -24,7 +24,7 @@ func (this *HTTPRequest) doPlanBefore() (blocked bool) {
|
||||
|
||||
// check max upload size
|
||||
if this.RawReq.ContentLength > 0 {
|
||||
var plan = sharedNodeConfig.FindPlan(this.ReqServer.UserPlan.PlanId)
|
||||
var plan = nodeConfig().FindPlan(this.ReqServer.UserPlan.PlanId)
|
||||
if plan != nil && plan.MaxUploadSize != nil && plan.MaxUploadSize.Count > 0 {
|
||||
if this.RawReq.ContentLength > plan.MaxUploadSize.Bytes() {
|
||||
this.writeCode(http.StatusRequestEntityTooLarge, "Reached max upload size limitation in your plan.", "触发套餐中最大文件上传尺寸限制。")
|
||||
|
||||
@@ -29,7 +29,7 @@ func init() {
|
||||
if sharedUAMManager != nil {
|
||||
return
|
||||
}
|
||||
manager, _ := uam.NewManager(sharedNodeConfig.NodeId, sharedNodeConfig.Secret)
|
||||
manager, _ := uam.NewManager(nodeConfig().NodeId, nodeConfig().Secret)
|
||||
if manager != nil {
|
||||
sharedUAMManager = manager
|
||||
}
|
||||
@@ -39,7 +39,7 @@ func init() {
|
||||
if sharedUAMManager != nil {
|
||||
return
|
||||
}
|
||||
manager, _ := uam.NewManager(sharedNodeConfig.NodeId, sharedNodeConfig.Secret)
|
||||
manager, _ := uam.NewManager(nodeConfig().NodeId, nodeConfig().Secret)
|
||||
if manager != nil {
|
||||
sharedUAMManager = manager
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/utils/bytepool"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
@@ -126,6 +128,12 @@ func (this *HTTPRequest) doWebsocket(requestHost string, isLastRetry bool) (shou
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Println(fmt.Sprintf("[WEBSOCKET]goroutine panic: %v", r))
|
||||
}
|
||||
}()
|
||||
|
||||
// 读取第一个响应
|
||||
var respReader = NewWebsocketResponseReader(originConn)
|
||||
resp, respErr := http.ReadResponse(bufio.NewReader(respReader), this.RawReq)
|
||||
|
||||
@@ -93,8 +93,8 @@ func (this *BaseListener) matchSSL(domains []string) (*sslconfigs.SSLPolicy, *tl
|
||||
}
|
||||
|
||||
var globalServerConfig *serverconfigs.GlobalServerConfig
|
||||
if sharedNodeConfig != nil {
|
||||
globalServerConfig = sharedNodeConfig.GlobalServerConfig
|
||||
if nodeConfig() != nil {
|
||||
globalServerConfig = nodeConfig().GlobalServerConfig
|
||||
}
|
||||
|
||||
// 如果域名为空,则取第一个
|
||||
@@ -191,7 +191,7 @@ func (this *BaseListener) findNamedServer(name string, exactly bool) (serverConf
|
||||
return
|
||||
}
|
||||
|
||||
var globalServerConfig = sharedNodeConfig.GlobalServerConfig
|
||||
var globalServerConfig = nodeConfig().GlobalServerConfig
|
||||
var matchDomainStrictly = globalServerConfig != nil && globalServerConfig.HTTPAll.MatchDomainStrictly
|
||||
|
||||
if globalServerConfig != nil &&
|
||||
@@ -241,7 +241,7 @@ func (this *BaseListener) findNamedServerMatched(name string) (serverConfig *ser
|
||||
}
|
||||
|
||||
// 是否严格匹配域名
|
||||
var matchDomainStrictly = sharedNodeConfig.GlobalServerConfig != nil && sharedNodeConfig.GlobalServerConfig.HTTPAll.MatchDomainStrictly
|
||||
var matchDomainStrictly = nodeConfig().GlobalServerConfig != nil && nodeConfig().GlobalServerConfig.HTTPAll.MatchDomainStrictly
|
||||
|
||||
// 如果只有一个server,则默认为这个
|
||||
var currentServers = group.Servers()
|
||||
@@ -270,7 +270,7 @@ func (this *BaseListener) helloServerNames(clientInfo *tls.ClientHelloInfo) (ser
|
||||
}
|
||||
}
|
||||
|
||||
serverNames = append(serverNames, sharedNodeConfig.IPAddresses...)
|
||||
serverNames = append(serverNames, nodeConfig().IPAddresses...)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func TestBaseListener_FindServer(t *testing.T) {
|
||||
sharedNodeConfig = &nodeconfigs.NodeConfig{}
|
||||
sharedNodeConfig.Store(&nodeconfigs.NodeConfig{})
|
||||
|
||||
var listener = &BaseListener{}
|
||||
listener.Group = serverconfigs.NewServerAddressGroup("https://*:443")
|
||||
|
||||
@@ -121,7 +121,7 @@ func (this *HTTPListener) ServeHTTPWithAddr(rawWriter http.ResponseWriter, rawRe
|
||||
return
|
||||
}
|
||||
|
||||
var globalServerConfig = sharedNodeConfig.GlobalServerConfig
|
||||
var globalServerConfig = nodeConfig().GlobalServerConfig
|
||||
if globalServerConfig != nil && !globalServerConfig.HTTPAll.SupportsLowVersionHTTP && (rawReq.ProtoMajor < 1 /** 0.x **/ || (rawReq.ProtoMajor == 1 && rawReq.ProtoMinor == 0 /** 1.0 **/)) {
|
||||
http.Error(rawWriter, rawReq.Proto+" request is not supported.", http.StatusHTTPVersionNotSupported)
|
||||
time.Sleep(1 * time.Second) // make connection slow down
|
||||
@@ -223,7 +223,7 @@ func (this *HTTPListener) ServeHTTPWithAddr(rawWriter http.ResponseWriter, rawRe
|
||||
IsHTTPS: this.isHTTPS,
|
||||
IsHTTP3: this.isHTTP3,
|
||||
|
||||
nodeConfig: sharedNodeConfig,
|
||||
nodeConfig: nodeConfig(),
|
||||
}
|
||||
req.Do()
|
||||
|
||||
@@ -259,8 +259,8 @@ func (this *HTTPListener) emptyServer() *serverconfigs.ServerConfig {
|
||||
}
|
||||
|
||||
// 检查是否开启访问日志
|
||||
if sharedNodeConfig != nil {
|
||||
var globalServerConfig = sharedNodeConfig.GlobalServerConfig
|
||||
if nodeConfig() != nil {
|
||||
var globalServerConfig = nodeConfig().GlobalServerConfig
|
||||
if globalServerConfig != nil && globalServerConfig.HTTPAccessLog.EnableServerNotFound {
|
||||
var accessLogRef = serverconfigs.NewHTTPAccessLogRef()
|
||||
accessLogRef.IsOn = true
|
||||
|
||||
@@ -237,7 +237,7 @@ func (this *ListenerManager) findProcessNameWithPort(isUdp bool, port string) st
|
||||
}
|
||||
|
||||
func (this *ListenerManager) addToFirewalld(groupAddrs []string) {
|
||||
if !sharedNodeConfig.AutoOpenPorts {
|
||||
if !nodeConfig().AutoOpenPorts {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ func (this *ListenerManager) addToFirewalld(groupAddrs []string) {
|
||||
}
|
||||
|
||||
// HTTP/3相关端口
|
||||
var http3Ports = sharedNodeConfig.FindHTTP3Ports()
|
||||
var http3Ports = nodeConfig().FindHTTP3Ports()
|
||||
if len(http3Ports) > 0 {
|
||||
for _, port := range http3Ports {
|
||||
var groupAddr = "udp://:" + types.String(port)
|
||||
@@ -347,12 +347,12 @@ func (this *ListenerManager) reloadFirewalld() {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
|
||||
var nodeConfig = sharedNodeConfig
|
||||
var cfg = nodeConfig()
|
||||
|
||||
// 所有的新地址
|
||||
var groupAddrs = []string{}
|
||||
var availableServerGroups = nodeConfig.AvailableGroups()
|
||||
if !nodeConfig.IsOn {
|
||||
var availableServerGroups = cfg.AvailableGroups()
|
||||
if !cfg.IsOn {
|
||||
availableServerGroups = []*serverconfigs.ServerAddressGroup{}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,11 +49,17 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
var sharedNodeConfig *nodeconfigs.NodeConfig
|
||||
var sharedNodeConfig atomic.Pointer[nodeconfigs.NodeConfig]
|
||||
|
||||
// nodeConfig 返回当前节点配置(并发安全)
|
||||
func nodeConfig() *nodeconfigs.NodeConfig {
|
||||
return sharedNodeConfig.Load()
|
||||
}
|
||||
var nodeTaskNotify = make(chan bool, 8)
|
||||
var nodeConfigChangedNotify = make(chan bool, 8)
|
||||
var nodeConfigUpdatedAt int64
|
||||
@@ -63,7 +69,7 @@ var nodeInstance *Node
|
||||
|
||||
// Node 节点
|
||||
type Node struct {
|
||||
isLoaded bool
|
||||
isLoaded atomic.Bool
|
||||
sock *gosock.Sock
|
||||
locker sync.Mutex
|
||||
|
||||
@@ -200,11 +206,13 @@ func (this *Node) Start() {
|
||||
remotelogs.ServerError(serverErr.Id, "NODE", serverErr.Message, nodeconfigs.NodeLogTypeServerConfigInitFailed, maps.Map{})
|
||||
}
|
||||
}
|
||||
sharedNodeConfig = nodeConfig
|
||||
sharedNodeConfig.Store(nodeConfig)
|
||||
this.onReload(nodeConfig, true)
|
||||
|
||||
// 调整系统参数
|
||||
go this.tuneSystemParameters()
|
||||
goman.New(func() {
|
||||
this.tuneSystemParameters()
|
||||
})
|
||||
|
||||
// 发送事件
|
||||
events.Notify(events.EventLoaded)
|
||||
@@ -406,7 +414,7 @@ func (this *Node) syncConfig(taskVersion int64) error {
|
||||
}
|
||||
|
||||
// 刷新配置
|
||||
if this.isLoaded {
|
||||
if this.isLoaded.Load() {
|
||||
remotelogs.Println("NODE", "reloading node config ...")
|
||||
} else {
|
||||
remotelogs.Println("NODE", "loading node config ...")
|
||||
@@ -417,11 +425,11 @@ func (this *Node) syncConfig(taskVersion int64) error {
|
||||
// 发送事件
|
||||
events.Notify(events.EventReload)
|
||||
|
||||
if this.isLoaded {
|
||||
if this.isLoaded.Load() {
|
||||
return sharedListenerManager.Start(nodeConfig)
|
||||
}
|
||||
|
||||
this.isLoaded = true
|
||||
this.isLoaded.Store(true)
|
||||
|
||||
// 预创建本地日志目录与空文件,便于 Fluent Bit 立即 tail,无需等首条访问日志
|
||||
_ = accesslogs.SharedFileWriter().EnsureInit()
|
||||
@@ -885,7 +893,7 @@ func (this *Node) listenSock() error {
|
||||
// 重载配置调用
|
||||
func (this *Node) onReload(config *nodeconfigs.NodeConfig, reloadAll bool) {
|
||||
nodeconfigs.ResetNodeConfig(config)
|
||||
sharedNodeConfig = config
|
||||
sharedNodeConfig.Store(config)
|
||||
|
||||
var accessLogFilePath string
|
||||
if config != nil && config.GlobalServerConfig != nil {
|
||||
@@ -1069,7 +1077,7 @@ func (this *Node) reloadServer() {
|
||||
if countUpdatingServers > 0 {
|
||||
var updatingServerMap = this.updatingServerMap
|
||||
this.updatingServerMap = map[int64]*serverconfigs.ServerConfig{}
|
||||
newNodeConfig, err := nodeconfigs.CloneNodeConfig(sharedNodeConfig)
|
||||
newNodeConfig, err := nodeconfigs.CloneNodeConfig(nodeConfig())
|
||||
if err != nil {
|
||||
remotelogs.Error("NODE", "apply server config error: "+err.Error())
|
||||
return
|
||||
@@ -1121,7 +1129,7 @@ func (this *Node) tuneSystemParameters() {
|
||||
return
|
||||
}
|
||||
|
||||
if sharedNodeConfig == nil || !sharedNodeConfig.AutoSystemTuning {
|
||||
if nodeConfig() == nil || !nodeConfig().AutoSystemTuning {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -51,14 +51,14 @@ func (this *Node) reloadCommonScripts() error {
|
||||
return err
|
||||
}
|
||||
if len(configsResp.ScriptConfigsJSON) == 0 {
|
||||
sharedNodeConfig.CommonScripts = nil
|
||||
nodeConfig().CommonScripts = nil
|
||||
} else {
|
||||
var configs = []*serverconfigs.CommonScript{}
|
||||
err = json.Unmarshal(configsResp.ScriptConfigsJSON, &configs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decode script configs failed: %w", err)
|
||||
}
|
||||
sharedNodeConfig.CommonScripts = configs
|
||||
nodeConfig().CommonScripts = configs
|
||||
}
|
||||
|
||||
// 通知更新
|
||||
@@ -71,13 +71,20 @@ func (this *Node) reloadCommonScripts() error {
|
||||
}
|
||||
|
||||
func (this *Node) reloadIPLibrary() {
|
||||
if sharedNodeConfig.Edition == lastEdition {
|
||||
var cfg = nodeConfig()
|
||||
if cfg.Edition == lastEdition {
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
remotelogs.Error("IP_LIBRARY", fmt.Sprintf("goroutine panic: %v", r))
|
||||
}
|
||||
}()
|
||||
|
||||
var err error
|
||||
lastEdition = sharedNodeConfig.Edition
|
||||
lastEdition = cfg.Edition
|
||||
if len(lastEdition) > 0 && (lists.ContainsString([]string{"pro", "ent", "max", "ultra"}, lastEdition)) {
|
||||
err = iplib.InitPlus()
|
||||
} else {
|
||||
@@ -100,11 +107,12 @@ func (this *Node) notifyPlusChange() error {
|
||||
return err
|
||||
}
|
||||
|
||||
var isChanged = resp.Edition != sharedNodeConfig.Edition
|
||||
var cfg = nodeConfig()
|
||||
var isChanged = resp.Edition != cfg.Edition
|
||||
if resp.IsPlus {
|
||||
sharedNodeConfig.Edition = resp.Edition
|
||||
cfg.Edition = resp.Edition
|
||||
} else {
|
||||
sharedNodeConfig.Edition = ""
|
||||
cfg.Edition = ""
|
||||
}
|
||||
|
||||
if isChanged {
|
||||
|
||||
@@ -70,7 +70,8 @@ func (this *NodeStatusExecutor) Listen() {
|
||||
}
|
||||
|
||||
func (this *NodeStatusExecutor) update() {
|
||||
if sharedNodeConfig == nil {
|
||||
var cfg = nodeConfig()
|
||||
if cfg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -83,7 +84,7 @@ func (this *NodeStatusExecutor) update() {
|
||||
status.OS = runtime.GOOS
|
||||
status.Arch = runtime.GOARCH
|
||||
status.ExePath, _ = os.Executable()
|
||||
status.ConfigVersion = sharedNodeConfig.Version
|
||||
status.ConfigVersion = cfg.Version
|
||||
status.IsActive = true
|
||||
status.ConnectionCount = sharedListenerManager.TotalActiveConnections()
|
||||
status.CacheTotalDiskSize = caches.SharedManager.TotalDiskSize()
|
||||
|
||||
@@ -156,8 +156,9 @@ func (this *Node) execNodeLevelChangedTask(rpcClient *rpc.RPCClient) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if sharedNodeConfig != nil {
|
||||
sharedNodeConfig.Level = levelInfoResp.Level
|
||||
var cfg = nodeConfig()
|
||||
if cfg != nil {
|
||||
cfg.Level = levelInfoResp.Level
|
||||
}
|
||||
|
||||
var parentNodes = map[int64][]*nodeconfigs.ParentNodeConfig{}
|
||||
@@ -168,8 +169,8 @@ func (this *Node) execNodeLevelChangedTask(rpcClient *rpc.RPCClient) error {
|
||||
}
|
||||
}
|
||||
|
||||
if sharedNodeConfig != nil {
|
||||
sharedNodeConfig.ParentNodes = parentNodes
|
||||
if cfg != nil {
|
||||
cfg.ParentNodes = parentNodes
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -181,9 +182,10 @@ func (this *Node) execDDoSProtectionChangedTask(rpcClient *rpc.RPCClient) error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var cfg = nodeConfig()
|
||||
if len(resp.DdosProtectionJSON) == 0 {
|
||||
if sharedNodeConfig != nil {
|
||||
sharedNodeConfig.DDoSProtection = nil
|
||||
if cfg != nil {
|
||||
cfg.DDoSProtection = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -194,8 +196,8 @@ func (this *Node) execDDoSProtectionChangedTask(rpcClient *rpc.RPCClient) error
|
||||
return fmt.Errorf("decode DDoS protection config failed: %w", err)
|
||||
}
|
||||
|
||||
if ddosProtectionConfig != nil && sharedNodeConfig != nil {
|
||||
sharedNodeConfig.DDoSProtection = ddosProtectionConfig
|
||||
if ddosProtectionConfig != nil && cfg != nil {
|
||||
cfg.DDoSProtection = ddosProtectionConfig
|
||||
}
|
||||
|
||||
go func() {
|
||||
@@ -227,8 +229,9 @@ func (this *Node) execGlobalServerConfigChangedTask(rpcClient *rpc.RPCClient) er
|
||||
if err != nil {
|
||||
return fmt.Errorf("validate global server config failed: %w", err)
|
||||
}
|
||||
if sharedNodeConfig != nil {
|
||||
sharedNodeConfig.GlobalServerConfig = globalServerConfig
|
||||
var cfg = nodeConfig()
|
||||
if cfg != nil {
|
||||
cfg.GlobalServerConfig = globalServerConfig
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,7 +261,7 @@ func (this *Node) execUserServersStateChangedTask(rpcClient *rpc.RPCClient, task
|
||||
// 更新一组服务列表
|
||||
func (this *Node) execUpdatingServersTask(rpcClient *rpc.RPCClient) error {
|
||||
if this.lastUpdatingServerListId <= 0 {
|
||||
this.lastUpdatingServerListId = sharedNodeConfig.UpdatingServerListId
|
||||
this.lastUpdatingServerListId = nodeConfig().UpdatingServerListId
|
||||
}
|
||||
|
||||
resp, err := rpcClient.UpdatingServerListRPC.FindUpdatingServerLists(rpcClient.Context(), &pb.FindUpdatingServerListsRequest{LastId: this.lastUpdatingServerListId})
|
||||
@@ -353,7 +356,7 @@ func (this *Node) execWebPPolicyChangedTask(rpcClient *rpc.RPCClient) error {
|
||||
webPPolicyMap[policy.NodeClusterId] = webPPolicy
|
||||
}
|
||||
}
|
||||
sharedNodeConfig.UpdateWebPImagePolicies(webPPolicyMap)
|
||||
nodeConfig().UpdateWebPImagePolicies(webPPolicyMap)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ func (this *Node) execUAMPolicyChangedTask(rpcClient *rpc.RPCClient) error {
|
||||
uamPolicyMap[policy.NodeClusterId] = uamPolicy
|
||||
}
|
||||
}
|
||||
sharedNodeConfig.UpdateUAMPolicies(uamPolicyMap)
|
||||
nodeConfig().UpdateUAMPolicies(uamPolicyMap)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ func (this *Node) execHTTPCCPolicyChangedTask(rpcClient *rpc.RPCClient) error {
|
||||
httpCCPolicyMap[policy.NodeClusterId] = httpCCPolicy
|
||||
}
|
||||
}
|
||||
sharedNodeConfig.UpdateHTTPCCPolicies(httpCCPolicyMap)
|
||||
nodeConfig().UpdateHTTPCCPolicies(httpCCPolicyMap)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ func (this *Node) execHTTP3PolicyChangedTask(rpcClient *rpc.RPCClient) error {
|
||||
}
|
||||
}
|
||||
|
||||
sharedNodeConfig.UpdateHTTP3Policies(http3PolicyMap)
|
||||
nodeConfig().UpdateHTTP3Policies(http3PolicyMap)
|
||||
|
||||
// 加入端口到防火墙
|
||||
sharedListenerManager.reloadFirewalld()
|
||||
@@ -143,7 +143,7 @@ func (this *Node) execHTTPPagesPolicyChangedTask(rpcClient *rpc.RPCClient) error
|
||||
httpPagesPolicyMap[policy.NodeClusterId] = httpPagesPolicy
|
||||
}
|
||||
}
|
||||
sharedNodeConfig.UpdateHTTPPagesPolicies(httpPagesPolicyMap)
|
||||
nodeConfig().UpdateHTTPPagesPolicies(httpPagesPolicyMap)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ func (this *Node) execPlanChangedTask(rpcClient *rpc.RPCClient) error {
|
||||
}
|
||||
}
|
||||
|
||||
sharedNodeConfig.UpdatePlans(planMap)
|
||||
nodeConfig().UpdatePlans(planMap)
|
||||
sharedPlanBandwidthLimiter.UpdatePlans(planMap)
|
||||
|
||||
return nil
|
||||
|
||||
@@ -72,8 +72,8 @@ func (this *OriginStateManager) Stop() {
|
||||
|
||||
// Loop 单次循环检查
|
||||
func (this *OriginStateManager) Loop() error {
|
||||
var nodeConfig = sharedNodeConfig // 复制
|
||||
if nodeConfig == nil {
|
||||
var cfg = nodeConfig() // 复制
|
||||
if cfg == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ func (this *OriginStateManager) Loop() error {
|
||||
this.locker.Lock()
|
||||
for originId, state := range this.stateMap {
|
||||
// 检查Origin是否正在使用
|
||||
var originConfig = nodeConfig.FindOrigin(originId)
|
||||
var originConfig = cfg.FindOrigin(originId)
|
||||
if originConfig == nil || !originConfig.IsOn {
|
||||
delete(this.stateMap, originId)
|
||||
continue
|
||||
|
||||
@@ -18,10 +18,11 @@ func init() {
|
||||
}
|
||||
|
||||
events.On(events.EventLoaded, func() {
|
||||
if sharedNodeConfig == nil {
|
||||
var cfg = nodeConfig()
|
||||
if cfg == nil {
|
||||
return
|
||||
}
|
||||
sharedPlanBandwidthLimiter.UpdatePlans(sharedNodeConfig.FindAllPlans())
|
||||
sharedPlanBandwidthLimiter.UpdatePlans(cfg.FindAllPlans())
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -43,8 +43,9 @@ func init() {
|
||||
}
|
||||
|
||||
events.On(events.EventReload, func() {
|
||||
if sharedNodeConfig != nil {
|
||||
var scripts = sharedNodeConfig.CommonScripts // 拷贝为了安全操作
|
||||
var cfg = nodeConfig()
|
||||
if cfg != nil {
|
||||
var scripts = cfg.CommonScripts // 拷贝为了安全操作
|
||||
if js.IsSameCommonScripts(scripts) {
|
||||
if SharedJSPool == nil {
|
||||
createPool()
|
||||
@@ -60,8 +61,9 @@ func init() {
|
||||
|
||||
goman.New(func() {
|
||||
for range commonScriptsChangesChan {
|
||||
if sharedNodeConfig != nil {
|
||||
var scripts = sharedNodeConfig.CommonScripts // 拷贝为了安全操作
|
||||
var cfg = nodeConfig()
|
||||
if cfg != nil {
|
||||
var scripts = cfg.CommonScripts // 拷贝为了安全操作
|
||||
if js.IsSameCommonScripts(scripts) {
|
||||
if SharedJSPool == nil {
|
||||
createPool()
|
||||
|
||||
@@ -43,15 +43,16 @@ func NewSystemServiceManager() *SystemServiceManager {
|
||||
}
|
||||
|
||||
func (this *SystemServiceManager) Setup() error {
|
||||
if sharedNodeConfig == nil || !sharedNodeConfig.IsOn {
|
||||
var cfg = nodeConfig()
|
||||
if cfg == nil || !cfg.IsOn {
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(sharedNodeConfig.SystemServices) == 0 {
|
||||
if len(cfg.SystemServices) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
systemdParams, ok := sharedNodeConfig.SystemServices[nodeconfigs.SystemServiceTypeSystemd]
|
||||
systemdParams, ok := cfg.SystemServices[nodeconfigs.SystemServiceTypeSystemd]
|
||||
if ok {
|
||||
err := this.setupSystemd(systemdParams)
|
||||
if err != nil {
|
||||
|
||||
@@ -21,7 +21,7 @@ func init() {
|
||||
}
|
||||
|
||||
events.On(events.EventLoaded, func() {
|
||||
sharedOCSPTask.version = sharedNodeConfig.OCSPVersion
|
||||
sharedOCSPTask.version = nodeConfig().OCSPVersion
|
||||
|
||||
goman.New(func() {
|
||||
sharedOCSPTask.Start()
|
||||
@@ -76,10 +76,11 @@ func (this *OCSPUpdateTask) Loop() error {
|
||||
return err
|
||||
}
|
||||
|
||||
var cfg = nodeConfig()
|
||||
for _, ocsp := range resp.SslCertOCSP {
|
||||
// 更新OCSP
|
||||
if sharedNodeConfig != nil {
|
||||
sharedNodeConfig.UpdateCertOCSP(ocsp.SslCertId, ocsp.Data, ocsp.ExpiresAt)
|
||||
if cfg != nil {
|
||||
cfg.UpdateCertOCSP(ocsp.SslCertId, ocsp.Data, ocsp.ExpiresAt)
|
||||
}
|
||||
|
||||
// 修改版本
|
||||
|
||||
@@ -62,7 +62,8 @@ func (this *SyncAPINodesTask) Stop() {
|
||||
|
||||
func (this *SyncAPINodesTask) Loop() error {
|
||||
// 如果有节点定制的API节点地址
|
||||
var hasCustomizedAPINodeAddrs = sharedNodeConfig != nil && len(sharedNodeConfig.APINodeAddrs) > 0
|
||||
var cfg = nodeConfig()
|
||||
var hasCustomizedAPINodeAddrs = cfg != nil && len(cfg.APINodeAddrs) > 0
|
||||
|
||||
config, err := configs.LoadAPIConfig()
|
||||
if err != nil {
|
||||
|
||||
@@ -47,11 +47,11 @@ func (this *TrimDisksTask) loop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var nodeConfig = sharedNodeConfig
|
||||
if nodeConfig == nil {
|
||||
var cfg = nodeConfig()
|
||||
if cfg == nil {
|
||||
return nil
|
||||
}
|
||||
if !nodeConfig.AutoTrimDisks {
|
||||
if !cfg.AutoTrimDisks {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ func init() {
|
||||
}
|
||||
|
||||
events.On(events.EventLoaded, func() {
|
||||
err := sharedTOAManager.Apply(sharedNodeConfig.TOA)
|
||||
err := sharedTOAManager.Apply(nodeConfig().TOA)
|
||||
if err != nil {
|
||||
remotelogs.Error("TOA", err.Error())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user