移除扩展名匹配器的缓存机制,简化相关逻辑,优化配置更新时的处理流程,提升代码可读性和维护性。

This commit is contained in:
wood chen 2025-06-02 06:50:37 +08:00
parent 9e45b3e38a
commit 1c9d5bc326
3 changed files with 5 additions and 106 deletions

View File

@ -2,7 +2,6 @@ package config
import ( import (
"strings" "strings"
"sync"
) )
type Config struct { type Config struct {
@ -15,11 +14,6 @@ type PathConfig struct {
ExtensionMap []ExtRuleConfig `json:"ExtensionMap"` // 扩展名映射规则 ExtensionMap []ExtRuleConfig `json:"ExtensionMap"` // 扩展名映射规则
ExtRules []ExtensionRule `json:"-"` // 内部使用,存储处理后的扩展名规则 ExtRules []ExtensionRule `json:"-"` // 内部使用,存储处理后的扩展名规则
RedirectMode bool `json:"RedirectMode"` // 是否使用302跳转模式 RedirectMode bool `json:"RedirectMode"` // 是否使用302跳转模式
// 缓存相关字段不参与JSON序列化
matcherCache interface{} `json:"-"` // 缓存的ExtensionMatcher使用interface{}避免循环导入
matcherCacheMux sync.RWMutex `json:"-"` // 缓存读写锁
cacheValid bool `json:"-"` // 缓存是否有效
} }
// ExtensionRule 表示一个扩展名映射规则(内部使用) // ExtensionRule 表示一个扩展名映射规则(内部使用)
@ -79,32 +73,6 @@ func (p *PathConfig) ProcessExtensionMap() {
p.ExtRules = append(p.ExtRules, extRule) p.ExtRules = append(p.ExtRules, extRule)
} }
} }
// 清除缓存,因为规则已经改变
p.InvalidateMatcherCache()
}
// InvalidateMatcherCache 清除ExtensionMatcher缓存
func (p *PathConfig) InvalidateMatcherCache() {
p.matcherCacheMux.Lock()
defer p.matcherCacheMux.Unlock()
p.matcherCache = nil
p.cacheValid = false
}
// GetMatcherCache 获取缓存的ExtensionMatcher
func (p *PathConfig) GetMatcherCache() (interface{}, bool) {
p.matcherCacheMux.RLock()
defer p.matcherCacheMux.RUnlock()
return p.matcherCache, p.cacheValid
}
// SetMatcherCache 设置ExtensionMatcher缓存
func (p *PathConfig) SetMatcherCache(matcher interface{}) {
p.matcherCacheMux.Lock()
defer p.matcherCacheMux.Unlock()
p.matcherCache = matcher
p.cacheValid = true
} }
// GetProcessedExtTarget 快速获取扩展名对应的目标URL如果存在返回true // GetProcessedExtTarget 快速获取扩展名对应的目标URL如果存在返回true

View File

