redis:使用go-redis通过过期时间实现计数器,防止刷单

过期时间

工作原理

当对Redis中的一个键设置过期时间时,键的过期时间会被存储为一个绝对的Unix时间戳。这样做的目的在于,即使Redis服务器宕机了一段时间,这个时间戳也会被持久化到RDB文件中,这个时间戳依然会继续起作用。

在一个键过期之后,当客户端试图访问已经过期键时,redis会立即将其从内存中删除。redis这种删除键的方式叫做被动过期。对于哪些已经过期而且永远不会再访问的键,redis会定期运行一个基于概率的算法来进行主动删除。

应用场景

  • 限时的优惠活动信息
  • 网站数据缓存(对于一些需要定时更新的数据,例如:积分排行榜)
  • 手机验证码
  • 限制网站访客访问频率(例如:1分钟最多访问10次)
    等等

实践

设计

一个IP请求,限制10秒内请求总数为200次,超过200次就等待,等下一秒。需要存储的信息是

  • 用户IP 【作为key】
  • 访问次数 【每次访问就Incr】

这里我使用string作为存储数据的结构,同时设置键的过期时间为1s。

127.0.0.1:6379> get 192.168.0.1
(nil)
127.0.0.1:6379> incr 192.168.0.1
(integer) 1
127.0.0.1:6379> get 192.168.0.1
"1"
127.0.0.1:6379> incr 192.168.0.1
(integer) 2
127.0.0.1:6379> get 192.168.0.1
"2"
127.0.0.1:6379> exists 192.168.0.1   -- 查看键是否存在
(integer) 1
127.0.0.1:6379> expire 192.168.0.1 5  --设置键的过期时间
(integer) 1
127.0.0.1:6379> ttl 192.168.0.1      --在键过期前查看剩余时间
(integer) 2
如果键存在但是没有设置过期时间,则ttl命令会返回-1.如果键不存在,那么ttl会返回-2

127.0.0.1:6379> persist 192.168.0.1  -- 让键变成持久的键
(integer) 1

代码

package main

import (
	"fmt"
	"github.com/go-redis/redis"
	"strconv"
)

func createClient() *redis.Client {
	client := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})

	// 通过 cient.Ping() 来检查是否成功连接到了 redis 服务器
	_, err := client.Ping().Result()
	if err != nil{
		panic(err)
	}

	return client
}

func count_string(client *redis.Client, userip string){
	val, err := client.Exists(userip).Result()
	if err != nil{
		panic(err)
	}

	if val == 0{  // no exists
		_, err := client.Incr(userip).Result()
		if err != nil{
			panic(err)
		}


		_, err = client.Expire(userip, 5 * 1000 * 1000 * 1000 * 10).Result() //设置键的过期时间  10s
		if err != nil{
			panic(err)
		}

	}else{  //exist
		count, err := client.Get(userip).Result()
		if err != nil{
			panic(err)
		}

        temp , _:= strconv.Atoi(count)
		fmt.Println(temp)

		if temp < 200{
			_, err = client.Incr(userip).Result()
			if err != nil{
				panic(err)
			}
		}else{
			fmt.Println("不允许访问")
		}

	}
}


func main(){
	client := createClient()
	fmt.Println(client)

	count_string(client, "192.168.0.1")
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值