Redis和lua脚本实现计数器封装

直接贴代码

<?php

namespace App\Cache\Redis\CommonResolve\Utils;


use App\Cache\Redis\CommonResolve\BaseResolve;
use Illuminate\Support\Carbon;

/**
 * 计数器类
 * Class Counter
 * @package App\Cache\Redis\CommonResolve\Utils
 */
class Counter 
{

    /**
     * @var int
     */
    public $expireTime = 3600;


    public $key = '';

    /**
     * @var int
     */
    public $limit = 10;

    /**
     * @var string
     */
    public $drive = 'redis';


    /**
     * @var string
     */
    public $timestamp = '';


    /**
     * @var string
     */
    public $startTimestamp = '';


    /**
     * @var string
     */
    public $endTimestamp = '';

    /**
     * @return string
     */
    public function getStartTimestamp(): string
    {
        return $this->startTimestamp;
    }

    /**
     * @param string $startTimestamp
     */
    public function setStartTimestamp(string $startTimestamp): void
    {
        $this->startTimestamp = $startTimestamp;
    }

    /**
     * @return string
     */
    public function getEndTimestamp(): string
    {
        return $this->endTimestamp;
    }

    /**
     * @param string $endTimestamp
     */
    public function setEndTimestamp(string $endTimestamp): void
    {
        $this->endTimestamp = $endTimestamp;
    }


    /**
     * @return string
     */
    public function getTimestamp(): string
    {
        return $this->timestamp ? $this->timestamp : Carbon::now()->timestamp;
    }

    /**
     * @param string $timestamp
     */
    public function setTimestamp(string $timestamp): void
    {
        $this->timestamp = $timestamp;
    }

    /**
     * @return string
     */
    public function getKey(): string
    {
        return $this->key;
    }

    /**
     * @param string $key
     */
    public function setKey(string $key): void
    {
        $this->key = $key;
    }


    /**
     * @return int
     */
    public function getExpireTime(): int
    {
        return $this->expireTime;
    }

    /**
     * @return int
     */
    public function getLimit(): int
    {
        return $this->limit;
    }

    /**
     * @param int $limit
     */
    public function setLimit(int $limit): void
    {
        $this->limit = $limit;
    }

    /**
     * @param int $expireTime
     */
    public function setExpireTime(int $expireTime): void
    {
        $this->expireTime = $expireTime;
    }

    /**
     * @return string
     */
    public function getDrive(): string
    {
        return $this->drive;
    }

    /**
     * @param string $drive
     */
    public function setDrive(string $drive): void
    {
        $this->drive = $drive;
    }


    /**
     * @return array
     * @throws \Exception
     */
    public function counter()
    {
         $sha = CustomRedis::script('load', 'counter.lua');
         list($bool, $count) =  CustomRedis::evalSha($sha, 1,
            $this->getKey(),
            $this->getLimit(),
            $this->getExpireTime(),
            $this->getTimestamp(),
            $this->getStartTimestamp(),
            $this->getEndTimestamp()
        );
       
        return [$bool, $count];
    }


}

couter.lua


local visitTimes = redis.call('incr', KEYS[1])

local logVisitKey = KEYS[1] .. ':log:visit';

if (visitTimes == 1) then
    redis.call('expire', KEYS[1], tonumber(ARGV[2]));
    redis.call('expire', logVisitKey, tonumber(ARGV[2]));
end


redis.call('zadd', logVisitKey,ARGV[3],visitTimes);


local logVisitCount = redis.call('zcard', logVisitKey);

if ARGV[4] and ARGV[5] then
    local logVisitRangeCount = redis.call('zcount',logVisitKey,ARGV[4],ARGV[5])
    logVisitCount = logVisitRangeCount;
end


if logVisitCount > tonumber(ARGV[1]) then
    return {0,logVisitCount}
else
    return {1,logVisitCount}
end




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝颜~岁月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值