十九、SpringCloud Alibaba Sentinel实现熔断和限流(三、)
八、@SentinelResource
1、按名称限流+后续处理
参考上面的热点key步骤
2、按照Url地址限流 + 后续处理
限流处理是sentinel自带的
3、上面兜底方案面临的问题
同Hystrix一样
①、系统默认的,没有体现我们自己的业务要求
②、依照现有条件,我们自己定义的处理方法和业务代码耦合在一块,不直观
③、如果每个业务方法都添加一个兜底的,那代码膨胀加剧
④、全局统一的处理方法没有体现
4、客户自定义限流处理逻辑
①、创建 CustomerBlockHandler类用于自定义限流处理逻辑
②、自定义限流类
③、@SentinelResource上配置限流测处理类以及方法
@GetMapping("/rateLimit/customerBlockHandler") @SentinelResource(value = "customerBlockHandler", blockHandlerClass = CustomerBlockHandler.class, blockHandler = "handlerException2") public CommonResult customerBlockHandler() { return new CommonResult(200,"按客戶自定义",new Payment(2020L,"serial003")); }
九、服务熔断
1、sentinel整合ribbon+openFeign+fallback
2、Sentinel整合Ribbon演示
1)启动nacos和sentinel
2)服务提供者 cloudalibaba-provider-payment9003/9004
3)服务消费者 cloudalibaba-consumer-nacos-order84
代码放在gitee上:https://gitee.com/houchen1996/cloud2020
4)启动上述三个服务
5)添加 fallback 和 blockHandler,查看测试情况
①、目的
fallback管运行时异常
bolckHandler管配置违规
②、测试地址
③、不加任何配置
@RequestMapping("/consumer/fallback/{id}") @SentinelResource(value = "fallback") //没有配置 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; }
当没有任何配置时,返回给用户的就是Error页面
④、只配置fallback
@RequestMapping("/consumer/fallback/{id}") //@SentinelResource(value = "fallback") //没有配置 @SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常 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
@RequestMapping("/consumer/fallback/{id}") //@SentinelResource(value = "fallback") //没有配置 //@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常 @SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规 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); }
此时给fallback链路添加流控规则
快速点击fallback请求,会出现限流,但是不会对异常进行降级
⑥、fallback和blockHandler都进行配置
@RequestMapping("/consumer/fallback/{id}") //@SentinelResource(value = "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 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); }
4、Sentinel支持Feign
①、需要激活 sentinel对Feign的支持
在yml文件中配置
# 激活Sentinel对Feign的支持 feign: sentinel: enabled: true
主启动类上添加 @EnableFeignClients
②、声明FeignClient
@FeignClient(value = "nacos-payment-provider",fallback = PaymentFallbackService.class) public interface PaymentService { @GetMapping(value = "/paymentSQL/{id}") public CommonResult<Payment> paymentSQL(@PathVariable("id") Long id); } //feign的降级类 @Component public class PaymentFallbackService implements PaymentService { @Override public CommonResult<Payment> paymentSQL(Long id) { return new CommonResult<>(44444,"服务降级返回,---PaymentFallbackService",new Payment(id,"errorSerial")); } }
③、测试
将服务9003 9004停了,访问接口,会出现降级
十、规则持久化
1、是什么?
一旦我们重启应用(比如说上面的nacos8401服务),sentinel规则将会消失,生产环境需要将配置规则进行持久化
2、怎么玩?
将限流配置规则持久化进Nacos保存,只要刷新8401 某个rest地址,sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对8401上sentinel的流控规则持续有效
3、步骤
以nacos8401作为实例
1)修改nacos8401服务的pom文件
添加依赖
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency>
2)修改nacos8401服务的yml文件
sentinel: datasource: #将流控规则持久化到nacos dsl: nacos: server-addr: localhost:8848 dataId: cloudalibaba-sentinel-service groupId: DEFAULT_GROUP data-type: json rule-type: flow
3)去nacos配置sentinel的持久化规则
[ { "resource": "/rateLimit/byUrl", "limitApp": "default", "grade": 1, "count": 1, "strategy": 0, "controlBehavior": 0, "clusterMode": false } ]
4)启动nacos8401服务后,刷新sentinel发现配置的流控规则有了
原文地址:https://www.cnblogs.com/houchen/p/15182606.html
- 从MapX到MapXtreme2004[9]-标注的强调显示
- 分布式监控系统Zabbix-3.0.3-完整安装记录(4)-解决zabbix监控图中出现中文乱码问题
- 常用Lambda表达式实例
- centos6.8部署vnc服务
- linux下的缓存机制及清理buffer/cache/swap的方法梳理
- 分组合计且排序和显示名称
- silverlight动态读取txt文件/解析json数据/调用wcf示例
- Junit加载Spring容器作单元测试_添加事务回滚
- 实现三遍决策树,你就会想出更快的算法!
- 将一段复杂文本变成字符串的赋值语句
- Linux下squid代理缓存服务环境部署
- linux下清除Squid缓存的方法记录
- memcached缓存知识简单梳理
- Idea 常用快捷键
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- Linux环境下使用glog日志库的方法
- crontab执行时间与系统时间不一致问题解决
- Linux内核设备驱动之proc文件系统笔记整理
- CentOS7.6系统下使用yum配置lnmp环境的方法
- Linux内核设备驱动之高级字符设备驱动笔记整理
- Linux使用scp命令进行文件远程拷贝详解
- Linux内核设备驱动之Linux内核模块加载机制笔记整理
- linux无损扩容的方法
- Linux内核设备驱动之内核的时间管理笔记整理
- 使用squid搭建http和https的代理服务器设置指南
- linux中gdb的入门使用教程
- Linux命令中Ctrl+z、Ctrl+c和Ctrl+d的区别和使用详解
- Linux lseek函数的使用详解
- Nginx出现500 Internal Server Error 错误的解决方案
- Linux常见基本命令与用法大全