diff --git a/internal/caches/storage_file.go b/internal/caches/storage_file.go index 56b418c..e99d04c 100644 --- a/internal/caches/storage_file.go +++ b/internal/caches/storage_file.go @@ -22,6 +22,7 @@ import ( "github.com/iwind/TeaGo/rands" "github.com/iwind/TeaGo/types" stringutil "github.com/iwind/TeaGo/utils/string" + "github.com/shirou/gopsutil/v3/load" "math" "os" "path/filepath" @@ -1025,8 +1026,15 @@ func (this *FileStorage) purgeLoop() { var times = 1 // 空闲时间多清理 - if utils.SharedFreeHoursManager.IsFreeHour() { - times = 5 + systemLoad, _ := load.Avg() + if systemLoad != nil { + if systemLoad.Load5 < 2 { + times = 5 + } else if systemLoad.Load5 < 3 { + times = 3 + } else if systemLoad.Load5 < 5 { + times = 2 + } } // 处于LFU阈值时,多清理 diff --git a/internal/utils/free_hours_manager.go b/internal/utils/free_hours_manager.go deleted file mode 100644 index 693372a..0000000 --- a/internal/utils/free_hours_manager.go +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. - -package utils - -import ( - teaconst "github.com/TeaOSLab/EdgeNode/internal/const" - "github.com/TeaOSLab/EdgeNode/internal/events" - "github.com/TeaOSLab/EdgeNode/internal/goman" - "sort" - "sync" - "sync/atomic" - "time" -) - -var SharedFreeHoursManager = NewFreeHoursManager() - -func init() { - if !teaconst.IsMain { - return - } - - events.On(events.EventLoaded, func() { - goman.New(func() { - SharedFreeHoursManager.Start() - }) - }) - events.OnClose(func() { - SharedFreeHoursManager.Stop() - }) -} - -// FreeHoursManager 计算节点空闲时间 -// 以便于我们在空闲时间执行高强度的任务,如清理缓存等 -type FreeHoursManager struct { - dayTrafficMap map[int][24]uint64 // day => [ traffic bytes ] - lastBytes uint64 - - freeHours []int - count int - - locker sync.Mutex - ticker *time.Ticker -} - -func NewFreeHoursManager() *FreeHoursManager { - return &FreeHoursManager{dayTrafficMap: map[int][24]uint64{}, count: 3} -} - -func (this *FreeHoursManager) Start() { - this.ticker = time.NewTicker(30 * time.Minute) - for range this.ticker.C { - this.Update(atomic.LoadUint64(&teaconst.InTrafficBytes)) - } -} - -func (this *FreeHoursManager) Update(bytes uint64) { - if this.count <= 0 { - this.count = 3 - } - - if this.lastBytes == 0 { - this.lastBytes = bytes - } else { - // 记录流量 - var deltaBytes = bytes - this.lastBytes - var now = time.Now() - var day = now.Day() - var hour = now.Hour() - traffic, ok := this.dayTrafficMap[day] - if ok { - traffic[hour] += deltaBytes - } else { - var traffic = [24]uint64{} - traffic[hour] += deltaBytes - this.dayTrafficMap[day] = traffic - } - - this.lastBytes = bytes - - // 计算空闲时间 - var result = [24]uint64{} - var hasData = false - for trafficDay, trafficArray := range this.dayTrafficMap { - // 当天的不算 - if trafficDay == day { - continue - } - - // 查看最近5天的 - if (day > trafficDay && day-trafficDay <= 5) || (day < trafficDay && trafficDay-day >= 26) { - var weights = this.sortUintArrayWeights(trafficArray) - for k, v := range weights { - result[k] += v - } - hasData = true - } - } - if hasData { - var freeHours = this.sortUintArrayIndexes(result) - this.locker.Lock() - this.freeHours = freeHours[:this.count] // 取前N个小时作为空闲时间 - this.locker.Unlock() - } - } -} - -func (this *FreeHoursManager) IsFreeHour() bool { - this.locker.Lock() - defer this.locker.Unlock() - - if len(this.freeHours) == 0 { - return false - } - - var hour = time.Now().Hour() - for _, h := range this.freeHours { - if h == hour { - return true - } - } - return false -} - -func (this *FreeHoursManager) Stop() { - if this.ticker != nil { - this.ticker.Stop() - } -} - -// 对数组进行排序,并返回权重 -func (this *FreeHoursManager) sortUintArrayWeights(arr [24]uint64) [24]uint64 { - var l = []map[string]interface{}{} - for k, v := range arr { - l = append(l, map[string]interface{}{ - "k": k, - "v": v, - }) - } - sort.Slice(l, func(i, j int) bool { - var m1 = l[i] - var v1 = m1["v"].(uint64) - - var m2 = l[j] - var v2 = m2["v"].(uint64) - - return v1 < v2 - }) - - var result = [24]uint64{} - for k, v := range l { - if k < this.count { - k = 0 - } else { - k = 1 - } - result[v["k"].(int)] = v["v"].(uint64) - } - - return result -} - -// 对数组进行排序,并返回索引 -func (this *FreeHoursManager) sortUintArrayIndexes(arr [24]uint64) [24]int { - var l = []map[string]interface{}{} - for k, v := range arr { - l = append(l, map[string]interface{}{ - "k": k, - "v": v, - }) - } - sort.Slice(l, func(i, j int) bool { - var m1 = l[i] - var v1 = m1["v"].(uint64) - - var m2 = l[j] - var v2 = m2["v"].(uint64) - - return v1 < v2 - }) - - var result = [24]int{} - var i = 0 - for _, v := range l { - result[i] = v["k"].(int) - i++ - } - - return result -} diff --git a/internal/utils/free_hours_manager_test.go b/internal/utils/free_hours_manager_test.go deleted file mode 100644 index 777f0e1..0000000 --- a/internal/utils/free_hours_manager_test.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. - -package utils - -import ( - "testing" - "time" -) - -func TestFreeHoursManager_Update(t *testing.T) { - var manager = NewFreeHoursManager() - manager.Update(111) - - manager.dayTrafficMap[1] = [24]uint64{1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1} - manager.dayTrafficMap[2] = [24]uint64{0, 0, 1, 0, 1, 1, 1, 0, 0} - manager.dayTrafficMap[3] = [24]uint64{0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1} - manager.dayTrafficMap[4] = [24]uint64{0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1} - manager.dayTrafficMap[5] = [24]uint64{0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1} - manager.dayTrafficMap[6] = [24]uint64{0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1} - manager.dayTrafficMap[7] = [24]uint64{} - manager.dayTrafficMap[8] = [24]uint64{} - manager.dayTrafficMap[9] = [24]uint64{} - manager.dayTrafficMap[10] = [24]uint64{1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} - manager.dayTrafficMap[11] = [24]uint64{1} - manager.dayTrafficMap[12] = [24]uint64{1} - manager.dayTrafficMap[13] = [24]uint64{1} - manager.dayTrafficMap[14] = [24]uint64{} - manager.dayTrafficMap[15] = [24]uint64{} - manager.dayTrafficMap[16] = [24]uint64{} - manager.dayTrafficMap[25] = [24]uint64{} - manager.dayTrafficMap[26] = [24]uint64{} - manager.dayTrafficMap[27] = [24]uint64{} - manager.dayTrafficMap[28] = [24]uint64{} - manager.dayTrafficMap[29] = [24]uint64{} - manager.dayTrafficMap[30] = [24]uint64{} - manager.dayTrafficMap[31] = [24]uint64{} - - var before = time.Now() - manager.Update(222) - t.Log(manager.freeHours) - t.Log(manager.IsFreeHour()) - t.Log(time.Since(before).Seconds()*1000, "ms") -} - -func TestFreeHoursManager_SortArray(t *testing.T) { - var manager = NewFreeHoursManager() - t.Log(manager.sortUintArrayWeights([24]uint64{0, 1, 2, 3, 4, 5, 6, 7, 8, 109, 10, 11, 12, 130, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23})) - t.Log(manager.sortUintArrayIndexes([24]uint64{1, 2, 3, 5, 4, 0, 100})) -}