Sentinel 注解支持

@SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。 @SentinelResource 注解包含以下属性:

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

注:1.6.0 之前的版本 fallback 函数只针对降级异常(DegradeException)进行处理,不能针对业务异常进行处理。

特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。若未配置 blockHandler、fallback 和 defaultFallback,则被限流降级时会将 BlockException 直接抛出。

使用注意点采坑日记

@SentinelResource 注解不单单用于controller的接口流控。同时也可以用于方法上面。如果看过实现方式代码。可以知道他底层是基于cglib动态代理实现的。进行切面处理。注意点:

  • 不能修饰在接口上面。只能修饰在实现类的方法上
  • 不能修饰在静态的方法上面。
  • 同一个bean方法A调用方法B,假设方法A和B都进行了注解。B方法注解失效,请参考@Transactional 失效。
    • @Transactional 加于private方法, 无效
    • @Transactional 加于未加入接口的public方法, 再通过普通接口方法调用, 无效
    • @Transactional 加于接口方法, 无论下面调用的是private或public方法, 都有效
    • @Transactional 加于接口方法后, 被本类普通接口方法直接调用, 无效
    • @Transactional 加于接口方法后, 被本类普通接口方法通过接口调用, 有效
    • @Transactional 加于接口方法后, 被它类的接口方法调用, 有效
    • @Transactional 加于接口方法后, 被它类的私有方法调用后, 有效

blockHandler 和 blockHandlerClass 的使用

blockHandler 是可选的。如果使用blockHandlerClass,必须搭配blockHandler使用, blockHandler指定blockHandlerClass类中对应的方法名称。方法名称、参数、返回值、static 必须按照上述文档描述一样。官方文档没有强调要必须要搭配使用。

同理 fallback 和 fallbackClass也是上面讲述的注意点。

改造client 服务

        <dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

bootstrap.yml 配置文件

spring:
cloud:
sentinel:
filter:
# sentienl 默认生效,本地调试false
enabled: true
transport:
dashboard: localhost:8890
port: 8719
# 饥饿加载
eager: true
datasource:
# Sentinel基于nacos存储获取配置信息
na:
nacos:
server-addr: 47.99.209.72:8848
groupId: DEFAULT_GROUP
dataId: ${spring.application.name}-${spring.profiles.active}-sentinel
# 类型
# FLOW("flow", FlowRule.class),
# DEGRADE("degrade", DegradeRule.class),
# PARAM_FLOW("param-flow", ParamFlowRule.class),
# SYSTEM("system", SystemRule.class),
# AUTHORITY("authority", AuthorityRule.class),
# GW_FLOW("gw-flow", "com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule"),
# GW_API_GROUP("gw-api-group", "com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition");
rule-type: flow

nacos 创建 cloud-discovery-client-dev-sentinel 配置文件

