概要

  • 在项目中引入Guava相关包
  • 创建拦截器
  • 添加拦截器
  • 测试

在使用SpringBoot做接口访问如何做接口的限流,这里我们可以使用google的Guava包来实现.

1.在项目中引入Guava相关包

1
2
3
4
5
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.5-jre</version>
</dependency>

2.创建拦截器

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class AuthInterceptor extends HandlerInterceptorAdapter {

enum LimiterTypeEnum {
DROP,//丢弃
WAIT //等待
}


//限流器
private RateLimiter rateLimiter;
//限流类型
private LimiterTypeEnum limiterType;

/**
* @param permitsPerSecond 限流量 (每秒处理量)
* @param limiterType 限流类型
*/
public AuthInterceptor(int permitsPerSecond, LimiterTypeEnum limiterType) {
this.rateLimiter = RateLimiter.create(permitsPerSecond);
this.limiterType = limiterType;
}

/**
* @param permitsPerSecond 每秒新增的令牌数(这个是平滑增长,有一个预热过程)
* @param limiterType 限流类型
*/
public AuthInterceptor(double permitsPerSecond, LimiterTypeEnum limiterType) {
this.rateLimiter = RateLimiter.create(permitsPerSecond, 1, TimeUnit.SECONDS);
this.limiterType = limiterType;
}

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (Objects.equals(limiterType, LimiterTypeEnum.DROP)) {
return rateLimiter.tryAcquire(); //false为被限流
} else {
rateLimiter.acquire();//一直等待,直到拿到令牌
return true;
}
}

}

3.添加拦截器

1
2
3
4
5
6
7
8
9
@Configuration
public class AuthHandlerAdapter extends WebMvcConfigurerAdapter {

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor(10, AuthInterceptor.LimiterTypeEnum.DROP))
.addPathPatterns("/*");
}
}

4.测试

  • controller
    1
    2
    3
    4
    5
    6
    7
    8
    @RestController
    public class TestController {

    @GetMapping
    public String TestGetString() {
    return "爱生活,爱java";
    }
    }
  • 并发请求
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public class RequestTest {
    public static void main(String[] args) {
    HttpClient httpClient = new HttpClient("http://127.0.0.1:8080", 2000, 2000);
    IntStream.range(0, 1000).forEach(value -> {
    testSend(httpClient);
    try {
    TimeUnit.MILLISECONDS.sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }

    });

    }
    public static void testSend(HttpClient httpClient) {
    try {
    httpClient.sendGet("UTF-8");
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }