Spring Cloud Alibaba系列(五)sentinel实现服务限流降级
一、sentinel是什么
sentinel的官方名称叫分布式系统的流量防卫兵。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。在Spring Cloud项目中最开始我们使用的是Hystrix,目前已停止更新了。现在Spring Cloud官方推荐的是rensilience4j。当然还有我们今天学习的sentinel。
Sentinel 具有以下特征:
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运 行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
- 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
二、sentinel实现限流
2.1 安装sentinel控制台
这里我们直接下载jar包即可,下载后通过命令行启动:
java -jar sentinel-dashboard-1.7.2.jar
- 默认端口:8080
- 默认用户名:sentinel
- 默认密码:sentinel
启动成功后,我们浏览器访问http://localhost:8080,出现如下界面。

2.2 微服务继承sentinel
- 引入sentinel依赖
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
- 添加sentinel的相关配置
server:
  port: 7003
spring:
  application:
    name: sentinel-provider
  cloud:
	nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080
- 提供个接口用来测试限流
@SpringBootApplication
public class SentinelApplication {
    public static void main(String[] args) {
        SpringApplication.run(SentinelApplication.class, args);
    }
}
@RestController
class TestController{
    @GetMapping("/test")
    public String test(){
        return "hello! sentinel!";
    }
}
我们请求几次这个接口后,打开sentinel控制台,就可以实时监控到这个sentinel-provider服务接口调用情况了。

2.3 配置限流规则

我们这里做一个简单的规则配置:
- 阀值类型:QPS 
- 单机阀值:2 
意思就是:该接口每秒最多允许进入两个请求。
点击新增后,在流控规则里发现了一条规则:

现在,我们继续请求3次这个接口。第三次响应的内容如下:
Blocked by Sentinel (flow limiting)
我们打开控制台发现拒绝了一条请求。

三、Sentinel规则介绍
不管是限流还是降级,它都是按照某种规则进行的,下面具体介绍一下sentinel支持的几种规则。
3.1 流控规则
流量控制,其原理是监控应用流量的QPS(每秒查询率) 或并发线程数等指标,当达到指定的阈值时
对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。

资源名:唯一名称,默认是请求路径,可自定义
针对来源:指定对哪个微服务进行限流,默认指default,意思是不区分来源,全部限制
阈值类型/单机阈值:
- QPS(每秒请求数量): 当调用该接口的QPS达到阈值的时候,进行限流 
- 线程数:当调用该接口的线程数达到阈值的时候,进行限流 
3.2 降级规则
降级规则就是当满足什么条件时,对服务降级——即将请求转发到另外接口上,这个接口与业务无关,只是为了保证系统的完整性。

- RT(平均响应时间) :当资源的平均响应时间超过阈值(以 ms 为单位)之后,资源进入准降级状态。如果接下来 1s 内持续进入 5 个请求,它们的 RT都持续超过这个阈值,那么在接下的时间窗口(以 s 为单位)之内,就会对这个方法进行服务降级。 - 注意 Sentinel 默认统计的 RT 上限是 4900 ms,超出此阈值的都会算作 4900 ms,若需要变更此上限可以通过启动配置项 -Dcsp.sentinel.statistic.max.rt=xxx 来配置。 
- 异常比例:当资源的每秒异常总数占通过量的比值超过阈值之后,资源进入降级状态,即在接下的时间窗口(以 s 为单位)之内,对这个方法的调用都会自动地返回。异常比率的阈值范围是 [0.0,1.0]。 
- 异常数 :当资源近 1 分钟的异常数目超过阈值之后会进行服务降级。注意由于统计时间窗口是分钟级别的,若时间窗口小于 60s,则结束熔断状态后仍可能再进入熔断状态。 
3.3 热点规则
热点规则允许将规则具体到参数上。
我们用个例子来看看效果。
- 编写接口
@GetMapping("/myTest")
@SentinelResource("test3")
public String test123(String name,String age){
    return  name + "----"+ age;
}
- 添加规则

- 运行效果


结果显示,第一个参数被限流了,而第二个参数正常。
3.4 系统规则
系统保护规则是从应用级别的入口流量进行控制,从单台机器的总体 Load、RT、入口 QPS 、CPU使用率和线程数五个维度监控应用数据,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量 (进入应用的流量) 生效。
- Load(仅对 Linux/Unix-like 机器生效):当系统 load1 超过阈值,且系统当前的并发线程数超过系统容量时才会触发系统保护。系统容量由系统的 maxQps * minRt 计算得出。设定参考值一般是 CPU cores * 2.5。 
- RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。 
- 线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。 
- 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。 
- CPU使用率:当单台机器上所有入口流量的 CPU使用率达到阈值即触发系统保护。 
3.5 授权规则
很多时候,我们需要根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源问控制的功能。来源访问控制根据资源的请求来源(origin)限制资源是否通过:
- 若配置白名单,则只有请求来源位于白名单内时才可通过; 
- 若配置黑名单,则请求来源位于黑名单时不通过,其余的请求通过。 

流控应用:sentinel提供了RequestOriginParser来处理接口来源。
我们运行abc来源的请求访问/test接口。
@Component
class requestOrigin implements RequestOriginParser{
    @Override
    public String parseOrigin(HttpServletRequest httpServletRequest) {
        String server = httpServletRequest.getParameter("server");
        return server;
    }
}
我们请求http://localhost:7003/test?server=abc 和 http://localhost:7003/test?server=ab来分别看看效果。
@SentinelResource的使用
@SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。
主要参数有以下几个
| 属性 | 作用 | 
|---|---|
| value | 资源名称 | 
| entryType | entry类型,标记流量的方向,取值IN/OUT,默认是OUT | 
| blockHandler | 处理BlockException的函数名称,函数要求:1. 必须是 public;2.返回类型 参数与原方法一致;3. 默认需和原方法在同一个类中。若希望使用其他类的函数,可配置blockHandlerClass ,并指定blockHandlerClass里面的方法。 | 
| blockHandlerClass | 存放blockHandler的类,对应的处理函数必须static修饰。 | 
| fallback | 1. 返回类型与原方法一致;2. 参数类型需要和原方法相匹配;3. 默认需和原方法在同一个类中。若希望使用其他类的函数,可配置fallbackClass | 
| fallbackClass | 存放fallback的类。对应的处理函数必须static修饰。 | 
| defaultFallback | 若同时配置了 fallback 和 defaultFallback,以fallback为准。 | 
| exceptionsToIgnore | 指定排除掉哪些异常。排除的异常不会计入异常统计,也不会进入fallback逻辑,而是原样抛出。 | 
| exceptionsToTrace | 需要trace的异常 | 
@sentinelResource可结合blockHandler用于限流处理,结合fallback用于降级处理。具体规则可通过sentinel控制台配置,具体我就不演示了,在下一章内容中,我会分别演示限流和降级的应用。
public class MySentinelResource {
    @SentinelResource(value="message",blockHandler="blockHandler",fallback="fallback")
    public String message(String str){
        if(StringUtils.isBlank(str)){
            throw new RuntimeException();
        }
        return str;
    }
    /**
     * 限流处理
     * @param str
     * @param ex
     * @return
     */
    public String blockHandler(String str, BlockedException ex){
        return str + "--"+ ex;
    }
    /**
     * 降级处理
     * @param str
     * @return
     */
    public String fallback(String str){
        return null;
    }
}
代码示例
gitee:https://gitee.com/zhixie/spring-cloud-alibaba-learning/tree/master/sentinel-server
github:https://github.com/binzh303/spring-cloud-alibaba-learning/tree/master/sentinel-server
Spring Cloud Alibaba系列(五)sentinel实现服务限流降级的更多相关文章
- SpringCloud Alibaba系列(三) Sentinel热点参数限流
		愿你生命中有够多的云翳,造就一个美好的黄昏 欢迎关注公众号[渣男小四],一个喜欢技术更喜欢艺术的青年 一.介绍 热点即经常访问的数据.很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据 ... 
- spring cloud 2.x版本 Gateway熔断、限流教程
		前言 本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 本文基于前两篇文章eureka-server.eureka-client.eureka ... 
- Spring Cloud Alibaba系列(一)nacos作为服务注册中心
		Spring Cloud Alibaba各组件版本关系 Spring Cloud Alibaba Version Sentinel Version Nacos Version RocketMQ Ver ... 
