阿里开源限流神器Sentinel以及个人对限流总结

官网:https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D

总结:1.Semaphone信号量限流  2.在spring cloud +RateLimite

你可以发现没有一个框架是直接限流的,Sentinel哨兵框架很棒

它包括限流,熔断,统计等等功能

原理我看不下那个源码,个人能力有限,打扰了,网址:https://github.com/alibaba/Sentinel/wiki/Sentinel%E5%B7%A5%E4%BD%9C%E4%B8%BB%E6%B5%81%E7%A8%8B

大概意思是:所有的资源对应一个资源名称以及Entry,然后会附带很多插槽,包括限流,熔断...我的理解是通过这个资源名称,来适配这些资源,对他们进行限流等等操作

限流:

https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6

pom.xml


            com.alibaba.csp
            sentinel-annotation-aspectj
            1.4.1
        

demo

public static void main(String[] args) {
        instanceFlowRules();
        Entry entry = null;
        try {
            entry = SphU.entry("HelloWorld");
            System.out.println("HelloWorld");
        } catch (BlockException e) {
            System.out.println("block...");
        } finally {
            if(entry!=null){
                entry.exit();
            }
        }
    }

    private static void instanceFlowRules() {
        List list = new ArrayList<>();
        FlowRule flowRule = new FlowRule();
        flowRule.setResource("HelloWorld");
//20qps
        flowRule.setCount(20);
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        list.add(flowRule);
        FlowRuleManager.loadRules(list);
    }

以QPS方式限流,限流是使用FlowRule

 

如何测试效果?

@ResponseBody
    @RequestMapping(value = "test1")
    public void b() {
        Entry entry = null;
        try {
            entry = SphU.entry("HelloWorld");
            System.out.println("HelloWorld");
        } catch (BlockException e) {
            System.out.println("block...");
        } finally {
            if(entry!=null){
                entry.exit();
            }
        }
    }

使用apache ab工具,ab -c 100 -n 1000 http://localhost:8080/test1

可以看到会出现blocking...

因为超出阈值的时候,统一抛出BlockExection

 

熔断降级

https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7

官方demohttps://github.com/alibaba/Sentinel/blob/master/sentinel-demo/sentinel-demo-basic/src/main/java/com/alibaba/csp/sentinel/demo/degrade/RtDegradeDemo.java

对应的是DegradeRule

private static void initDegradeRule() {
        List rules = new ArrayList();
        DegradeRule rule = new DegradeRule();
        rule.setResource(KEY);
        // set threshold rt, 10 ms
        rule.setCount(10);
        rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
        rule.setTimeWindow(10);
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }

 

使用注解@SentinelResource

https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81

参数:

  • value: 资源名称,必需项(不能为空)
  • entryType: 入口类型,可选项(默认为 EntryType.OUT
  • blockHandler blockHandlerClassblockHandler 对应处理 BlockException 的函数名称,可选项。若未配置,则将 BlockException 直接抛出。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
  • fallback: fallback 函数名称,可选项,仅针对降级功能生效(DegradeException)。fallback 函数的访问范围需要是 public,参数类型和返回类型都需要与原方法相匹配,并且需要和原方法在同一个类中。业务异常不会进入 fallback 逻辑。

 

个人demo

@Configuration
public class AopConfiguration {

    @Bean
    public SentinelResourceAspect sentinelResourceAspect() {
        return new SentinelResourceAspect();
    }
}

实例化注解

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Service;

@Service
public class AServer {

    @SentinelResource(value = "test", blockHandler = "exceptionHandler")
    public void HelloWorld() {
        System.out.println("调用get()");
    }

    public void exceptionHandler(BlockException e) {
        e.printStackTrace();
        System.out.println("出错!!!");
    }
}

value资源名称,blockHandler发生BlockExection时进行服务降级

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;

@Controller
public class AController {

    @Autowired
    AServer aServer;

    @ResponseBody
    @RequestMapping(value = "test")
    public void a() {
        System.out.println("Hello");
        aServer.HelloWorld();
    }

    @ResponseBody
    @RequestMapping(value = "test1")
    public void b() {
        Entry entry = null;
        try {
            entry = SphU.entry("HelloWorld");
            System.out.println("HelloWorld");
        } catch (BlockException e) {
            System.out.println("block...");
        } finally {
            if(entry!=null){
                entry.exit();
            }
        }
    }



    public static void main(String[] args) {
        //instanceFlowRules();
        Entry entry = null;
        try {
            entry = SphU.entry("HelloWorld");
            System.out.println("HelloWorld");
        } catch (BlockException e) {
            System.out.println("block...");
        } finally {
            if(entry!=null){
                entry.exit();
            }
        }
    }

    private static void instanceFlowRules() {
        List list = new ArrayList<>();
        FlowRule flowRule = new FlowRule();
        flowRule.setResource("HelloWorld");
        flowRule.setCount(20);
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        list.add(flowRule);
        FlowRuleManager.loadRules(list);
    }

}

 

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        instanceFlowRules();
        SpringApplication.run(DemoApplication.class, args);
    }

    private static void instanceFlowRules() {
        List list = new ArrayList<>();
        FlowRule flowRule = new FlowRule();
        flowRule.setResource("test");
        flowRule.setCount(20);
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        list.add(flowRule);
        FlowRuleManager.loadRules(list);
    }

}

启动类配置限流,对test资源限流

 

ab工具访问http://localhost:8080/test

 

输出;

出错!!!
Hello
com.alibaba.csp.sentinel.slots.block.flow.FlowException
出错!!!
Hello
com.alibaba.csp.sentinel.slots.block.flow.FlowException
出错!!!

 

 

你可能感兴趣的:(限流)