Java简单的限流方案

简单的限流方案

在项目中开发中,经常在很短的时间会有非常大的并发请求过来。如果不做限流可能一下子服务器就崩了,这时候限流就显示的很重要了

限流工具

限流我使用的是阿里巴巴的sentinelsentinel, 是面向分布式服务架构的高可用防护组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助用户保障微服务的稳定性。

常用的限流有计数法,滑动窗口计数法,漏桶算法和令牌桶算法,阿里有开源的限流工具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("/**");
    }

}

测试

限流2

限流3

查看日志发现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
作者
归云
发布于
2021年10月26日
更新于
2024年06月18日
许可协议