分布式锁实现限流

本文介绍了在高并发场景下如何使用Redis实现接口限流,特别是针对秒杀活动的限流策略。通过DistributedCurrentLimit注解和自定义锁,结合RedisDistributedCurrentLimit类,确保在并发访问超出设定上限时返回服务忙信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.限流锁的应用场景

同一时间接口访问量巨大,如秒杀,需要进行限流。

2.实现思路

用 CURRENT_LIMIT_+ 类名+方法名作为redis的key, value作为访问秒杀接口的人数。
用redis的计数器统计访问人数,每新增一个访问请求,计数器+1,当人数超过上限,提示服务忙,秒杀接口处理完之后,计数器-1。

3.主要组成

Dcl:限流注解,自定义锁注解,然后给需要限流的方法加上此注解
DistributedCurrentLimit:限流接口
RedisDistributedCurrentLimit:限流实现类
DistributedCurrentLimitAspect:切面类【核心】

自定义锁注解,利用切面给所有加注解的方法加分布式锁进行限流。

4.关键代码分析:

DistributedCurrentLimitAspect:用redis计时器算人头,人头达到上限就返回服务正忙

@Around("@annotation(com.nascent.ecrp.mall.common.distribute.Dcl)")
    public Object distributedLock(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
   
        if (request == null) {
   
            return proceedingJoinPoint.proceed();
        }
        MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
        Method method = methodSignature.getMethod();
        // 用CURRENT_LIMIT_+ 类名+方法名作为redis的key,统计调用此方法的用户数
        String lockKey = "CURRENT_LIMIT_" + method.getDeclaringClass().getName() + "." + method.getName();

        Dcl distributedKey = method.getAnnotation(Dcl.class);

        // 解析缓存key的后缀
        int keyIndex = distributedKey.keyIndex();
        String suffixKey = "";
        if (keyIndex > -1) {
   
            Object[] args = proceedingJoinPoint.getArgs();
            suffixKey += "_" + args[keyIndex];
        }
        lockKey += suffixKey;

        try {
   
        	// 每进来一个,redis的计数器+1
            Long incr = currentLimit.incr(lockKey);
            // 计数器数 > MAX_LIMIT,抛出异常,用户就不能继续访问接口了
            if (incr > MAX_LIMIT) {
   
                // currentLimit.decr(lockKey);
                throw new WmDefinitelyRuntimeException("前方道路拥挤,请稍后再试");
            }
            return proceedingJoinPoint.proceed();
        } catch (Throwable e) {
   
            throw new WmDefinitelyRuntimeException(e);
        } finally {
   
            currentLimit.decr(lockKey);
        }
    }

3.全部代码

Dcl

/**
 * 限流
 */
@Documented
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Dcl {
   

    /**
     * 缓存key后缀参数所在位置
     *
     * @return 位置
     */
    int keyIndex();
}

DistributedCurrentLimit

/**
 * 分布式限流
 */
public interface DistributedCurrentLimit{
   

    /**
     * 队列加1
     */
    Long incr(String lockKey);

    /**
     * 队列减一
     */
    Long decr(String lockKey);

RedisDistributedCurrentLimit

/**
 * redis 分布式锁
 */
@SuppressWarnings({
   "UnusedReturnValue", "NullableProblems", "unused", "RedundantThrows"})
@Component
public class RedisDistributedCurrentLimit implements DistributedCurrentLimit {
   


    /**
     * 缓存
     */
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值