php redis 利用zset 限流

15 篇文章 0 订阅

思路

1、限流需求中存在一个滑动的时间窗口,而zset的score值可以用来圈定时间窗口,窗口之外的数据都可以删除

2、zset的value需要是一个唯一的值,只需要保证唯一性即可

3、如果按照某个接口单位时间允许访问次数,那么key可以用接口路径,如果是限制单个用户那么key可以结合userId

4、缺点是内存有可能占用过多,如果用户60s之内请求超过100w次,那么就需要在zset中添加100w个值

<?php
class Limit
{
    public $redis = null;
    public  function __construct()
    {
           $this->redis = new Redis();
           $this->redis->connect("172.17.185.131",6379);
    }
    public function uuid()
    {
        $str="123456790abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        $uuid="";
        for($i=0;$i<10;$i++) {
            $uuid.=$str[mt_rand(0,strlen($str)-1)];
        }
        return $uuid;
    }
    public function setLimit($userId)
    {
        $time = time();
        $pipe=$this->redis->multi(2);
        $pipe->zRemRangeByRank("limit:{$userId}",0,$time-60*1000);
        $val = $this->uuid();
        $ret = $pipe->zAdd("limit:{$userId}",time(),$val);
        $pipe->zCard("limit:{$userId}");
        $ret = $pipe->exec();
        $pipe->close();
        return $ret;
    }
}
$redis = new Limit();
$ret= $redis->setLimit()[2];
if ($ret>1000) {
    return false;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值