主启动
@EnableDiscoveryClient @SpringBootApplication @EnableFeignClients public class OrderNacosMain84 { public static void main(String[] args) { SpringApplication.run(OrderNacosMain84.class, args); } }配置类
@Configuration public class ApplicationContextConfig { @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } }service
@Component public class PaymentFallbackService implements PaymentService { @Override public CommonResult<Payment> paymentSQL(Long id) { return new CommonResult<>(44444, "服务降级返回,=> PaymentFallbackService", new Payment(id, "errorSerial")); } }controller
fallback管运行异常
blockHandler管配置违规
若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 只会进入 blockHandler处理逻辑
@RestController @Slf4j public class CircleBreakerController { public static final String SERVICE_URL = "http://nacos-payment-provider"; @Resource private RestTemplate restTemplate; //① 没有配置 // @SentinelResource(value = "fallback") //② fallback只负责业务异常 // @SentinelResource(value = "fallback",fallback = "handlerFallback") //③ blockHandler只负责sentinel控制台配置违规 // @SentinelResource(value = "fallback",blockHandler = "blockHandler") @RequestMapping("/consumer/fallback/{id}") @SentinelResource(value = "fallback", fallback = "handlerFallback", blockHandler = "blockHandler", exceptionsToIgnore = {IllegalArgumentException.class}) public CommonResult<Payment> fallback(@PathVariable Long id) { CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/" + id, CommonResult.class, id); if (id == 4) { throw new IllegalArgumentException( "IllegalArgumentException,非法参数异常!"); } else if (result.getData() == null) { throw new NullPointerException( "NullPointerException,该ID没有对应记录,空指针异常"); } return result; } //本例是fallback public CommonResult handlerFallback(@PathVariable Long id, Throwable e) { Payment payment = new Payment(id, "null"); return new CommonResult<>(444, "兜底异常handlerFallback,exception内容 " + e.getMessage(), payment); } //本例是blockHandler public CommonResult blockHandler(@PathVariable Long id, BlockException blockException) { Payment payment = new Payment(id, "null"); return new CommonResult<>(445, "blockHandler-sentinel限流,无此流水: blockException " + blockException.getMessage(), payment); } //==> OpenFeign @Resource private PaymentService paymentService; @GetMapping(value = "/consumer/paymentSQL/{id}") public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id) { return paymentService.paymentSQL(id); } }测试
测试轮询::84/consumer/fallback/1
测试@SentinelResource
没有任何配置:给客户error页面,不友好
添加fallback,blockHandler,exceptionsToIgnore:① 忽略了非法参数异常,出现非法参数异常仍是系统错误页面,② 其他情况都有了兜底方案
5.10 规则持久化是什么
一旦我们重启应用,Sentinel规则消失,生产环境需要将配置规则进行持久化
怎么做
将限流规则持久进Nacos保存,只要刷新8401某个rest地址,Sentinel控制台的流控规则就能看的到,只要Nacos里面的配置不删除,针对8401上的流控规则持续有效。
步骤演示
现象:我们先在Sentinel配置一条流控规则,当重启8401后,该流控规则就会失效消失了!
修改8401
pom
<!--SpringCloud ailibaba sentinel-datasource-nacos 做持久化用 --> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency>yml (添加Nacos数据源配置)
添加Nacos业务规则配置(规则即可以保存在Sentinel中,也可以保存在Nacos中等,只要是一个持久化媒介就行)
[ { "resource":"/rateLimit/byUrl", //资源名称 "limitApp":"default", //来源应用 "grade":1, //阈值类型,0表示线程数,1表示QPS "count":1, //单机阈值 "strategy":0, //流控模式,0表示直接,1表示关联,2表示链路 "controlBehavior":0, //流控效果,0表示快速失败,1表示Warm Up,2表示排队等候 "clusterMode":false //是否集群 } ]启动8401 刷新Sentinel发现业务规则有了
停止8401,再看sentinel,发现停机后流控规则消失了!
重启8401,再看sentinel,多次调用接口,多次刷新sentinel后,发现流控规则重新出现了,持久化验证成功!
6. Seata处理分布式事务 6.1 分布式事务问题分布式之前
单机库存没有这个问题