Files
dns-server/.trae/documents/内存泄露问题.md
2026-01-14 23:08:46 +08:00

4.9 KiB
Raw Blame History

内存泄漏问题

1. IP地理位置缓存泄漏

问题IP地理位置缓存ipGeolocationCache)缺少全局过期清理机制,仅在获取新数据时检查单条缓存过期,导致长期运行后内存无限增长。

修复建议:

// 在Server结构体中添加清理定时器ipGeolocationCacheCleanupTicker *time.Ticker// 在NewServer函数中启动清理协程go s.startIPGeolocationCacheCleanup()// 添加清理函数func (s *Server) startIPGeolocationCacheCleanup() {    ticker := time.NewTicker(time.    Hour) // 每小时清理一次    defer ticker.Stop()        for {        select {        case <-ticker.C:            s.            cleanupExpiredIPGeolocat            ionCache()        case <-s.ctx.Done():            return        }    }}func (s *Server) cleanupExpiredIPGeolocationCache() {    now := time.Now()    s.ipGeolocationCacheMutex.Lock()    defer s.ipGeolocationCacheMutex.    Unlock()        for ip, geo := range s.    ipGeolocationCache {        if now.After(geo.Expiry) {            delete(s.            ipGeolocationCache, ip)        }    }}

2. DNS缓存无大小限制

问题DNS缓存DNSCache仅按TTL过期无最大条目数限制可能导致内存无限增长。

修复建议:

// 在DNSCache结构体中添加最大大小限制maxSize int// 在Set方法中添加大小限制检查func (c *DNSCache) Set(qName string, qType uint16, response *dns.Msg, ttl time.Duration) {    // 现有代码...        c.mutex.Lock()    defer c.mutex.Unlock()        c.cache[key] = item        // 检查并清理超过最大大小的缓存    if c.maxSize > 0 && len(c.    cache) > c.maxSize {        c.evictOldest() // 实现LRU或        随机淘汰策略    }}

1. 域名检查函数性能优化

问题:CheckDomainBlockDetails函数中重复的子域名检查和大量正则表达式匹配导致CPU使用率过高。

修复建议:

// 合并本地和远程规则检查减少循环次数func (m *ShieldManager) CheckDomainBlockDetails(domain string) map[string]interface{} {    // 预处理域名    // ...        // 合并域名排除规则检查    if m.domainExceptions[domain] {        result["excluded"] = true        result["excludeRule"] = m.        domainExceptionsOriginal        [domain]        result["excludeRuleType"] =         "exact_domain"        result["blocksource"] = m.        domainExceptionsSource        [domain]        return result    }        // 合并子域名检查    parts := strings.Split(domain,     ".")    for i := 0; i < len(parts)-1; i    ++ {        subdomain := strings.Join        (parts[i:], ".")        if m.domainExceptions        [subdomain] {            result["excluded"] =             true            result["excludeRule"] =             m.            domainExceptionsOriginal            [subdomain]            result            ["excludeRuleType"] =             "subdomain"            result["blocksource"] =             m.domainExceptionsSource            [subdomain]            return result        }    }        // 合并正则表达式检查    for _, re := range m.    regexExceptions {        if re.pattern.MatchString        (domain) {            result["excluded"] =             true            result["excludeRule"] =             re.original            result            ["excludeRuleType"] =             "regex"            result["blocksource"] =             re.source            return result        }    }        // 阻止规则检查采用相同优化方式    // ...}

2. 减少锁持有时间

问题:CheckDomainBlockDetails函数持有读锁时间过长,影响并发性能。 修复建议:

// 采用更细粒度的锁或读写分离策略func (m *ShieldManager) CheckDomainBlockDetails(domain string) map[string]interface{} {    // 只在需要访问共享数据时加锁    m.rulesMutex.RLock()    domainExists := m.    domainExceptions[domain]    m.rulesMutex.RUnlock()        if domainExists {        m.rulesMutex.RLock()        // 获取详细信息        m.rulesMutex.RUnlock()        return result    }        // 其他检查采用相同方式}

其他优化建议

1. DNS缓存优化

实现LRU缓存淘汰策略限制最大缓存大小 定期统计缓存命中率,调整缓存策略

2. WebSocket连接管理

实现连接池管理,限制最大连接数 添加连接心跳检测机制,及时清理无效连接

3. 并行查询优化

限制同时发起的上游查询数量,避免资源耗尽 实现超时控制,防止长时间阻塞

4. 正则表达式优化

预编译所有正则表达式规则 合并相似规则,减少正则表达式数量 使用更高效的规则匹配算法

总结

通过实施上述修复建议和优化方案可以有效解决DNS服务器的内存泄漏问题和CPU性能瓶颈提高系统稳定性和响应速度。建议优先修复IP地理位置缓存泄漏和域名检查函数性能问题这些是当前最严重的问题。