@ -182,10 +182,6 @@ func NewProxyHandler(cfg *config.Config) *ProxyHandler {
// 注册配置更新回调 // 注册配置更新回调
config.RegisterUpdateCallback(func(newCfg *config.Config) { config.RegisterUpdateCallback(func(newCfg *config.Config) {
// 注意config包已经在回调触发前处理了所有ExtRules这里无需再次处理 // 注意config包已经在回调触发前处理了所有ExtRules这里无需再次处理
// 清理所有ExtensionMatcher缓存因为配置已更新
utils.ClearAllMatcherCaches(newCfg.MAP)
handler.pathMap = newCfg.MAP handler.pathMap = newCfg.MAP
handler.prefixTree.update(newCfg.MAP) // 更新前缀匹配树 handler.prefixTree.update(newCfg.MAP) // 更新前缀匹配树
handler.config = newCfg handler.config = newCfg

View File

@ -14,7 +14,6 @@ import (
"sort" "sort"
"strings" "strings"
"sync" "sync"
"sync/atomic"
"time" "time"
) )
@ -38,10 +37,6 @@ var (
cacheTTL = 5 * time.Minute cacheTTL = 5 * time.Minute
accessTTL = 30 * time.Second accessTTL = 30 * time.Second
maxCacheSize = 10000 // 最大缓存条目数 maxCacheSize = 10000 // 最大缓存条目数
// 缓存统计
matcherCacheHits int64
matcherCacheMisses int64
) )
// 清理过期缓存 // 清理过期缓存
@ -86,19 +81,6 @@ func init() {
}) })
} }
}() }()
// 定期打印缓存统计信息
go func() {
ticker := time.NewTicker(5 * time.Minute)
for range ticker.C {
hits, misses := GetMatcherCacheStats()
if hits+misses > 0 {
hitRate := float64(hits) / float64(hits+misses) * 100
log.Printf("[Cache] ExtensionMatcher stats: hits=%d, misses=%d, hit_rate=%.2f%%",
hits, misses, hitRate)
}
}
}()
} }
// GenerateRequestID 生成唯一的请求ID // GenerateRequestID 生成唯一的请求ID
@ -296,40 +278,7 @@ func extractExtension(path string) string {
return "" return ""
} }
// GetMatcherCacheStats 获取缓存统计信息 // SelectBestRule 根据文件大小和扩展名选择最合适的规则(优化版本)
func GetMatcherCacheStats() (hits, misses int64) {
return atomic.LoadInt64(&matcherCacheHits), atomic.LoadInt64(&matcherCacheMisses)
}
// ResetMatcherCacheStats 重置缓存统计
func ResetMatcherCacheStats() {
atomic.StoreInt64(&matcherCacheHits, 0)
atomic.StoreInt64(&matcherCacheMisses, 0)
}
// getOrCreateExtensionMatcher 获取或创建ExtensionMatcher带缓存和统计
func getOrCreateExtensionMatcher(pathConfig *config.PathConfig) *ExtensionMatcher {
// 尝试从缓存获取
if cached, valid := pathConfig.GetMatcherCache(); valid && cached != nil {
if matcher, ok := cached.(*ExtensionMatcher); ok {
atomic.AddInt64(&matcherCacheHits, 1)
return matcher
}
}
// 缓存未命中,创建新的匹配器
atomic.AddInt64(&matcherCacheMisses, 1)
matcher := NewExtensionMatcher(pathConfig.ExtRules)
// 存储到缓存
pathConfig.SetMatcherCache(matcher)
log.Printf("[Cache] ExtensionMatcher created and cached for %d rules", len(pathConfig.ExtRules))
return matcher
}
// SelectBestRule 根据文件大小和扩展名选择最合适的规则(优化版本,带缓存)
// 返回值: (选中的规则, 是否找到匹配的规则, 是否使用了备用目标) // 返回值: (选中的规则, 是否找到匹配的规则, 是否使用了备用目标)
func SelectBestRule(client *http.Client, pathConfig config.PathConfig, path string) (*config.ExtensionRule, bool, bool) { func SelectBestRule(client *http.Client, pathConfig config.PathConfig, path string) (*config.ExtensionRule, bool, bool) {
// 如果没有扩展名规则返回nil // 如果没有扩展名规则返回nil
@ -340,8 +289,8 @@ func SelectBestRule(client *http.Client, pathConfig config.PathConfig, path stri
// 提取扩展名 // 提取扩展名
ext := extractExtension(path) ext := extractExtension(path)
// 获取或创建缓存的扩展名匹配器 // 创建扩展名匹配器(可以考虑缓存这个匹配器)
matcher := getOrCreateExtensionMatcher(&pathConfig) matcher := NewExtensionMatcher(pathConfig.ExtRules)
// 获取匹配的规则 // 获取匹配的规则
matchingRules := matcher.GetMatchingRules(ext) matchingRules := matcher.GetMatchingRules(ext)
@ -385,7 +334,7 @@ func SelectBestRule(client *http.Client, pathConfig config.PathConfig, path stri
return nil, false, false return nil, false, false
} }
// SelectRuleForRedirect 专门为302跳转优化的规则选择函数(带缓存) // SelectRuleForRedirect 专门为302跳转优化的规则选择函数
func SelectRuleForRedirect(client *http.Client, pathConfig config.PathConfig, path string) *RuleSelectionResult { func SelectRuleForRedirect(client *http.Client, pathConfig config.PathConfig, path string) *RuleSelectionResult {
result := &RuleSelectionResult{} result := &RuleSelectionResult{}
@ -405,9 +354,7 @@ func SelectRuleForRedirect(client *http.Client, pathConfig config.PathConfig, pa
// 检查扩展名规则 // 检查扩展名规则
if len(pathConfig.ExtRules) > 0 { if len(pathConfig.ExtRules) > 0 {
ext := extractExtension(path) ext := extractExtension(path)
matcher := NewExtensionMatcher(pathConfig.ExtRules)
// 获取或创建缓存的扩展名匹配器
matcher := getOrCreateExtensionMatcher(&pathConfig)
// 快速检查如果没有任何302跳转规则跳过复杂逻辑 // 快速检查如果没有任何302跳转规则跳过复杂逻辑
if !matcher.HasRedirectRule() { if !matcher.HasRedirectRule() {
@ -591,15 +538,3 @@ func ParseInt(s string, defaultValue int) int {
} }
return result return result
} }
// ClearAllMatcherCaches 清理所有ExtensionMatcher缓存用于配置更新时
func ClearAllMatcherCaches(configMap map[string]config.PathConfig) {
cleared := 0
for path := range configMap {
pathConfig := configMap[path]
pathConfig.InvalidateMatcherCache()
configMap[path] = pathConfig
cleared++
}
log.Printf("[Cache] Cleared %d ExtensionMatcher caches due to config update", cleared)
}