微服务守护神-Sentinel-其他

news2024/11/15 10:43:41

引言

书接上篇 微服务守护神-Sentinel-热点-授权-系统规则 ,上面介绍了Sentinel热点、授权、系统规则,本篇继续来Sentinel 剩下其他操作

自定义异常返回

当触发sentinel流控规则之后, sentinel就干巴巴返回异常信息,单纯的文字输出

而当前大部分项目都是前后端分离,接口设计基本采用restful的设计风格,返回都是json格式数据,此时怎办?sentinel其实也考虑过这种情况,允许顽疾自定义异常返回。

  • FlowException 限流异常

  • DegradeException 降级异常

  • ParamFlowException 参数限流异常

  • AuthorityException 授权异常

  • SystemBlockException 系统负载异常

sentinel默认给出以上5种异常,并提供BlockExceptionHandler 接口允许用户自定义

需求:自定义流控异常返回

package cn.wolfcode.error;
@Component
public class ExceptionHandlerPage implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        response.setContentType("application/json;charset=utf-8");
        ResultData data = null;
        if (e instanceof FlowException) {
            data = new ResultData(-1, "接口被限流了");
        } else if (e instanceof DegradeException) {
            data = new ResultData(-2, "接口被降级了");
        }else if (e instanceof ParamFlowException) {
            data = new ResultData(-3, "参数限流异常");
        }else if (e instanceof AuthorityException) {
            data = new ResultData(-4, "授权异常");
        }else if (e instanceof SystemBlockException) {
            data = new ResultData(-5, "系统负载异常了...");
        }
        response.getWriter().write(JSON.toJSONString(data));
    }
}
@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
class ResultData {
    private int code;
    private String message;
}

简单明了,直接实现BlockExceptionHandler接口,重写handle 方法即可。后续测试,触发不同类型流程跳转到不同异常,输出指定格式数据。
 

@SentinelResource注解

前面项目中所有触发流控规则之后,我们的解决方案都是抛出异常,提示信息。但是开发中没有那么简单的逻辑,很多时候多需要围绕这个异常做一些后续操作。最简单例子:当触发熔断时,要走降级方法,而不是简单抛出异常。如果想实现这种操作该怎么玩?此时就得用上sentinel提供@SentinelResource的功能了。

@SentinelResource 注解作用有2个

1>定义资源,标记资源

能将普通的方法标记成一个资源,进而可以给这个资源加上流控规则。

@Service
@Slf4j
public class TraceServiceImpl {
    @SentinelResource(value = "tranceService")
    public void tranceService(){
        log.info("调用tranceService方法");
    }
}

2>定制规则

如果说前面使用可视化控制台配置流控规则,那么使用@SentinelResource注解就可以编码方式配置规则。

@SentinelResource 注解常用属性

