使用Spring Boot实现限流

大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!

一、什么是限流?

在分布式系统中,限流是一种重要的技术手段,用于控制系统的请求流量,防止系统因请求过多而导致的资源耗尽、服务质量下降甚至崩溃。限流可以通过各种算法和工具来实现,例如基于令牌桶、漏桶算法等。

二、Spring Boot中的限流实现

在Spring Boot中,我们可以利用现成的库和工具来实现限流功能,下面介绍基于Guava和Redis两种常用的限流实现方式。

1. 基于Guava实现限流

Guava是Google开发的Java核心库,其中包含了许多实用的工具类和集合类,也包括了限流的支持。

首先,添加Guava依赖:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>30.1-jre</version> <!-- 使用最新版本 -->
</dependency>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

然后,编写限流的工具类:

package cn.juwatech.limiter;

import com.google.common.util.concurrent.RateLimiter;
import org.springframework.stereotype.Component;

@Component
public class GuavaRateLimiter {

    private RateLimiter rateLimiter = RateLimiter.create(10.0); // 每秒钟生成的令牌数

    public boolean tryAcquire() {
        return rateLimiter.tryAcquire();
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

在需要进行限流的地方注入 GuavaRateLimiter,并调用 tryAcquire 方法来尝试获取令牌,如果获取成功则处理请求,否则进行限流处理。

package cn.juwatech.controller;

import cn.juwatech.limiter.GuavaRateLimiter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class MyController {

    @Autowired
    private GuavaRateLimiter guavaRateLimiter;

    @GetMapping("/test")
    public String test() {
        if (guavaRateLimiter.tryAcquire()) {
            return "Hello, World!";
        } else {
            return "Rate limit exceeded!";
        }
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.

2. 基于Redis实现限流

Redis作为一款高性能的缓存和消息中间件,也常被用来实现分布式系统中的限流。

首先,添加Redis依赖和Spring Boot集成的依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

然后,配置Redis连接信息和限流工具:

package cn.juwatech.limiter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class RedisRateLimiter {

    private static final String RATE_LIMIT_KEY = "rate_limit_key";
    private static final long LIMIT = 10; // 限流阈值
    private static final long TIMEOUT = 1; // 时间窗口

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public boolean tryAcquire() {
        Long count = redisTemplate.opsForValue().increment(RATE_LIMIT_KEY, 1);
        if (count != null && count <= LIMIT) {
            redisTemplate.expire(RATE_LIMIT_KEY, TIMEOUT, TimeUnit.SECONDS);
            return true;
        } else {
            return false;
        }
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.

在需要进行限流的地方注入 RedisRateLimiter,并调用 tryAcquire 方法来尝试获取令牌,实现限流逻辑。

package cn.juwatech.controller;

import cn.juwatech.limiter.RedisRateLimiter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class MyController {

    @Autowired
    private RedisRateLimiter redisRateLimiter;

    @GetMapping("/test")
    public String test() {
        if (redisRateLimiter.tryAcquire()) {
            return "Hello, World!";
        } else {
            return "Rate limit exceeded!";
        }
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.

三、总结

通过以上示例,我们实现了基于Guava和Redis两种不同的限流方式。在实际应用中,根据具体的场景和需求选择合适的限流算法和工具,来保护系统免受高并发请求的影响。

著作权归聚娃科技微赚淘客系统开发者团队,转载请注明出处!