频限类并发安全的map

pull/29/head
taoshihan1991 3 years ago
parent 04f4b0383f
commit 07b9a1ba9c

@ -1,7 +1,7 @@
FROM golang:alpine
WORKDIR /app
COPY . /app
ENV GOPROXY https://mirrors.aliyun.com/goproxy
RUN go env -w GO111MODULE=on && go env -w GOPROXY=https://goproxy.cn,direct
VOLUME ["/app/config"]
RUN go build go-fly.go
EXPOSE 8081

@ -2,10 +2,31 @@ package tools
import (
"log"
"sync"
"time"
)
var LimitQueue map[string][]int64
type LimitQueeMap struct {
sync.RWMutex
LimitQueue map[string][]int64
}
func (l *LimitQueeMap) readMap(key string) ([]int64, bool) {
l.RLock()
value, ok := l.LimitQueue[key]
l.RUnlock()
return value, ok
}
func (l *LimitQueeMap) writeMap(key string, value []int64) {
l.Lock()
l.LimitQueue[key] = value
l.Unlock()
}
var LimitQueue = &LimitQueeMap{
LimitQueue: make(map[string][]int64),
}
var ok bool
func NewLimitQueue() {
@ -15,7 +36,7 @@ func cleanLimitQueue() {
go func() {
for {
log.Println("cleanLimitQueue start...")
LimitQueue = nil
LimitQueue.LimitQueue = nil
now := time.Now()
// 计算下一个零点
next := now.Add(time.Hour * 24)
@ -29,26 +50,28 @@ func cleanLimitQueue() {
//单机时间滑动窗口限流法
func LimitFreqSingle(queueName string, count uint, timeWindow int64) bool {
currTime := time.Now().Unix()
if LimitQueue == nil {
LimitQueue = make(map[string][]int64)
if LimitQueue.LimitQueue == nil {
LimitQueue.LimitQueue = make(map[string][]int64)
}
if _, ok = LimitQueue[queueName]; !ok {
LimitQueue[queueName] = make([]int64, 0)
if _, ok = LimitQueue.readMap(queueName); !ok {
LimitQueue.writeMap(queueName, make([]int64, 0))
return true
}
q, _ := LimitQueue.readMap(queueName)
//队列未满
if uint(len(LimitQueue[queueName])) < count {
LimitQueue[queueName] = append(LimitQueue[queueName], currTime)
if uint(len(q)) < count {
LimitQueue.writeMap(queueName, append(q, currTime))
return true
}
//队列满了,取出最早访问的时间
earlyTime := LimitQueue[queueName][0]
earlyTime := q[0]
//说明最早期的时间还在时间窗口内,还没过期,所以不允许通过
if currTime-earlyTime <= timeWindow {
return false
} else {
//说明最早期的访问应该过期了,去掉最早期的
LimitQueue[queueName] = LimitQueue[queueName][1:]
LimitQueue[queueName] = append(LimitQueue[queueName], currTime)
q = q[1:]
LimitQueue.writeMap(queueName, append(q, currTime))
}
return true
}

Loading…
Cancel
Save