博客限制进入系统请求 de 设计方案

为了限制博客系统的请求数量,可以采用以下限流的设计方案:

  1. 令牌桶算法:这是一种经典的限流算法,它可以让请求在桶中拿取令牌进行处理。每个令牌代表一个处理请求的许可,而令牌桶的大小则代表了系统的并发处理能力。当桶内没有令牌时,请求将会被拒绝或等待更多的令牌,以此来保证系统的并发能力。具体实现可以在令牌桶中设定令牌密度、桶的大小、超时时间等参数。

  2. 漏桶算法:这种算法可以通过一个容量固定、常量速率出水的漏桶存放请求。如果请求的速率超过了出水的速率,则漏桶会被填满,请求就会被拒绝。漏桶算法可以平滑流量,但是不能一段时间内限制请求的总数。

  3. 计数器算法:在请求过程中,对请求进行计数。在设定的时间窗口内,如果请求计数超过了设定的阈值,则限制请求。这种算法比较简单,但是可能会导致短时间内的流量瞬间暴增。

  4. 计数器算法 + 滑动窗口:在计数器算法的基础上,加入滑动窗口的概念。通过对时间窗口进行切分,并在每个时间窗口内限制请求计数,可以有效平滑流量,避免短时间内流量暴增。

  5. 令牌桶算法 + 黑白名单:可以将令牌桶算法与黑白名单功能结合起来。根据IP地址、用户ID等信息来判断请求是否被限制,例如对于一些低风险的用户或者访问者,设置更高的调用频率限制。

在以上方案中,需要注意的是,在限流的过程中,应该要合理设置参数,谨慎评估和选择方案,以兼顾系统的安全和性能。


Spring Boot + Redis架构

限流是一种常见的高并发系统的解决方案。在Spring Boot + Redis的架构设计中,可以通过以下步骤进行请求限流:

1.在Redis中使用计数器存储每个请求的数量。可以为每个IP或每个API分别计数。

2.创建一个Filter,并将其注入过滤器链中。

3.每当收到来自客户端的请求时,过滤器将从Redis中获取当前请求计数器中存储的请求数量。

4.如果请求数量已经超过了预先设置的限制,则返回“请求过多”的HTTP 429状态码,否则将请求计数器增加1,然后将请求传递到下一个过滤器或处理程序中。

5.在Redis中使用过期时间,以避免过多的计数器在内存中存储而导致问题。

下面是一个使用Spring Boot和Redis实现请求限流的示例:

1.添加Redis依赖

pom.xml文件中添加以下依赖项:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2.创建计数器存储

在Redis中为每个请求路径创建一个计数器。在一个类中实现RedisRequestCounter类,该类封装了与Redis交互的所有方法。

@Component
public class RedisRequestCounter {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public long incrementAndGet(String key) {
        return redisTemplate.opsForValue().increment(key, 1);
    }

    public void expire(String key, int timeout) {
        redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
    }

    public long getCount(String key) {
        String count = redisTemplate.opsForValue().get(key);
        return count == null ? 0 : Long.parseLong(count);
    }
}

3.创建过滤器

创建一个过滤器,以对来自客户端的请求进行计数和限制。在一个类中实现RequestLimitFilter类。

我们假设请求路径是/api/**,我们将为每个IP地址设置最大并发数为100:

@Component
public class RequestLimitFilter extends OncePerRequestFilter {

    private static final Logger log = LoggerFactory.getLogger(RequestLimitFilter.class);

    @Autowired
    private RedisRequestCounter redisRequestCounter;

    @Override
    protected void doFilterInternal(HttpServletRequest httpRequest, HttpServletResponse httpResponse,
                                    FilterChain filterChain) throws ServletException, IOException {

        final String ipAddress = getIpAddress(httpRequest);
        final String api = httpRequest.getRequestURI();

        //仅对API路径进行限流
        if (api.startsWith("/api/")) {

            final String key = String.join("_", "request_count", api, ipAddress);
            final int limit = 100;

            final long count = redisRequestCounter.incrementAndGet(key);
            log.debug("Request Count Key {} count {}", key, count);

            if (count > limit) {
                //请求过多
                httpResponse.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
                httpResponse.getWriter().write("Too many requests");
                return;
            } else {
                //增加过期时间
                redisRequestCounter.expire(key, 60);
            }

        }
        filterChain.doFilter(httpRequest, httpResponse);
    }

    /**
     * 获取IP地址
     *
     * @param request
     * @return
     */
    private String getIpAddress(HttpServletRequest request) {
        final String xff = request.getHeader("X-Forwarded-For");
        if (xff != null) {
            return xff.split(",")[0].trim();
        }
        return request.getRemoteAddr();
    }
}

4.将过滤器添加到Spring Boot应用程序中

在你的Spring Boot应用程序中注册过滤器。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private RequestLimitFilter requestLimitFilter;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(requestLimitFilter);
    }

}

5.测试

现在,启动你的应用程序,发起数量超过100的请求。你将看到返回HTTP 429状态码,提示你已超过请求限制。

在本示例中,我们使用Redis存储计数器和过期时间来对请求进行限流。这是一种简单而有效的方法,可以有效地防止DDoS攻击和其他恶意请求。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值