SpringCloud微服务:Sentinel哨兵组件,管理服务限流和降级

源码地址:GitHub·点这里||GitEE·点这里

一、基本简介

1、概念描述

Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。包括核心的独立类库,监控台,丰富的使用场景验证。(这似乎是阿里开源组件的一贯作风,极其有特点,且特点很规律)

基本特性图:

补刀一句:这种图很多人可能不在意,但是一般官方给这个图就是该中间件的基本使用思路,与核心功能点。

2、基础性概念

  • 资源管理

资源是Sentinel组件中的核心概念之一。应用服务器上脚本,静态页面,API接口,文件图片等都可以理解为资源,对于Java开发者而言,API接口就是这里资源的概念。

  • 规则配置

Sentinel组件通过流控规则的配置,来指定允许该资源(API接口)通过的请求次数,IP黑白名单,应用服务等。

  • 测试效果

QPS:每秒查询率,是一台服务器每秒能够处理的查询次数。

TPS:每秒处理事务数,事务处理整体倾向于整个过程。

二、框架环境整合

这里的环境主要整合Nacos注册中心,Feign服务,Sentinel哨兵,和Sentinel控制台。

1、基本依赖

这里的依赖需要参考官方文档,不同的环境使用不同的依赖,这里主要适配SpringCloud环境,所以使用如下包即可。

1<dependency> 2 <groupId>com.alibaba.cloud</groupId> 3 <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> 4 <version>2.1.1.RELEASE</version> 5</dependency>

2、控制台面板

这里直接从GitHub下载一个控制台服务包即可,也可以自己下载源码,按照需求修改后自行打包。

java -jar sentinel-dashboard-1.7.1.jar

下载并启动控制台服务。

3、服务配置

这里主要是把用到的两个服务9001和9002连接到监控台。

1spring: 2 application: 3 name: node09-nacos-9001 4 cloud: 5 nacos: 6 discovery: 7 server-addr: 127.0.0.1:8848 8 config: 9 server-addr: 127.0.0.1:8848 10 file-extension: yaml 11 sentinel: 12 transport: 13 port: 9001 14 dashboard: localhost:8080

最下面四行文件是哨兵控制台的主要配置,注意刚启动之后控制台是看不到连接的,有资源被触发之后才能看到。(附一张首页效果图)

三、流量控制

1、基本描述

流量控制(flow control),其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。

2、限流规则

限流规则主要由下面几个因素组成。

  • resource:资源名,即限流规则的作用对象,对于Java服务端开发而言就是执行的方法;
  • count: 限流阈值,单位时间内能按照规则通过的请求量;
  • grade: 限流阈值类型,QPS 或并发线程数 ;
  • limitApp: 流控限制的指定应用来源,若为default则不区分调用来源;
  • strategy: 调用关系限流策略,直连,链路等;
  • controlBehavior: 流量控制效果,直接拒绝、Warm Up、匀速排队;

3、基本案例

  • 硬编码

配置规则