- Spring Cloud Alibaba系列之分布式服务组件Dubbo
		本博客的例子代码可以在github找到下载链接:代码下载 SpringBoot.SpringCloud Alibaba系列博客专栏:链接 1.分布式理论 1.1.分布式基本定义 <分布式系统原理 ... 
- spring cloud 入门系列五:使用Feign 实现声明式服务调用
		一.Spring Cloud Feign概念引入通过前面的随笔,我们了解如何通过Spring Cloud ribbon进行负责均衡,如何通过Spring Cloud Hystrix进行服务断路保护,两 ... 
- Spring Cloud Alibaba系列(二)nacos作为服务配置中心
		Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持.使用 Spring Cloud Alibaba Nacos Config,您可 ... 
- Spring Cloud Alibaba基础教程:Nacos服务发现与配置管理
		随着微服务概念的流行,越来越多的公司采用`Spring Cloud`全家桶构建微服务系统,实现业务的快速迭代.`Spring Cloud`提供了快速构建分布式微服务常用组件,包括`Spring Clo ... 
- Spring Cloud Alibaba(五)RocketMQ 异步通信实现
		本文探讨如何使用 RocketMQ Binder 完成 Spring Cloud 应用消息的订阅和发布. 介绍 RocketMQ 是一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的.高 ... 
- 今天介绍一下自己的开源项目,一款以spring cloud alibaba为核心的微服务架构项目,为给企业与个人提供一个零开发基础的微服务架构。
		LaoCat-Spring-Cloud-Scaffold 一款以spring cloud alibab 为核心的微服务框架,主要目标为了提升自己的相关技术,也为了给企业与个人提供一个零开发基础的微服务 ... 
随机推荐
- Linux (八)服务
			个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.服务的概念 操作系统中在后台持续运行的程序,本身并没有操作界面,需要通过端口号访问和操作.CentO ... 
- Java实现 LeetCode 641 设计循环双端队列(暴力)
			641. 设计循环双端队列 设计实现双端队列. 你的实现需要支持以下操作: MyCircularDeque(k):构造函数,双端队列的大小为k. insertFront():将一个元素添加到双端队列头 ... 
- Java实现 蓝桥杯 算法提高 矩阵相乘
			算法提高 矩阵相乘 时间限制:1.0s 内存限制:256.0MB 问题描述 小明最近在为线性代数而头疼,线性代数确实很抽象(也很无聊),可惜他的老师正在讲这矩阵乘法这一段内容. 当然,小明上课打瞌睡也 ... 
- Java实现 LeetCode 73 矩阵置零
			73. 矩阵置零 给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0.请使用原地算法. 示例 1: 输入: [ [1,1,1], [1,0,1], [1,1,1] ... 
- Java实现旅行商问题
			1 问题描述 何为旅行商问题?按照非专业的说法,这个问题要求找出一条n个给定的城市间的最短路径,使我们在回到触发的城市之前,对每个城市都只访问一次.这样该问题就可以表述为求一个图的最短哈密顿回路的问题 ... 
- java实现洛谷P1308统计单词数
			题目描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数. 现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给 ... 
- java实现第四届蓝桥杯世纪末星期
			世纪末星期 题目描述 曾有邪教称1999年12月31日是世界末日.当然该谣言已经不攻自破. 还有人称今后的某个世纪末的12月31日,如果是星期一则会- 有趣的是,任何一个世纪末的年份的12月31日都不 ... 
- zabbix 邮箱告警
			脚本内容 #!/bin/env python #coding:utf- import smtplib from email.mime.text import MIMEText from sys imp ... 
- Spring Security 实战干货:如何实现不同的接口不同的安全策略
			1. 前言 欢迎阅读 Spring Security 实战干货 系列文章 .最近有开发小伙伴提了一个有趣的问题.他正在做一个项目,涉及两种风格,一种是给小程序出接口,安全上使用无状态的JWT Toke ... 
- ubuntu qwt6.1.0安装
			1.ubuntu-12.04 qt-5.1.1 2.sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev 3.qmake 4.make 5.sud ... 
