Skip to content
This repository was archived by the owner on Nov 5, 2024. It is now read-only.

Commit 41248be

Browse files
committed
限制各个内存缓存的条目数量,防止OOM
1 parent 2874c7b commit 41248be

10 files changed

Lines changed: 55 additions & 19 deletions

File tree

teageo/utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"strings"
1010
)
1111

12-
var ip2cityGrid = teamemory.NewGrid(32)
12+
var ip2cityGrid = teamemory.NewGrid(32, teamemory.NewLimitCountOpt(100_0000))
1313

1414
// 加载Geo-City数据库
1515
func SetupDB() {

tealogs/accesslogs/access_log.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
"time"
2121
)
2222

23-
var userAgentGrid = teamemory.NewGrid(32)
23+
var userAgentGrid = teamemory.NewGrid(32, teamemory.NewLimitCountOpt(100_0000))
2424
var charsetReg = regexp.MustCompile("(?i)charset\\s*=\\s*([\\w-]+)")
2525
var headerReg = regexp.MustCompile("([A-Z])")
2626

teamemory/cell.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import (
77
)
88

99
type Cell struct {
10-
LimitSize int64
10+
LimitSize int64
11+
LimitCount int
1112

1213
mapping map[uint64]*Item // key => item
1314
list *List // { item1, item2, ... }
@@ -37,6 +38,12 @@ func (this *Cell) Write(hashKey uint64, item *Item) {
3738
}
3839
}
3940

41+
// limit count
42+
if this.LimitCount > 0 && len(this.mapping) >= this.LimitCount {
43+
this.locker.Unlock()
44+
return
45+
}
46+
4047
// trim memory
4148
size := item.Size()
4249
shouldTrim := false

teamemory/grid.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ type Grid struct {
2424

2525
gzipLevel int
2626

27-
limitSize int64
27+
limitSize int64
28+
limitCount int
2829
}
2930

