sentinel 页面配置结合Java代码
关于微服务架构的降级熔断有疑问的请移步我的其他博客
服务流程大意:
- 客户端(消费者)通过ribbon负载均衡远程调用服务端(生产者),在客户端配置了sentinel内容,达到微服务熔断降级
- 客户端(消费者)通过open feign负载均衡远程调用服务端(生产者),在客户端配置了sentinel内容,达到微服务熔断降级
两种类型: 都是sentinel页面配置的降级,Java业务程序异常降级,两个维度分析
客户端代码
maven
<!--nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<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-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
yml
server:
port: 83
spring:
application:
name: nacos-consumer-order
cloud:
nacos:
discovery:
server-addr: localhost:8848 #nacos地址,将服务注册到nacos中
sentinel:
transport:
dashboard: localhost:8080
port: 8719
management:
endpoints:
web:
exposure:
include: '*'
service-url:
nacos-user-service: http://nacos-provider-payment #生产者服务名,用于远程调用
主启动类
/**
* @author 小鱼
* @version 1.0
* @date 2021/8/4 5:16 下午
* @EnableDiscoveryClient:开启服务注册
*/
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerMain83 {
public static void main(String[] args) {
SpringApplication.run(ConsumerMain83.class);
}
}
资源请求类
里面的请求都是去远程调用了服务端(生产者)
/**
* @author 小鱼
* @version 1.0
* @date 2021/8/4 5:20 下午
*/
@RestController
@Slf4j
public class OrderController {
@Value("${service-url.nacos-user-service}")
private String url;
@Resource
private RestTemplate restTemplate;
@GetMapping("/getPort")
public String getPort(){
return restTemplate.getForObject(url+"/getPort",String.class);
}
@GetMapping("/consumer/payment/get/{id}")
public CommonResult getPaymentById(@PathVariable("id") Long id) {
return restTemplate.getForObject(url+"/payment/get/"+id,CommonResult.class);
}
/**
* 测试sentinel页面配置的规则
* @SentinelResource:
* blockHandler:contentTestBlockHandler方法用于 超过规则时候调用
* @return
*/
@GetMapping("/consumer/payment/testBlockHandler")
@SentinelResource(value = "testBlockHandler",blockHandler = "contentTestBlockHandler")
public CommonResult testBlockHandler() {
return restTemplate.getForObject(url+"/payment/testBlockHandler",CommonResult.class);
}
public CommonResult contentTestBlockHandler(BlockException blockException) {
return new CommonResult(444, "我是sentinel的控制台违规处理:"+blockException.getMessage() , null);
}
/**
* @SentinelResource:
* fallback:java业务代码出现异常的时候出现调用的降级方法
* @return
*/
@GetMapping("/consumer/payment/testFallback")
@SentinelResource(value = "testFallback",fallback = "contentTestFallback")
public CommonResult testFallback() {
return restTemplate.getForObject(url+"/payment/testFallback",CommonResult.class);
}
public CommonResult contentTestFallback(Throwable throwable) {
return new CommonResult(444, "我是业务异常处理降级:"+throwable.getMessage() , null);
}
@GetMapping("/consumer/payment/testAll")
@SentinelResource(value = "testAll",fallback = "contentTestFallback",blockHandler = "contentTestBlockHandler" )
public CommonResult testAll() {
return restTemplate.getForObject(url+"/payment/testFallback",CommonResult.class);
}
}
生产者代码
@GetMapping("/payment/testBlockHandler")
public CommonResult testBlockHandler() {
return new CommonResult(444, "我是正常测试testBlockHandler:" + "端口:" + port, null);
}
@GetMapping("/payment/testFallback")
public CommonResult testFallback() {
int num=10/0;
return new CommonResult(444, "我是正常测试testFallback:" + "端口:" + port, null);
}
验证
1.浏览器访问:http://localhost:83/consumer/payment/testBlockHandler。sentinel了流控规则:QPS的阈值为1。浏览器刷新很快就会出现下图,调用了contentTestBlockHandler方法
2.浏览器访问:http://localhost:83/consumer/payment/testFallback。Java运行时异常,业务逻辑写错了,调用了contentTestFallback方法
2.浏览器访问:http://localhost:83/consumer/payment/testAll。这个配置了fallback和blockHandler的时候会出现两种情况。如果不符合blockHandler的时候出现了fallback的情况会去fallback里面的方法。但是如果符合blockHandler的规则,那么会运行
blockHandler的方法。效果如下图