Java简单的限流方案
简单的限流方案
在项目中开发中,经常在很短的时间会有非常大的并发请求过来。如果不做限流可能一下子服务器就崩了,这时候限流就显示的很重要了
限流工具
限流我使用的是阿里巴巴的sentinel,sentinel, 是面向分布式服务架构的高可用防护组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助用户保障微服务的稳定性。
常用的限流有计数法,滑动窗口计数法,漏桶算法和令牌桶算法,阿里有开源的限流工具sentinel, sentinel是阿里针对服务流量控制、熔断降级的框架,承接了阿里巴巴近 10 年的双十一大促流量的核心场景,底层采用滑动窗口计数法
简单的示例
import com.alibaba.csp.sentinel.SphO;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Created by myy on 2021/10/22.
*/
public class SentinelTest {
public static void main(String[] args) {
// 配置规则
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("tutorial");
// QPS 不得超出 1
rule.setCount(1);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
// 运行被限流作用域保护的代码
while (true) {
new SentinelTest().run();
}
}
void run() {
if (SphO.entry("tutorial")) {
try {
System.out.println(new Date());
} finally {
SphO.exit();
}
} else {
// System.out.println("请求被限流");
}
}
}
运行结果
Spring boot 的简单实例
配置限流规则,每秒一次请求
package org.example.framework.config;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
* Created by myy on 2021/10/25.
*/
@Configuration
public class FilterConfig {
@Bean
public void sentinelFilterRegistration() {
// 配置规则
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("tutorial");
// QPS 不得超出 1
rule.setCount(1);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}
拦截请求
import com.alibaba.csp.sentinel.SphO;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* HTTP请求拦截器
* Created by myy on 2021/10/25.
*/
public class RequestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (SphO.entry("tutorial")) {
try {
return true;
} finally {
SphO.exit();
}
} else {
return false;
}
}
}
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* Created by myy on 2021/10/25.
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new RequestInterceptor()).addPathPatterns("/**");
}
}
测试
查看日志发现qps没超过1
Java简单的限流方案
https://guiyunweb.com/archives/java%E7%AE%80%E5%8D%95%E7%9A%84%E9%99%90%E6%B5%81%E6%96%B9%E6%A1%88