Sentinel 容灾中心的使用
Sentinel 容灾中心的使用
往期文章
- Nacos环境搭建
- Nacos注册中心的使用
- Nacos配置中心的使用
熔断/限流结果
Jar
生产者
spring-cloud-alibaba:2021.0.4.0
spring-boot:2.6.8
spring-cloud-loadbalancer:3.1.3
sentinel:2021.0.4.0
<!-- 一定要放在前面 -->
<!--Sentinel -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- sentinel-dashboard -->
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-transport-simple-http</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!--Spring Cloud Alibaba Nacos Discovery-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--Spring Cloud Alibaba Nacos Config-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--LoadBalancer-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
消费者
<!-- 一定要放在前面 -->
<!--Sentinel -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--Spring Cloud Alibaba Nacos Config-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--LoadBalancer-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--FastJSON-->
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId>
</dependency>
yml
生产者
server:
port: 8481
spring:application:name: nacos-providercloud:nacos:discovery:server-addr: localhost:8848username: devilvanpassword: 741258963hjkl
management:endpoints:web:exposure:include: '*'
消费者
server:port: 8581
spring:application:name: nacos-consumercloud:nacos:config:group: DEFAULT_GROUPserver-addr: localhost:8848
熔断/流量控制(硬编码限流规则)
【资源】是sentinel限流、熔断的基本单位,可以设置每个资源的阈值。
@Service
public class NacosProviderServiceImpl implements NacosProviderService {private static final String[] RESOURCE_NAME_ARR = new String[]{"echo", "echo2"};/*** 初始化限流规则*/@PostConstructpublic void initFlowRules() {List<FlowRule> flowRules = new ArrayList<>();for (String resourceName : RESOURCE_NAME_ARR) {FlowRule flowRule = new FlowRule();// 设置受保护的资源flowRule.setResource(resourceName);// 设置流控规则 QPSflowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);// 设置受保护的资源阈值// Set limit QPS to 1.flowRule.setCount(1);flowRules.add(flowRule);}// 加载配置好的规则FlowRuleManager.loadRules(flowRules);}
}
控制层
其中echo方法使用注解形式定义sentinel资源,并通过自定义类的形式指定熔断和限流的方法。
/*** @Description Nacos生产者 控制层*/
@RestController
@RequestMapping(value = "nacosProviderController")
public class NacosProviderController {@Resource(name = "nacosProviderServiceImpl")private NacosProviderService nacosProviderService;@GetMapping(value = "/echo/{str}")@SentinelResource(value = "echo", fallback = "echoFallback", fallbackClass = EchoFallback.class,blockHandler = "echoBlockHandler", blockHandlerClass = EchoFallback.class)public ResultMessage<String> echo(@PathVariable String str) {return nacosProviderService.echo(str);}@GetMapping(value = "/echo2/{str}")public ResultMessage<String> echo2(@PathVariable String str) {return nacosProviderService.echo2(str);}
}
echo方法对应限流/熔断处理类
/*** @Description echo方法 异常回调类*/
public class EchoFallback {/*** 遇到异常走的逻辑** @param str 原方法的参数* @param e 异常信息* @return 异常回调方法返回值,和原方法返回值一致*/public static ResultMessage<String> echoFallback(String str, Throwable e) {ResultMessage<String> resultMessage = new ResultMessage<>();String message = "熔断-echo方法调用异常,str: " + str + "\n" + e;resultMessage.setMessage(message);return resultMessage;}/*** 方法限流逻辑** @param str 原方法的参数* @param e 异常信息* @return 限流回调方法返回值,和原方法返回值一致*/public static ResultMessage<String> echoBlockHandler(String str, BlockException e) {ResultMessage<String> resultMessage = new ResultMessage<>();String message = "限流-echo方法进行 限流,str: " + str + "\n" + e;resultMessage.setMessage(message);return resultMessage;}
}
业务逻辑层
echo2方法则使用官方案例的写法,先在初始化initFlowRules()
方法中定义echo2资源,然后在实现类中编写对该资源熔断、限流的逻辑
/*** @Description Nacos生产者 业务逻辑实现类*/
@Service
public class NacosProviderServiceImpl implements NacosProviderService {private static final String[] RESOURCE_NAME_ARR = new String[]{"echo", "echo2"};/*** 初始化限流规则*/@PostConstructpublic void initFlowRules() {List<FlowRule> flowRules = new ArrayList<>();for (String resourceName : RESOURCE_NAME_ARR) {FlowRule flowRule = new FlowRule();// 设置受保护的资源flowRule.setResource(resourceName);// 设置流控规则 QPSflowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);// 设置受保护的资源阈值// Set limit QPS to 1.flowRule.setCount(1);flowRules.add(flowRule);}// 加载配置好的规则FlowRuleManager.loadRules(flowRules);}/*** 测试限流/熔断的方法** @param str 原方法的参数* @return 回调*/@Overridepublic ResultMessage<String> echo(String str) {ResultMessage<String> resultMessage = new ResultMessage<>();if ("devilvan".equals(str)) {String msg = "Hello Nacos Discovery " + str;resultMessage.setMessage(msg);} else {throw new RuntimeException();}return resultMessage;}/*** 测试sentinel设置资源并使用的方法** @param str 入参字符串* @return 回调*/@Overridepublic ResultMessage<String> echo2(String str) {String resource = "echo2";ResultMessage<String> resultMessage = new ResultMessage<>();Entry entry = null;try {entry = SphU.entry(resource);if ("devilvan".equals(str)) {String msg = "Hello Nacos Discovery " + str;resultMessage.setMessage(msg);} else {throw new RuntimeException();}} catch (BlockException e) {String msg = "限流-echo2方法调用异常,str: " + str + "\n" + e;resultMessage.setMessage(msg);} catch (Exception e) {String msg = "熔断-echo2方法调用异常,str: " + str + "\n" + e;resultMessage.setMessage(msg);} finally {if (entry != null) {entry.exit();}}return resultMessage;}
}
对于使用异常的解释
以上两个方法案例中都涉及到对异常的处理(高亮部分),熔断的方法对应使用Throwable的异常捕获,限流的方法只使用BlockException
异常进行捕获。
消费者代码
控制层
/*** @Description Nacos消费者 控制层*/
@RestController
@RequestMapping(value = "nacosConsumerController")
public class NacosConsumerController {private NacosFeignService nacosFeignService;@Autowiredpublic void setNacosFeignService(NacosFeignService nacosFeignService) {this.nacosFeignService = nacosFeignService;}@RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)public String echo(@PathVariable String str) {return nacosFeignService.echo(str);}@RequestMapping(value = "/echo2/{str}", method = RequestMethod.GET)public String echo2(@PathVariable String str) {return nacosFeignService.echo2(str);}
}
feign远程调用层
/*** @author Evad.Wu* @Description Nacos Feign 远程调用接口* @date 2022-11-05*/
@FeignClient(value = "nacos-provider")
public interface NacosFeignService {/*** 远程调用的测试方法** @param str 路由下的参数* @return 返回值* @author Evad.Wu* @Description 远程调用的测试方法* @date 2022-11-05*/@GetMapping(value = "nacosProviderController/echo/{str}")String echo(@PathVariable String str);/*** 远程调用的测试方法2** @param str 路由下的参数* @return 返回值* @author Evad.Wu* @Description 远程调用的测试方法2* @date 2022-11-05*/@GetMapping(value = "nacosProviderController/echo2/{str}")String echo2(@PathVariable String str);
}