# confine
**Repository Path**: itCjb/confine
## Basic Information
- **Project Name**: confine
- **Description**: 轻量限流控制组件-confine
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 15
- **Forks**: 1
- **Created**: 2021-03-18
- **Last Updated**: 2021-03-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 轻量限流控制组件-confine
## confine-client使用教程
confine-client组件纯api手动进行限流操作,使用前请引入此依赖
```java
icu.funkye
confine-client
1.0.0
```
使用方式:
注:使用confine-spring-boot-starter时可直接通过注解来等价与以下使用方法
```java
@RequestMapping("/test")
@ResponseBody
public String test(@ModelAttribute Test test) throws InterruptedException {
try {
//会通过此资源名找到对应的资源构造对象,自动进行判断当前是否需要限流
ConfineFilter.entry(资源名称,可以为类名+函数+入参来命名);
// business
return "ok";
}catch (ConfineException e) {
//当抛出此异常的时候,就是触发限流,可自行编写failback逻辑
}
}
public void init(){
//默认根据tps限流,如果有填写限流rt,如rt为1000,那么就是1秒,1分钟内此资源被请求的平均rt高于此阈值则进行限流,若低于根据tps进行判断是否限流
RateLimiterFactory.put(资源名称,可以为类名+函数+入参来命名, 对此资源限制的tps, 限流rt);
}
```
入口限流使用示例:
注:此功能强依赖spring组件,当然你也可以通过使用api方式自己写入口限流策略,使用confine-spring-boot-starter时自动装配入口限流
```java
private static volatile ScheduledThreadPoolExecutor EXECUTOR;
@Bean
public ConfineFailHandle confineFailHandle() {
//此熔断处理器可实现ConfineFailHandle接口自定义处理熔断时的逻辑
return new DefaultConfineFailHandle();
}
@Bean
public ConfineInterceptor confineInterceptor(ConfineFailHandle confineFailHandle) {
ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("computeTps-pool-%d").build();
EXECUTOR = new ScheduledThreadPoolExecutor(1, threadFactory);
ConfineInterceptor confineInterceptor = new ConfineInterceptor(confineFailHandle,
全局最大tps限制, 全局最大rt限制);
// 每分钟通过cpuload变更当前最大tps,计算公式 默认最大tps*目前空闲率
EXECUTOR.scheduleAtFixedRate(() -> {
int maxTps =最大tps;
com.sun.management.OperatingSystemMXBean bean =
(com.sun.management.OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
Double load = bean.getSystemCpuLoad();
ResourceWrapper resourceWrapper = RateLimiterFactory.put(DEFAULT_METHOD, maxTps);
RateLimiter rateLimiter = resourceWrapper.getRateLimiter();
BigDecimal standard = new BigDecimal(100);
BigDecimal loadRate = new BigDecimal(load.intValue() / 5);
BigDecimal tps = new BigDecimal(maxTps);
int currentTps = standard.subtract(loadRate).divide(standard).multiply(tps).intValue();
rateLimiter.setRate(currentTps);
confineInterceptor.setGlobalMaxTps(currentTps);
}, 0, 60, TimeUnit.SECONDS);
return confineInterceptor;
}
```
```
//继承WebMvcConfigurationSupport,使入口限流生效
@Configuration
public class HttpAutoConfiguration extends WebMvcConfigurationSupport {
@Autowired
ConfineInterceptor confineInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(confineInterceptor).addPathPatterns("/**");
}
}
```
## confine-spring-boot-starter使用教程
此组件拥有confine-client所有功能,并自动化装配上述所有功能
首先引入依赖:
```java
icu.funkye
confine-spring-boot-starter
1.0.0
```
首先在你的yaml或者properties中加入以下配置
```properties
confine.enable=true #是否开启自动装配,默认true,如果关闭使用方法跟confine-client无区别
confine.global-max-tps=1000 #全局最大tps,可自定义默认1000
confine.global-max-rt-threshold=1000 #全局最大rt,单位毫秒,默认1秒
confine.type=bucket #默认bucket实现,内置guava需要引入guava依赖,也可通过spi扩展使用其他限流实现
```
之后在需要限流的函数加入注解即可
```java
@RequestMapping("/test")
@ResponseBody
@ConfineLimiter(method=可不填,默认类名@函数名@参数@...拼接而成 ,tps = 最大tps, failBack = 触发限流后的处理器,可参考spring-cloud的failback配置, rt = 最大rt,1分钟内平均达到此rt后就限流)
public String test(@ModelAttribute Test test) throws InterruptedException {
return "ok";
}
```
如果你的应用已经继承了WebMvcConfigurationSupport或WebMvcConfigurationSupport
那么需要仿照HttpAutoConfiguration类的做法,将ConfineInterceptor注册到你的拦截链路中,才能实现对入口处的全局限流
## 动态更新限流阈值
通过shutter之类的配置中心,可自行订阅某个配置项,调用confine提供的接口来更新阈值
```java
//得到配置更新后,直接调用此接口即可
RateLimiterFactory.update(需要更新的资源名,最大tps,最大rt)
```
## SPI扩展实现
可参考BucketLimiter类的实现,简略示例如下:
```
@LoadLevel(name = "填你的实现名即可,confine.type的值等于此值既会加载此实现")
public class XXXXXLimiter extends AbstractLimiter {
@Override
public Limiter create(String resource, int tps, long seconds) {
return this;
}
@Override
public boolean tryAcquire(int permits, long timeout, TimeUnit unit) {
}
}
```