@Sentinel熔断机制的学习与运用
Sentinel熔断机制的学习与运用
微服务架构现状图及未来图
限流的作用
1、保护系统避免被瞬时流量冲垮
2、预防恶意请求与
-
针对请求限制
1、应用(接口的处理能力(QPS/TPS)). RT -> Jmeter (压测)
2、资源限制( cpu (线程池),内存(),网络资源)
3、服务器
-
如何控制流量。
1、限流的指标(可以容纳的流量,已经容纳的流量,可以接收的流量)阈值
2、限流的过程(通过算法来实现)
3、限流的结果(处理策略)
限流的算法
-
计数器(ZK: RequestThrottle)
-
滑动窗口
-
漏桶算法(用来控制传输速率)
1、水的流出速度是固定的
-
令牌桶算法
令牌桶算法的使用:
1、创建一个Demo类用来写令牌桶算法的Demo类
2、导入guava依赖
阿里云官方地址:https://developer.aliyun.com/mvn/search
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>22.0</version>
</dependency>
3、编写测试类
package com.chaoxing.springboot_sentinel;
import com.google.common.util.concurrent.RateLimiter;
/**
* 单机版限流使用方法
* @Author :Kun
* @Date 2022/6/27 10:21
*/
public class RateLimiterDemo {
/**
* 令牌桶算法
* Tps = 10
* 表示每秒可以允许10个令牌
*/
RateLimiter rateLimiter = RateLimiter.create(10);
/**
*请求方法
*如果令牌大于10会显示失败,小于10会显示成功
* 测试需要开许多的线程进行测试
*/
public void doRequest(){
if(rateLimiter.tryAcquire()){
System.out.println("success");
}else {
System.out.println("failed");
}
}
public static void main(String[] args) {
}
}
限流的实现
- Guava
- Semphore
- 分布式限流
Sentinel
1、Sentinel流程图
2、Sentinel的定义
Sentinel是阿里中间件团队开源的,面向分布式服务架构的轻量级高可用流量控制组件,主要以流量为切入点,从流量控制,熔断降级,系统负载保护等多个维度来帮助用户保护服务的稳定性
3、Sentinel的技术图
服务熔断
- 通过并发线程数进行限制
- 针对响应时间
Sentinel的使用及案例
1.建立项目
1、建立一个自己的项目并添加Sentinal依赖
2、导入Sentinel依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.0</version>
</dependency>
3、建立Sentinel测试Demo
4、使用单机版测试是否可以限流(resource_Name为自己设置的资源名称)
package com.chaoxing.springboot_sentinel;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
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 java.util.ArrayList;
import java.util.List;
/**
* 单机版本
*
* @Author :Kun
* @Date 2022/6/27 10:54
*/
public class SentinelDemo {
public static void main(String[] args) {
initFlowRule();
while (true) {
try {
//ResourceName 表示资源,控制访问流量的点
Entry entry = SphU.entry("resource_Name");
System.out.println("执行成功");
} catch (BlockException e) {
e.printStackTrace();
System.out.println("执行被拒绝");
}
}
}
/**
*定义限流规则,初始化规则方便使用
*/
private static void initFlowRule(){
List<FlowRule> rules = new ArrayList<>();
FlowRule flowRule = new FlowRule();
//绑定规则名称,针对那个规则设置规则
flowRule.setResource("resource_Name");
//QPS或者并发数
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
//QPS=5
flowRule.setCount(5);
//添加规则
rules.add(flowRule);
FlowRuleManager.loadRules(rules);
}
}
5、定义Sentinel的控制器SentinelController
package com.chaoxing.springboot_sentinel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author :Kun
* @Date 2022/6/27 11:32
*/
@RestController
public class SentinelController {
@Autowired
TestService testService;
@GetMapping("/hello/{name}")
public String sayHello(@PathVariable("name") String name){
return testService.doTest(name);
}
}
6、定义TestService服务
package com.chaoxing.springboot_sentinel;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @Author :Kun
* @Date 2022/6/27 11:36
*/
@Service
public class TestService {
@SentinelResource(value = "doTest")//声明限流的资源
public String doTest(@PathVariable String name){
return "hello,"+name;
}
}
7、在SpringbootSentinelApplication中定义并使用规则
package com.chaoxing.springboot_sentinel;
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.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.ArrayList;
import java.util.List;
@SpringBootApplication
public class SpringBootSentinelApplication {
public static void main(String[] args) {
initFlowRule();
SpringApplication.run(SpringBootSentinelApplication.class, args);
}
/**
*定义限流规则,初始化规则方便使用
*/
private static void initFlowRule(){
List<FlowRule> rules = new ArrayList<>();
FlowRule flowRule = new FlowRule();
//绑定规则名称,针对那个规则设置规则
flowRule.setResource("doTest");
//QPS或者并发数
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
//QPS=5
flowRule.setCount(5);
//添加规则
rules.add(flowRule);
FlowRuleManager.loadRules(rules);
}
}
8、测试是否可以限流,打开http://localhost:8080/hello/jack
快速刷新看是否存在限流服务
成功显示,由此可看限流服务已经加载到微服务上,此时的限流服务是可以自己设置页面等操作的
比如在配置文件中使用spring.cloud.sentinel.block-page色湖之阻塞页面的跳转
#被阻塞页面的跳转
spring.cloud.sentinel.block-page=
9、修改TestService做限流处理
package com.chaoxing.springboot_sentinel;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @Author :Kun
* @Date 2022/6/27 11:36
*/
@Service
public class TestService {
@SentinelResource(value = "doTest",blockHandler ="blockHandler",fallback = "fallback")//声明限流的资源
public String doTest(@PathVariable String name){
return "hello,"+name;
}
public String blockHandler(String name, BlockException e)//降级,限流触发的
{
return "被限流了";
}
public String fallback(String name){//降级,熔断触发的
return "被降级了";
}
}
此时如果限流的话会显示限流 处理的事务,如图所示:
详解:如果有blockHandler 触发blockHandler ,有fallback 触发fallback 两者都有触发blockHandler