1public class FlowRuleConfig { 2 3 public static void initFlowQpsRule(String resourceName) { 4 List<FlowRule> rules = new ArrayList<>(); 5 FlowRule rule = new FlowRule(resourceName); 6 // 修改这里参数,查看效果 7 rule.setCount(100); 8 rule.setGrade(RuleConstant.FLOW_GRADE_QPS); 9 rule.setLimitApp("default"); 10 rules.add(rule); 11 FlowRuleManager.loadRules(rules); 12 } 13}

该规则参考上面的限流因素,不难理解。

使用方式

1@RequestMapping(value = "/web/getOrder",method = RequestMethod.GET) 2public String getOrder (@RequestParam("id") Integer id){ 3 FlowRuleConfig.initFlowQpsRule("getOrder"); 4 Entry entry = null; 5 try { 6 // 定义资源,埋点 7 entry = SphU.entry("getOrder"); 8 // 保护的业务逻辑 9 return "Order=" + id ; 10 } catch (Exception e){ 11 e.printStackTrace(); 12 } finally { 13 if (entry != null){entry.exit();} 14 } 15 return "Order Error" ; 16}

测试的时候修改规则中count值,测试效果明显。

  • 编码简化

SphU.entry中可以设置处理类型,限流阈值。

1@RequestMapping(value = "/web/getState",method = RequestMethod.GET) 2public String getState (@RequestParam("id") Integer id){ 3 Entry entry = null; 4 try { 5 entry = SphU.entry("getOrder",EntryType.IN,2); 6 return "state=" + id; 7 } 8 catch (BlockException e){ 9 e.printStackTrace(); 10 } finally { 11 if (entry != null){entry.exit();} 12 } 13 return "State Error" ; 14}

不过这种模式依旧是代码入侵严重,不太符合现在编程的大趋势。Sentinel支持通过@SentinelResource注解定义资源并配置。

4、测试效果

请求上述的两个测试接口,之后看控制台中9001服务的簇点链路。

可以基于控制台实时配置资源的:流控、降级、热点、授权等核心功能,服务重启之后配置也会重置。

四、服务熔断降级

1、注解详解

核心注解SentinelResource

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

  • value

资源名称,核心概念不能为空;

  • entryType

entry 类型,可选项默认为 EntryType.OUT;

  • blockHandler

对应处理BlockException的函数名称,可选项。blockHandler函数访问范围需要是public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为BlockException。blockHandler函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass为对应的类的Class对象,注意对应的函数必须为 static 函数,否则无法解析。

  • fallback

fallback函数名称,可选项,用于在抛出异常的时候提供fallback处理逻辑。fallback函数可以针对所有类型的异常(除了 exceptionsToIgnore里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:返回值类型必须与原函数返回值类型一致;方法参数列表需要和原函数一致,或者可以额外多一个;

注意:这里可以这样理解blockHandler和fallback,fallback处理业务逻辑的异常,服务降级,blockHandler处理sentinel组件控制的阻断异常。

2、使用案例

9001接口服务

1@Service 2public class FlowServiceImpl implements FlowService { 3 @Resource 4 private JdbcTemplate jdbcTemplate ; 5 @SentinelResource(value = "getPhone",blockHandler = "exceptionHandler", fallback = "fallback") 6 @Override 7 public String getPhone(Integer id) { 8 String sql = "select phone from d_phone WHERE id="+id ; 9 Integer.parseInt("hand") ; 10 return jdbcTemplate.queryForList(sql,String.class).get(0) ; 11 } 12 // 降级处理 13 public String fallback(Integer id) { 14 return "服务降级,id="+id ; 15 } 16 // 异常处理 17 public String exceptionHandler(Integer id,BlockException be) { 18 be.printStackTrace(); 19 return "服务抛异常,id="+id ; 20 } 21}

9002请求服务

1@RequestMapping(value = "/web/getJdbc",method = RequestMethod.GET) 2public String getJdbc () { 3 return msgFeign.getJdbc() ; 4}

3、效果测试

通过控制台配置9001的限流规则,然后刷接口看效果。

注意阻断异常和业务异常的返参区别。

4、对比Hystrix组件

Hystrix的核心点在于以隔离和熔断为主的容错机制,超时或被熔断的调用将会快速失败,并可以提供 fallback 机制;

Sentinel核心点在于流量控制多样化,熔断降级服务,系统负载保护,实时监控和控制台;

补刀一句:对于流量控制类的组件,大部分场景是使用限流,服务降级这两块核心功能。

五、源代码地址

1GitHub地址:知了一笑 2https://github.com/cicadasmile/spring-cloud-base 3GitEE地址:知了一笑 4https://gitee.com/cicadasmile/spring-cloud-base

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

SpringCloud微服务:阿里开源组件Nacos,服务和配置管理

源码地址:GitHub·点这里(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fcicadasmile%2Fspringcloudbase)||GitEE·点这里(https://gitee.com/cicadasmile/springcloudba

SpringCloud微服务:基于Nacos组件,整合Dubbo框架

源码地址:GitHub·点这里(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fcicadasmile%2Fspringcloudbase)||GitEE·点这里(https://gitee.com/cicadasmile/springcloud

SpringCloud实现分库分表模式下,数据库实时扩容方案

本文源码:GitHub·点这里(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fcicadasmile%2Fspringcloudbase)||GitEE·点这里(https://gitee.com/cicadasmile/springcloud