• Sentinel限流和异常处理


    现在我们已经了解了如何进行限流操作,那么限流状态下的返回结果该怎么修改呢,我们看到被限流之后返回的是Sentinel默认的数据,现在我们希望自定义改如何操作?

    这里我们先创建好被限流状态下需要返回的内容,定义一个请求映射:

    1. @RequestMapping("/blocked")
    2. JSONObject blocked(){
    3. JSONObject object = new JSONObject();
    4. object.put("code", 403);
    5. object.put("success", false);
    6. object.put("massage", "您的请求频率过快,请稍后再试!");
    7. return object;
    8. }

    接着我们在配置文件中将此页面设定为限流页面:

    1. spring:
    2. cloud:
    3. sentinel:
    4. transport:
    5. dashboard: localhost:8858
    6. # 将刚刚编写的请求映射设定为限流页面
    7. block-page: /blocked

    这样,当被限流时,就会被重定向到指定页面:

    那么,对于方法级别的限流呢?经过前面的学习我们知道,当某个方法被限流时,会直接在后台抛出异常,那么这种情况我们该怎么处理呢,比如我们之前在Hystrix中可以直接添加一个替代方案,这样当出现异常时会直接执行我们的替代方法并返回,Sentinel也可以。

    比如我们还是在getUserBorrowDetailByUid方法上进行配置:

    1. @Override
    2. @SentinelResource(value = "getBorrow", blockHandler = "blocked") //指定blockHandler,也就是被限流之后的替代解决方案,这样就不会使用默认的抛出异常的形式了
    3. public UserBorrowDetail getUserBorrowDetailByUid(int uid) {
    4. List borrow = mapper.getBorrowsByUid(uid);
    5. User user = userClient.getUserById(uid);
    6. List bookList = borrow
    7. .stream()
    8. .map(b -> bookClient.getBookById(b.getBid()))
    9. .collect(Collectors.toList());
    10. return new UserBorrowDetail(user, bookList);
    11. }
    12. //替代方案,注意参数和返回值需要保持一致,并且参数最后还需要额外添加一个BlockException
    13. public UserBorrowDetail blocked(int uid, BlockException e) {
    14. return new UserBorrowDetail(null, Collections.emptyList());
    15. }

    可以看到,一旦被限流将执行替代方案,最后返回的结果就是:

    注意blockHandler只能处理限流情况下抛出的异常,包括下面即将要介绍的热点参数限流也是同理,如果是方法本身抛出的其他类型异常,不在管控范围内,但是可以通过其他参数进行处理:

    1. @RequestMapping("/test")
    2. @SentinelResource(value = "test",
    3. fallback = "except", //fallback指定出现异常时的替代方案
    4. exceptionsToIgnore = IOException.class) //忽略那些异常,也就是说这些异常出现时不使用替代方案
    5. String test(){
    6. throw new RuntimeException("HelloWorld!");
    7. }
    8. //替代方法必须和原方法返回值和参数一致,最后可以添加一个Throwable作为参数接受异常
    9. String except(Throwable t){
    10. return t.getMessage();
    11. }

    这样,其他的异常也可以有替代方案了:

    特别注意这种方式会在没有配置blockHandler的情况下,将Sentinel机制内(也就是限流的异常)的异常也一并处理了,如果配置了blockHandler,那么在出现限流时,依然只会执行blockHandler指定的替代方案(因为限流是在方法执行之前进行的)

  • 相关阅读:
    2020 Java开发者数据分析:中国已成为 Java 第一大国
    java毕业设计LIS检验系统2021mybatis+源码+调试部署+系统+数据库+lw
    算法通关村第一关-链表白银经典问题笔记
    jave image to ascii
    深度学习基础汇总
    Pytorch中批量定义模型中相同结构的子模型(动态定义子模型变量名)
    JS案例:在浏览器实现自定义菜单
    kubernetes学习(二) --------docker的基本命令,namespace和cgroups
    RKE2部署高可用Rancher2.6.5
    Camunda 7.x 系列【57】流程设计器
  • 原文地址:https://blog.csdn.net/Leon_Jinhai_Sun/article/details/126069998