代码片段如下:

package utils

import (
	"time"

	"base.domain.com/global"
	"github.com/go-redis/redis"
)

// Limiter 定义属性
type Limiter struct {
	redisClient *redis.Client
}

// NewLimiter 创建新的limiter
func NewLimiter() *Limiter {
	ipConfig := global.GetConfig("ip")
	redis := NewRedis(ipConfig.GetString("IP_FREQUENCE_LIMIT_REDIS"))
	return &Limiter{redisClient: redis.Client}
}

// Allow 通过redis的value判断第几次访问并返回是否允许访问
func (l *Limiter) Allow(key string, visitNumber int64, visitPeriod time.Duration) bool {
	currentLength := l.redisClient.LLen(key).Val()
	if currentLength >= visitNumber {
		return false
	}

	if v := l.redisClient.Exists(key).Val(); v == 0 {
		pipe := l.redisClient.TxPipeline()
		pipe.RPush(key, key)
		pipe.Expire(key, visitPeriod)
		_, _ = pipe.Exec()
	} else {
		l.redisClient.RPushX(key, key)
	}

	return true
}

// DuplicateSubmit 限制表单重复提交
func (l *Limiter) DuplicateSubmit(key string, visitNumber int64, visitPeriod time.Duration) bool {
	return l.redisClient.SetNX(key, visitNumber, visitPeriod).Val()
}

有一定的缺陷哈,慎用。。。

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