属性作用
value资源名称,必需项(不能为空)
entryTypeentry 类型,可选项(默认为 EntryType.OUT
blockHandler/blockHandlerClassblockHandler 对应处理 BlockException 的函数名称,可选项。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
fallback/fallbackClassfallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求: 1. 返回值类型必须与原函数返回值类型一致; 2.方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。 3.fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
defaultFallback默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求: 1. 返回值类型必须与原函数返回值类型一致; 2. 方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。 3. defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
exceptionsToIgnore用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。

需求:当接口调用异常时,触发降级方法

@RestController
@Slf4j
public class AnnoController {
    @RequestMapping("/anno1")
    @SentinelResource(value = "anno1",
            blockHandler="anno1BlockHandler",
            fallback = "anno1Fallback"
    )
    public String anno1(String name){
        if("dafei".equals(name)){
            throw new RuntimeException();
        }
        return "anno1";
    }
    public String anno1BlockHandler(String name,BlockException ex){
        log.error("{}", ex);
        return "接口被限流或者降级了";
    }
    //Throwable时进入的方法
    public String anno1Fallback(String name,Throwable throwable) {
        log.error("{}", throwable);
        return "接口发生异常了";
    }
}

方法/anno1 带上name=dafei,触发异常,异常出现进入anno1Fallback 逻辑, 配置流控规则,正常方法触发流控后,跳转到anno1BlockHandler 逻辑。

Feign整合Sentinel

使用@SentinelResource 确实达到熔断降级逻辑,但是编写方式有点麻烦,你可以理解为写一个接口需要配置2个方法,这种方式有点不优雅,这是引入Feign的编写方式啦。也就是说怎么使用Feign来优雅解决掉这种熔断降级的麻烦。

需求:订单调用商品接口,加上熔断降级逻辑

延用上几篇的案例

步骤1:在shop-order-server项目的配置文件中开启feign对Sentinel的支持

feign:
  sentinel:
    enabled: true

步骤2:创建容错类

@Component
public class ProductFeignService implements IProductFeginService {
    @Override
    public Product findByPid(Long pid) {
        Product product = new Product();
        product.setPid(-1L);
        product.setPname("兜底数据");
        product.setPprice(0.0);
        return product;
    }
}

步骤3:在feign接口中定义容错类

@FeignClient(name = "product-service",fallback = ProductFeignFallBack.class)
public interface IProductFeginService {
    @RequestMapping("/product/{pid}")
    public Product findByPid(@PathVariable("pid") Long pid);
}

步骤4:停止所有 商品服务,重启 shop-order 服务,访问请求,观察容错效果

 可能上面的案例并不是特别恰当,我们只是通过案例来演示Feign集成Sentinel实现降级的效果. 接下来我们具体更贴切的案例来讲解Feign降级的作用.

比如我们在购物的时候,查看商品详情页面的时候,里面包含库存信息,商品详情信息,评论信息,这个需求包含的微服务如下:

没做降级熔断前,假设评论服务宕机了,那意味用户发出查看商品请求也无法正常显示了,原因查看商品接口需要调用评论微服务,而评论微服调不通,请求失败。那页面商品就无法显示,用户自然也无法进行下单。但是对于用户来说,评论看不到并不影响购物,所以这时候我们应该对评论服务进行及时降级处理,返回一个兜底数据(空数据),这样用户的查看商品请求能正常显示,只是评论数据看不到而已,但完全不影响用户。

到这,微服务守护神-Sentinel所有逻辑就讲完了,下一篇到哪个组件了呢?且听下回讲解。

 看文字不过瘾可以切换视频版:SpringCloud Alibaba 极简入门

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/79883.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JVM监控及诊断工具

本文目录命令行jps 查看正在运行的Java进程jstat:查看JVM统计信息jinfo:实时查看和修改JVM配置参数jmap:导出内存映像文件&内存使用情况jhat:JDK自带堆分析工具jstack:打印JVM中线程快照jcmd:多功能命令…

docker、LXC、LXD的区别及传统的虚拟机与操作系统虚拟化的区别

1. 概念解释 1.1. Docker Docker是一个用于在集中式平台上创建、部署和运行应用程序的开源工具。这使得主机的操作系统通过容器运行具有相同Linux内核的应用程序,而不是创建一个完整的虚拟机。使用docker容器不需要考虑Ram和磁盘空间的分配。它能够自己处理这些需…

CopyOnWriteArrayList源码解析

CopyOnWriteArrayList源码解析 简介 我们知道 ArrayList 是线程不安全的,其存在一个古老的线程安全的 Vector,但是由于 Vector 效率太低 (方法都加了synchronzed),在 JDK1.5 时 Doug Lea 提供了一个效率较高的线程安全的 CopyOnWriteArrayL…

虚拟内存(深入理解计算机系统原书第3版9节)

深入理解计算机系统(原书第3版)读书笔记,其实就是嚼碎了原文然后把一部分挑了出来摘要,免得读着读着忘了 文章目录前言一、物理和虚拟寻址二、地址空间三、虚拟内存作为缓存的工具1、DRAM缓存的组织结构2、页表3、页命中4、缺页5、…

[附源码]Python计算机毕业设计SSM基于的小区物业管理系统(程序+LW)

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

微服务框架 SpringCloud微服务架构 微服务保护 33 授权规则 33.1 授权规则

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 微服务保护 文章目录微服务框架微服务保护33 授权规则33.1 授权规则33.1.1 授权规则33 授权规则 33.1 授权规则 33.1.1 授权规则 看看sen…

康鹏科技将于12月16日上会:曾在纽交所上市,由杨建华家族控股

近日,上海康鹏科技股份有限公司(下称“康鹏科技”)在上海证券交易所递交招股书(上会稿),准备在科创板上市。据贝多财经了解,康鹏科技将于2022年12月16日接受科创板上市委的现场审议。 根据公开信…

基于C++实现(MFC)职工工作量统计系统【100010022】

【职工工作量统计系统设计】 1、问题描述 职工包括姓名、职工号、性别、年龄、所在部门、联系方式等信息。 工作量包括职工号、完成的产品数量等信息。 该设计系统能够对职工的工作量进行统计,并排出名次。注意,一个职工的工作量是可以多次输入的。 2…

Alibaba官方上线,Java并发编程全彩图册(终极版)GitHub已置顶

都说程序员工资高、待遇好, 2022 金九银十到了,你的小目标是 30K、40K,还是 16薪的 20K?作为一名 Java 开发工程师,当能力可以满足公司业务需求时,拿到超预期的 Offer 并不算难。然而,提升 Java…

Python图像识别实战(一):实现按数量随机抽取图像复制到另一文件夹(附源码和实现效果)

前面我介绍了可视化的一些方法以及机器学习在预测方面的应用,分为分类问题(预测值是离散型)和回归问题(预测值是连续型)(具体见之前的文章)。 从本期开始,我将做一个关于图像识别的…

Qt实现全局鼠标事件监听器-Linux

Qt实现全局鼠标事件监听器-Linux版🦑 var code “bc8d4eb4-a9df-48e9-8028-bbe1ae7fbd05” 文章目录Qt实现全局鼠标事件监听器-Linux版🦑1、概述🦞2、实现效果🍰3、实现方式🦀4、关键代码🍦5、源代码&…

SpringMVC基础篇:第一个MVC程序和细节分析

文章整理自孙哥说SpringMVC,相关课程联系孙哥学习谢谢。第一章:编码开发一:思路分析二:SpringMVC程序编码三:控制器提供多个服务方法四:注意事项第二章:细节分析一:控制器创建次数二…

C++ 【set、map模拟实现】

目录 set概念 set基本使用 map概念 map的使用 map统计次数 operator[] operator[]底层如何实现? set和map迭代器封装 红黑树迭代器基本结构 operator operator-- operator[] 源代码链接 map、set底层都使用平衡搜索树(即红黑树),容器中的元素…

HanLP 基于朴素贝叶斯 训练 文本分类

一、HanLP 朴素贝叶斯分类器 HanLP 针对文本分类算法已经帮我们实现 朴素贝叶斯法 ,用户可以无需关心内部细节,HanLP 也提供了相关自定义训练接口,前提需要将数据集根据分类放到不同的目录中,例如: 官方给出了相关性能…

HanLP 基于SVM支持向量机 训练 文本分类

一、HanLP 基于SVM支持向量机分类器 上篇文章通过朴素贝叶斯文本分类器,训练测试了 搜狗文本分类语料库迷你版 ,本篇继续测试SVM支持向量机分类器。 由于HanLP 官方给出的 SVM 分类器依赖了第三方库,没有集成在主项目中,需要拉取…

问题解决(1)——VS中scanf报错怎么解决

目录 方法一: 方法二: 方法三: 各位好,博主新建了个公众号《自学编程村》,拉到底部即可看到,有情趣可以关注看看哈哈,关注后还可以加博主wx呦~~~(公众号拉到底部就能看到呦~~&am…

Redis【13】-修改数据库后,如何保证Redis与数据库的数据一致性

一、需求起因 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节。所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库。 这个业务场景,主要是解决读数据从Redi…

ARM 代码重定位实战

前言 任务 在 SRAM 中将代码从 0xd0020010 重定位到 0xd0024000。任务解释:本来代码是运行在0xd0020010的,但是因为一些原因我们又希望代码实际是在0xd0024000位置运行 的。这时候就需要重定位了。注解:本练习对代码本身运行无实际意义&…

你都工作两年半了,还不会RabbitMQ?

What is rabbitMQ ? RabbitMQ 是一个由 Erlang 语言开发的 AMQP(高级消息队列协议) 的开源实现。 RabbitMQ 是轻量级且易于部署的,能支持多种消息协议。 RabbitMQ 可以部署在分布式和联合配置中,以满足高规模、高可用性的需求。 具体特点包括…

ADI Blackfin DSP处理器-BF533的开发详解29:TOUCH_LINE(屏幕画线)(含源代码)

硬件准备 ADSP-EDU-BF533:BF533开发板 AD-HP530ICE:ADI DSP仿真器 软件准备 Visual DSP软件 硬件链接 硬件设计原理图 功能介绍 代码实现了读取触摸屏坐标,并将触摸屏坐标换算为液晶屏的显示坐标,将像素点显示到触摸坐标的位…