3031
func NewGrid(countCells int, opt ...interface{}) *Grid {
@@ -38,6 +39,8 @@ func NewGrid(countCells int, opt ...interface{}) *Grid {
3839
grid.gzipLevel = x.Level
3940
case *LimitSizeOpt:
4041
grid.limitSize = x.Size
42+
case *LimitCountOpt:
43+
grid.limitCount = x.Count
4144
case *RecycleIntervalOpt:
4245
grid.recycleInterval = x.Interval
4346
}
@@ -52,6 +55,8 @@ func NewGrid(countCells int, opt ...interface{}) *Grid {
5255
for i := 0; i < countCells; i++ {
5356
cell := NewCell()
5457
cell.LimitSize = int64(math.Floor(float64(grid.limitSize) / float64(countCells)))
58+
cell.LimitCount = int(math.Floor(float64(grid.limitCount)) / float64(countCells))
59+
5560
cells = append(cells, cell)
5661
}
5762
grid.cells = cells

teamemory/grid_test.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func TestMemoryGrid_Write(t *testing.T) {
2727
grid.Delete([]byte("abc"))
2828
t.Log(grid.Read([]byte("abc")))
2929

30-
for i := 0; i < 100; i ++ {
30+
for i := 0; i < 100; i++ {
3131
grid.WriteInt64([]byte(fmt.Sprintf("%d", i)), 123, 1)
3232
}
3333

@@ -45,6 +45,14 @@ func TestMemoryGrid_Write(t *testing.T) {
4545
grid.Destroy()
4646
}
4747

48+
func TestMemoryGrid_Write_LimitCount(t *testing.T) {
49+
grid := NewGrid(2, NewLimitCountOpt(10))
50+
for i := 0; i < 100; i++ {
51+
grid.WriteInt64([]byte(strconv.Itoa(i)), int64(i), 30)
52+
}
53+
t.Log(grid.Stat().CountItems, "items")
54+
}
55+
4856
func TestMemoryGrid_Compress(t *testing.T) {
4957
grid := NewGrid(5, NewCompressOpt(1))
5058
grid.WriteString([]byte("hello"), strings.Repeat("abcd", 10240), 30)
@@ -54,7 +62,7 @@ func TestMemoryGrid_Compress(t *testing.T) {
5462

5563
func BenchmarkMemoryGrid_Performance(b *testing.B) {
5664
grid := NewGrid(1024)
57-
for i := 0; i < b.N; i ++ {
65+
for i := 0; i < b.N; i++ {
5866
grid.WriteInt64([]byte("key:"+strconv.Itoa(i)), int64(i), 3600)
5967
}
6068
}
@@ -68,7 +76,7 @@ func TestMemoryGrid_Performance(t *testing.T) {
6876

6977
s := []byte(strings.Repeat("abcd", 10*1024))
7078

71-
for i := 0; i < 100000; i ++ {
79+
for i := 0; i < 100000; i++ {
7280
grid.WriteBytes([]byte(fmt.Sprintf("key:%d_%d", i, 1)), s, 3600)
7381
item := grid.Read([]byte(fmt.Sprintf("key:%d_%d", i, 1)))
7482
if item != nil {
@@ -97,10 +105,10 @@ func TestMemoryGrid_Performance_Concurrent(t *testing.T) {
97105
wg := sync.WaitGroup{}
98106
wg.Add(runtime.NumCPU())
99107

100-
for c := 0; c < runtime.NumCPU(); c ++ {
108+
for c := 0; c < runtime.NumCPU(); c++ {
101109
go func(c int) {
102110
defer wg.Done()
103-
for i := 0; i < 50000; i ++ {
111+
for i := 0; i < 50000; i++ {
104112
grid.WriteBytes([]byte(fmt.Sprintf("key:%d_%d", i, c)), s, 3600)
105113
item := grid.Read([]byte(fmt.Sprintf("key:%d_%d", i, c)))
106114
if item != nil {
@@ -128,7 +136,7 @@ func TestMemoryGrid_CompressPerformance(t *testing.T) {
128136
now := time.Now()
129137
data := []byte(strings.Repeat("abcd", 1024))
130138

131-
for i := 0; i < 100000; i ++ {
139+
for i := 0; i < 100000; i++ {
132140
grid.WriteBytes([]byte(fmt.Sprintf("key:%d", i)), data, 3600)
133141
item := grid.Read([]byte(fmt.Sprintf("key:%d", i+100)))
134142
if item != nil {

teamemory/item.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"unsafe"
1010
)
1111

12-
type ItemType = int
12+
type ItemType = int8
1313

1414
const (
1515
ItemInt64 = 1
@@ -33,6 +33,8 @@ type Item struct {
3333
// linked list
3434
Prev *Item
3535
Next *Item
36+
37+
size int64
3638
}
3739

3840
func NewItem(key []byte, dataType ItemType) *Item {
@@ -79,5 +81,8 @@ func (this *Item) String() string {
7981
}
8082

8183
func (this *Item) Size() int64 {
82-
return int64(int(unsafe.Sizeof(*this)) + len(this.Key) + len(this.ValueBytes))
84+
if this.size == 0 {
85+
this.size = int64(int(unsafe.Sizeof(*this)) + len(this.Key) + len(this.ValueBytes))
86+
}
87+
return this.size
8388
}

teamemory/opt_limit_count.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package teamemory
2+
3+
type LimitCountOpt struct {
4+
Count int
5+
}
6+
7+
func NewLimitCountOpt(count int) *LimitCountOpt {
8+
return &LimitCountOpt{
9+
Count: count,
10+
}
11+
}

teawaf/checkpoints/cc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func (this *CCCheckpoint) Start() {
2828
if this.grid != nil {
2929
this.grid.Destroy()
3030
}
31-
this.grid = teamemory.NewGrid(32)
31+
this.grid = teamemory.NewGrid(32, teamemory.NewLimitCountOpt(1000_0000))
3232
}
3333

3434
func (this *CCCheckpoint) RequestValue(req *requests.Request, param string, options map[string]string) (value interface{}, sysErr error, userErr error) {

teawaf/utils/utils.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"strconv"
1010
)
1111

12-
var grid = teamemory.NewGrid(32)
12+
var grid = teamemory.NewGrid(32, teamemory.NewLimitCountOpt(1000_0000))
1313

1414
// 正则表达式匹配字符串,并缓存结果
1515
func MatchStringCache(regex *regexp.Regexp, s string) bool {
@@ -21,9 +21,9 @@ func MatchStringCache(regex *regexp.Regexp, s string) bool {
2121
}
2222
b := regex.MatchString(s)
2323
if b {
24-
grid.WriteInt64(key, 1, 3600)
24+
grid.WriteInt64(key, 1, 1800)
2525
} else {
26-
grid.WriteInt64(key, 0, 3600)
26+
grid.WriteInt64(key, 0, 1800)
2727
}
2828
return b
2929
}
@@ -38,9 +38,9 @@ func MatchBytesCache(regex *regexp.Regexp, byteSlice []byte) bool {
3838
}
3939
b := regex.Match(byteSlice)
4040
if b {
41-
grid.WriteInt64(key, 1, 3600)
41+
grid.WriteInt64(key, 1, 1800)
4242
} else {
43-
grid.WriteInt64(key, 0, 3600)
43+
grid.WriteInt64(key, 0, 1800)
4444
}
4545
return b
4646
}

teaweb/actions/default/agents/board/scripts/engine.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222
"time"
2323
)
2424

25-
var engineCache = teamemory.NewGrid(1)
25+
var engineCache = teamemory.NewGrid(1, teamemory.NewLimitCountOpt(1000))
2626
var dayReg = regexp.MustCompile(`^(\d+)-(\d+)-(\d+)$`)
2727

2828
// 脚本引擎

0 commit comments

Comments
 (0)