废话不多说直接上代码:

1.依赖:

<dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>31.1-jre</version>
        </dependency>

2.配置类注册bean:

package com.hmdp.config;

import com.google.common.util.concurrent.RateLimiter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.TimeUnit;



@Configuration
public class RateLimiterConfig {
    
    @Bean("seckillRateLimiter")
    public RateLimiter seckillRateLimiter() {
        // 秒杀接口每秒放行 50 个请求(根据实际压测结果调整)
        // 预热模式:3秒内逐步达到稳定速率,保护冷启动
        return RateLimiter.create(50);
    }
}

3.拦截器拦截接口请求:

package com.hmdp.utils;

import com.google.common.util.concurrent.RateLimiter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class RateLimitInterceptor implements HandlerInterceptor {
    
    private final RateLimiter seckillRateLimiter;
    
    public RateLimitInterceptor(@Qualifier("seckillRateLimiter") RateLimiter rateLimiter) {
        this.seckillRateLimiter = rateLimiter;
    }
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
                            Object handler) throws Exception {
        // 对秒杀下单接口进行限流判断
        if (request.getRequestURI().contains("/voucher-order/seckill/")) {
            // 非阻塞式获取令牌,立刻返回成功/失败
            if (!seckillRateLimiter.tryAcquire()) {
                response.setStatus(429);
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write("{\"code\":429,\"msg\":\"当前请求人数过多,请稍后重试\"}");
                return false;
            }} else {

            return true;

        }
        return true;
    }
}

4.注册拦截器添加白名单:

registry.addInterceptor(rateLimitInterceptor)
                .addPathPatterns("/voucher-order/seckill/**");

5.apifox做简单压测

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