1、环境搭建
1、启动Nacos、Sentinel
2、新建9003、9004两个模块
pom
<!-- API -->
<dependency>
<groupId>com.sw</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
yml
server:
port: 9003
spring:
application:
name: nacos-payment-provider
cloud:
nacos:
discovery:
server-addr: localhost:8848
management:
endpoints:
web:
exposure:
include: '*'
启动类
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain9003 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain9003.class, args);
}
}
controller(此处的虚拟数据库是为了方便演示)
@RestController
@RequestMapping("/payment")
public class PaymentController {
@Value("${server.port}")
private String serverPort;
public static Map<Long, Payment> map = new HashMap<>();
static {
map.put(1L, new Payment(1L, "螺蛳粉01"));
map.put(2L, new Payment(2L, "螺蛳粉02"));
map.put(3L, new Payment(3L, "螺蛳粉03"));
}
@GetMapping("/{id}")
public CommonResult<Payment> payment(@PathVariable("id")Long id){
Payment payment = map.get(id);
CommonResult<Payment> result = new CommonResult<>(200, "serverPort: " + serverPort, payment);
return result;
}
}
注:9004构建步骤与9003一致
2、新建8884模块
pom
同理9004、9004模块
yml
server:
port: 8884
spring:
application:
name: nacos-order-consumer
cloud:
nacos:
discovery:
server-addr: localhost:8848
sentinel:
transport:
# sentinel dashboard地址
dashboard: localhost:8080
# 默认8719端口,如果8719被占用,默认递增
port: 8719
service-url:
nacos-user-service: http://nacos-payment-provider
management:
endpoints:
web:
exposure:
include: '*'
启动类
@SpringBootApplication
@EnableDiscoveryClient
public class OrderMain84 {
public static void main(String[] args) {
SpringApplication.run(OrderMain84.class, args);
}
}
config配置类
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
controller
@RestController
@RequestMapping("/consumer")
public class CircleBreakerController {
public static final String SERVICE_URL = "http://nacos-payment-provider";
@Autowired
private RestTemplate restTemplate;
@GetMapping(value = "fallback/{id}", produces = {"application/json;charset=UTF-8"})
@SentinelResource("fallback")
public CommonResult<Payment> fallback(@PathVariable("id")Long id){
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/payment/" + id, CommonResult.class, id);
if (id ==4){
throw new IllegalArgumentException("参数异常!");
}else if (result.getData() == null){
throw new NullPointerException("没有找到对应id的记录!");
}
return result;
}
}
指定降级方法
@RestController
@RequestMapping("/consumer")
public class CircleBreakerController {
public static final String SERVICE_URL = "http://nacos-payment-provider";
@Autowired
private RestTemplate restTemplate;
@GetMapping(value = "fallback/{id}", produces = {"application/json;charset=UTF-8"})
//@SentinelResource("fallback")
@SentinelResource(value = "fallback", fallback = "handlerFallback") //fallback只负责业务异常
public CommonResult<Payment> fallback(@PathVariable("id")Long id){
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/payment/" + id, CommonResult.class, id);
if (id ==4){
throw new IllegalArgumentException("参数异常!");
}else if (result.getData() == null){
throw new NullPointerException("没有找到对应id的记录!");
}
return result;
}
public CommonResult handlerFallback(@PathVariable("id")Long id, Throwable e){
Payment payment = new Payment(id, "null");
return new CommonResult(444,"handlerFallback,异常内容:" + e.getMessage(), payment);
}
}
2、测试
启动测试:
注:此处没有使用Sentinel来配置降级规则,但却降级成功,是因为fallback用于管理异常,当业务发生异常时,可以降级到指定的方法
为业务添加blockhandler
@RestController
@RequestMapping("/consumer")
public class CircleBreakerController {
public static final String SERVICE_URL = "http://nacos-payment-provider";
@Autowired
private RestTemplate restTemplate;
@GetMapping(value = "fallback/{id}", produces = {"application/json;charset=UTF-8"})
//@SentinelResource("fallback")
//@SentinelResource(value = "fallback", fallback = "handlerFallback") //fallback只负责业务异常
@SentinelResource(value = "fallback", blockHandler = "blockHandler") //blockHandler只负责sentinel控制台的配置
public CommonResult<Payment> fallback(@PathVariable("id")Long id){
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/payment/" + id, CommonResult.class, id);
if (id ==4){
throw new IllegalArgumentException("参数异常!");
}else if (result.getData() == null){
throw new NullPointerException("没有找到对应id的记录!");
}
return result;
}
// public CommonResult handlerFallback(@PathVariable("id")Long id, Throwable e){
// Payment payment = new Payment(id, "null");
// return new CommonResult(444,"handlerFallback,异常内容:" + e.getMessage(), payment);
// }
public CommonResult blockHandler(@PathVariable("id")Long id, BlockException exception){
Payment payment = new Payment(id, "null");
return new CommonResult(444,"blockHandler,异常内容:" + exception.getMessage(), payment);
}
}
测试结果:
注:可以看到返回结果直接报错,并没有降级,所以说blockHandler只适用于Sentinel配置的规则
同时配置fallback和blockHandler
@RestController
@RequestMapping("/consumer")
public class CircleBreakerController {
public static final String SERVICE_URL = "http://nacos-payment-provider";
@Autowired
private RestTemplate restTemplate;
@GetMapping(value = "fallback/{id}", produces = {"application/json;charset=UTF-8"})
//@SentinelResource("fallback")
//@SentinelResource(value = "fallback", fallback = "handlerFallback") //fallback只负责业务异常
//@SentinelResource(value = "fallback", blockHandler = "blockHandler") //blockHandler只负责sentinel控制台的配置
@SentinelResource(value = "fallback", fallback = "handlerFallback", blockHandler = "blockHandler")
public CommonResult<Payment> fallback(@PathVariable("id")Long id){
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/payment/" + id, CommonResult.class, id);
if (id ==4){
throw new IllegalArgumentException("参数异常!");
}else if (result.getData() == null){
throw new NullPointerException("没有找到对应id的记录!");
}
return result;
}
public CommonResult handlerFallback(@PathVariable("id")Long id, Throwable e){
Payment payment = new Payment(id, "null");
return new CommonResult(444,"handlerFallback,异常内容:" + e.getMessage(), payment);
}
public CommonResult blockHandler(@PathVariable("id")Long id, BlockException exception){
Payment payment = new Payment(id, "null");
return new CommonResult(444,"blockHandler,异常内容:" + exception.getMessage(), payment);
}
}
配置Sentinel规则:
结果:
可以看到,同时配置fallback
和blockHandler
,blockHandler
的优先级更高
exceptionsToIgnore属性
@RestController
@RequestMapping("/consumer")
public class CircleBreakerController {
public static final String SERVICE_URL = "http://nacos-payment-provider";
@Autowired
private RestTemplate restTemplate;
@GetMapping(value = "fallback/{id}", produces = {"application/json;charset=UTF-8"})
//@SentinelResource("fallback")
//@SentinelResource(value = "fallback", fallback = "handlerFallback") //fallback只负责业务异常
//@SentinelResource(value = "fallback", blockHandler = "blockHandler") //blockHandler只负责sentinel控制台的配置
@SentinelResource(value = "fallback", fallback = "handlerFallback", blockHandler = "blockHandler",
exceptionsToIgnore = {IllegalArgumentException.class})
public CommonResult<Payment> fallback(@PathVariable("id")Long id){
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/payment/" + id, CommonResult.class, id);
if (id ==4){
throw new IllegalArgumentException("参数异常!");
}else if (result.getData() == null){
throw new NullPointerException("没有找到对应id的记录!");
}
return result;
}
public CommonResult handlerFallback(@PathVariable("id")Long id, Throwable e){
Payment payment = new Payment(id, "null");
return new CommonResult(444,"handlerFallback,异常内容:" + e.getMessage(), payment);
}
public CommonResult blockHandler(@PathVariable("id")Long id, BlockException exception){
Payment payment = new Payment(id, "null");
return new CommonResult(444,"blockHandler,异常内容:" + exception.getMessage(), payment);
}
}
测试结果:
注:使用exceptionsToIgnore指定异常类,表示当前方法如果抛出了指定的异常,不进行降级处理,直接返回抛出的异常结果
图片来源:尚硅谷 - 周阳 - Spring Cloud Alibaba
评论 (0)