[
{
"resource": "client:log:save",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
},
{
"resource": "client:fegin:test",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
},
{
"resource": "user:service:saveTx",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
},
{
"resource": "user:service:save:test",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]

创建 BackHandlerClass DiscoveryClientControllerBackHandler

package com.xian.cloud.common.handler;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.xian.cloud.entity.UserEntity;
import lombok.extern.slf4j.Slf4j; /**
* 对应处理 BlockException 的函数名称 服务限流
* @Author: xlr
* @Date: Created in 9:08 PM 2019/11/16
*/
@Slf4j
public class DiscoveryClientControllerBackHandler { public static String defaultMessage(BlockException e){ log.warn( "DiscoveryClientControllerBackHandler defaultMessage BlockException : {}",e );
return "defaultMessage 服务限流,请稍后尝试";
} public static String saveTx(UserEntity entity,BlockException e) { log.warn( "DiscoveryClientControllerBackHandler saveTx BlockException : {}",e );
return "saveTx 服务限流,请稍后尝试";
}
}

创建 FallBackHandlerClass

package com.xian.cloud.common.handler;

import com.xian.cloud.entity.UserEntity;
import lombok.extern.slf4j.Slf4j; /**
* 仅针对降级功能生效(DegradeException)
* @Author: xlr
* @Date: Created in 9:13 PM 2019/11/16
*/
@Slf4j
public class DiscoveryClientControllerFallBackHandler { public static String defaultMessage(Throwable t){ log.warn( "DiscoveryClientControllerFallBackHandler defaultMessage Throwable : {}",t );
return "defaultMessage 服务降级,请稍后尝试";
} public static String saveTx(UserEntity entity,Throwable t) { log.warn( "DiscoveryClientControllerFallBackHandler saveTx Throwable : {}",t );
return "saveTx 服务降级,请稍后尝试";
}
}

对外接口DiscoveryClientController 添加接口


@SentinelResource(
value = "client:fegin:test",
blockHandler = "defaultMessage",
fallback = "defaultMessage",
blockHandlerClass = DiscoveryClientControllerBackHandler.class,
fallbackClass = DiscoveryClientControllerFallBackHandler.class
)
@RequestMapping(value = "fegin/test",method = RequestMethod.GET)
public String feginTest() {
String result = serverService.hello( "fegin" );
return " 返回 : " + result;
} @GetMapping("/log/save")
@SentinelResource(
value = "client/log/save",
blockHandler = "defaultMessage",
fallback = "defaultMessage",
blockHandlerClass = DiscoveryClientControllerBackHandler.class,
fallbackClass = DiscoveryClientControllerFallBackHandler.class
)
public String save(){
UserEntity entity = new UserEntity();
entity.setUsername("tom");
entity.setPassWord("1232131");
entity.setEmail("222@qq.com");
userService.saveTx(entity);
return "success";
} @GetMapping("user/service/save")
public String userServiceSaveTx(){
UserEntity entity = new UserEntity();
String result = userService.saveTx( entity );
return result;
}

UserServiceImpl 方法

  @Override
@Transactional
@SentinelResource(
value = "user:service:saveTx",
blockHandler = "saveTx",
fallback = "saveTx",
blockHandlerClass = DiscoveryClientControllerBackHandler.class,
fallbackClass = DiscoveryClientControllerFallBackHandler.class
)
public String saveTx(UserEntity entity) { return "success";
}

以上就配置完毕。然后进行测试在页面疯狂刷新

http://localhost:9011/client/user/service/save

http://localhost:9011/client/fegin/test

停止 server服务 再次调用 fegin、test

服务降级和服务限流来回切换提示在前端页面。blockHandlerClass、fallbackClass。

如何喜欢可以关注分享本公众号。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。转载请附带公众号二维码

Spring Cloud gateway 七 Sentinel 注解方式使用的更多相关文章

  1. Spring Cloud gateway 五 Sentinel整合

    微服务当前这么火爆的程度,如果不能学会一种微服务框架技术.怎么能升职加薪,增加简历的筹码?spring cloud 和 Dubbo 需要单独学习.说没有时间?没有精力?要学俩个框架?而Spring C ...

  2. Spring Cloud gateway 六 Sentinel nacos存储动态刷新

    微服务当前这么火爆的程度,如果不能学会一种微服务框架技术.怎么能升职加薪,增加简历的筹码?spring cloud 和 Dubbo 需要单独学习.说没有时间?没有精力?要学俩个框架?而Spring C ...

  3. spring cloud gateway整合sentinel作网关限流

    说明: sentinel可以作为各微服务的限流,也可以作为gateway网关的限流组件. spring cloud gateway有限流功能,但此处用sentinel来作为替待. 说明:sentine ...

  4. Spring Cloud Gateway 整合阿里 Sentinel网关限流实战!

    大家好,我是不才陈某~ 这是<Spring Cloud 进阶>第八篇文章,往期文章如下: 五十五张图告诉你微服务的灵魂摆渡者Nacos究竟有多强? openFeign夺命连环9问,这谁受得 ...

  5. 跟我学SpringCloud | 第十三篇:Spring Cloud Gateway服务化和过滤器

    SpringCloud系列教程 | 第十三篇:Spring Cloud Gateway服务化和过滤器 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich. ...

  6. 网关服务Spring Cloud Gateway(二)

    上一篇文章服务网关 Spring Cloud GateWay 初级篇,介绍了 Spring Cloud Gateway 的相关术语.技术原理,以及如何快速使用 Spring Cloud Gateway ...

  7. 阿里Sentinel支持Spring Cloud Gateway啦

    1. 前言 4月25号,Sentinel 1.6.0 正式发布,带来 Spring Cloud Gateway 支持.控制台登录功能.改进的热点限流和注解 fallback 等多项新特性,该出手时就出 ...

  8. curl使用post方式访问Spring Cloud gateway报time out错误

    公司老的项目使用是php,要进行重构.其他团队使用php curl函数使用post方式调用Spring Cloud gateway 报time out错误. 但是使用postman测试是没有任何问题, ...

  9. Spring Cloud Gateway 之获取请求体(Request Body)的几种方式

    Spring Cloud Gateway 获取请求体 一.直接在全局拦截器中获取,伪代码如下 private String resolveBodyFromRequest(ServerHttpReque ...

随机推荐

  1. python selenium单/复选框操作

    一.单选:radio 1.首先是定位选择框的位置 2.定位id,点击图标就可以了,代码如下(获取url地址方法:把上面源码粘贴到文本保存为.html后缀后用浏览器打开,在浏览器url地址栏复制出地址就 ...

  2. Redis系列(一):Redis简介

    一.Redis概述 Redis是一个开源(遵循BSD协议)Key-Value数据结构的内存存储系统,用作数据库.缓存和消息代理.它支持5种数据结构:字符串string.哈希hash.列表list.集合 ...

  3. SQL Server Try Catch 异常捕捉

    SQL Server Try Catch 异常捕捉 背景 今天遇到一个关于try catch 使用比较有意思的问题.如下一段代码: SELECT @@TRANCOUNT AS A BEGIN TRY ...

  4. CDN实现原理

    避让:尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快.更稳定. 检测:通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时监 ...

  5. 【OUC2019写作】学术论文写作第九小组第一次博客作业

    个人简介 潘旻琦:我是潘旻琦:我的爱好是游泳:羊肉泡馍是海大食堂中我最喜欢的一道菜(清真食堂):一句想说的话是:“追随本心,坚持不懈”. 郭念帆:我是郭念帆:我的爱好是足球:海大食堂中最喜欢的一道菜偏 ...

  6. Mybatis使用自定义类型转换Postgresql

    Mybatis使用自定义类型转换Postgresql 主要目的 为了解决从数据库取出来之后再手动转换为javaBean的问题. 主要用mybatis提供的Handler来把处理前置 添加转换类 imp ...

  7. 雷子聊并发编程(001):基础知识之串行&并行&并发

    前言 编写正确的程序很难,而编写正确的并发程序则难上加难.与串行程序相比,在并发程序中存在更多容易出错的地方.那么,为什么还要编写并发程序?原因很简单,能充分发挥与利用多处理器系统的强大计算能力. 在 ...

  8. 开发架构+osi七层协议+socket(day26)

    目录 软件开发架构 C/S架构 B/S架构 网络编程 互联网协议/OSI七层协议 传输层 网络层 数据链路层 物理连接层 socket 什么是socket 为什么用socket 如何使用 软件开发架构 ...

  9. 大家都说好用的 Python 命令行库:click

    作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...

  10. 百度ERNIE 2.0强势发布!16项中英文任务表现超越BERT和XLNet

    2019年3月,百度正式发布NLP模型ERNIE,其在中文任务中全面超越BERT一度引发业界广泛关注和探讨. 今天,经过短短几个月时间,百度ERNIE再升级.发布持续学习的语义理解框架ERNIE 2. ...