sentinel-实战笔记

什么是Sentinel

Sentinel是阿里开源的项目,提供了流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性。

Sentinel主要特性:

获取Sentinel

控制台(下载地址在这里)

部署

在使用Sentinel之前,我们首先需部署Sentinel Dashborad,通过以下命令运行

java -Dserver.port=9999 -Dcsp.sentinel.dashboard.server=localhost:9999 -Dproject.name=sentinel-dashboard -jar D:\server\sentinel\sentinel-dashboard-1.7.0.jar

启动成功可以访问:http://localhost:9999

默认账号密码:sentinel/sentinel

登录后可以看到dashboard

此时可以当sentinel监控到当前自己服务的信息。我们可以启动自己的应用。

项目中使用Sentinel

Sentinel针对各个主流框架都提供了适配(包括Servlet,Dubbo,SpringBoot/SpringCloud,gRPC,RocketMQ等),本文以SpringBoot2举例(通过笔者测试发现,SpringBoot 1.x支持不好,自定义流控规则不可用)。

配置application.yml

首先我们需要在SpringBoot2的配置文件中指定Sentinel连接的控制台地址和项目名,即application.yml文件,如下

spring:
application:
name: sentinel-project
cloud:
sentinel:
transport:
dashboard: localhost:9999

配置pom.xml

<!--sentinel-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--sentinel end-->

此时import依赖你会发现报错:

Could not find artifact com.alibaba.csp:sentinel-web-servlet:pom:unknown in nexus-aliyun (http://maven.aliyun.com/nexus/content/groups/public)

需要在pom文件中添加如下配置即可:

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>0.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

开发控制器

开发一个控制器用于测试。

@RestController
@RequestMapping("/sen")
public class HelloController { @RequestMapping("/hello")
public String hello() {
return "success";
}
}

部署项目

至此,启动项目。观察sentinel后台:

可以看到我们的应用被sentinel拦截,链路已被追踪到。

Sentinel操作

流控规则

直接限流:直接对关联的url资源限流

开启sentinel,开启provider服务

对/index资源做流控,设置QPS为1(表示一秒钟只允许访问一次)

此时我们短时间内多次访问http://localhost:7788/sen/hello接口,观察返回结果:

出现Blocked by Sentinel (flow limiting)很幸运,我们成功了!!!说明我们的接口被拦截了。

但是我们思考一个问题,在现在前后端分离的开发模式下,这样的异常抛给前端,肯定是不合适的!这时我们可以自定义异常来处理这个问题。

自定义URL拦截异常

/**
* 自定义sentinel异常返回信息
* @author user
*/
@Component
public class CustomUrlBlockHandler implements UrlBlockHandler {
@Override
public void blocked(HttpServletRequest request,
HttpServletResponse response,
BlockException e) throws IOException {
R r = null;
// BlockException 异常接口,其子类为Sentinel五种规则异常的实现类
// AuthorityException 授权异常
// DegradeException 降级异常
// FlowException 限流异常
// ParamFlowException 参数限流异常
// SystemBlockException 系统负载异常
if (e instanceof FlowException) {
r = R.error(100, "访问速度过快");
} else if (e instanceof DegradeException) {
r = R.error(100, "接口已被降级,暂时无法访问");
} else if (e instanceof AuthorityException) {
r = R.error(100, "无权访问");
} else if (e instanceof ParamFlowException) {
r = R.error(100, "热点参数限流了");
} else if (e instanceof SystemBlockException) {
r = R.error(100, "系统靠不住了,稍等吧");
}
response.setStatus(500);
response.setCharacterEncoding("utf-8");
response.setHeader("Content-type","application/json;charset=utf-8");
response.setContentType("application/json;charset=utf-8");
new ObjectMapper().writeValue(response.getWriter(), r);
}
}

实现UrlBlockHandler接口,重写blocked方法,对BlockException子异常进行处理。

重启项目再次访问:

这样抛给前端的异常就比较友好了。

降级规则

RT: 单个请求的响应时间超过阈值,则进入准降级状态,接下来 1 S 内连续 5 个请求响应时间均超过阈值,就进行降级,持续时间为时间窗口的值。

异常比例:每秒异常数量占通过量的比例大于阈值,就进行降级处理,持续时间为时间窗口的值。

异常数:1 分钟内的异常数超过阈值就进行降级处理,时间窗口的值要大于 60S,否则刚结束熔断又进入下一次熔断了。

热点规则

热点规则是流控规则的更细粒度操作,可以具体到对某个热点参数的限流,设置限流之后,如果带着限流参数的请求量超过阈值,则进行限流,时间为统计窗口时长。

必须要添加@SentinelResource,即对资源进行流控。

定义接口

@GetMapping("/hot")
@SentinelResource("hot")
public R hot(
@RequestParam(value = "num1", required = false) Integer num1,
@RequestParam(value = "num2", required = false) Integer num2) {
log.info("num1:{}, num2:{}", num1, num2);
return R.ok();
}

配置热点参数

访问

num1参数被携带多次访问接口,抛出以上异常。

定义全局异常

发现该异常没用被捕获,我们定义全局异常处理器来处理。

@Slf4j
@Component
@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class GlobalExceptionHandler { /**
* 功能描述: 处理ParamFlowException<br>
* @param ex
* @return: {@link R}
* @Author: Edward
* @Date: 2021/1/20 10:13
*/
@ExceptionHandler(value = ParamFlowException.class)
protected R handleParamFlowException(ParamFlowException ex) {
//获取所有错误信息
return R.error(4000,"热点参数限流了");
}
}

再次访问,返回结果如下:

授权规则

给指定的资源设置流控应用(追加参数),可以对流控应用进行访问权限的设置,具体就是添加白名单和黑名单。

添加配置类

如何给请求指定流控应用,通过实现RequestOriginParser接口来完成,代码如下所示。

public class RequestOriginParserDefinition implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest httpServletRequest) {
String serviceName = httpServletRequest.getParameter("appType");
return serviceName;
}
}

注册配置类

RequestOriginParserDefinition类交给Spring容器关联。

/**
* @version 1.0
* @Author: Edward
* @Date: 2021/1/21 15:21
* @Description:
*/
@Configuration
public class SentinelConfiguration {
@PostConstruct
public void init() {
WebCallbackManager.setRequestOriginParser(new RequestOriginParserDefinition());
}
}

配置规则

我们配置值运行应用类型为pc应用源可以访问。

访问

当以http://localhost:7788/sen/hello?appType=pc访问,

此时可以正常访问。

我们更改appType,再次访问http://localhost:7788/sen/hello?appType=app

存中…(img-wjogFRIm-1611222474344)]

我们配置值运行应用类型为pc应用源可以访问。

访问

当以http://localhost:7788/sen/hello?appType=pc访问,

[外链图片转存中…(img-akAWxZ6L-1611222474345)]

此时可以正常访问。

我们更改appType,再次访问http://localhost:7788/sen/hello?appType=app

[外链图片转存中…(img-1v9XwvpR-1611222474346)]

此时接口已被拦截,无法访问。

源码:https://gitee.com/edwarder/sentinel-project.git

sentinel-实战的更多相关文章

  1. SpringCloudAlibaba分布式流量控制组件Sentinel实战与源码分析(上)

    概述 定义 Sentinel官网地址 https://sentinelguard.io/zh-cn/index.html 最新版本v1.8.4 Sentinel官网文档地址 https://senti ...

  2. SpringCloudAlibaba分布式流量控制组件Sentinel实战与源码分析-中

    实战示例 控制台初体验 Sentinel的控制台启动后,控制台页面的内容数据都是空的,接下来我们来逐步操作演示结合控制台的使用,在上一节也已说明整合SpringCloud Alibaba第一步先加入s ...

  3. asp.net core 实战之 redis 负载均衡和"高可用"实现

    1.概述 分布式系统缓存已经变得不可或缺,本文主要阐述如何实现redis主从复制集群的负载均衡,以及 redis的"高可用"实现, 呵呵双引号的"高可用"并不是 ...

  4. net core 实战之 redis 负载均衡和"高可用"实现

    net core 实战之 redis 负载均衡和"高可用"实现 1.概述 分布式系统缓存已经变得不可或缺,本文主要阐述如何实现redis主从复制集群的负载均衡,以及 redis的& ...

  5. 第六章· Redis高可用sentinel

    sentinel介绍 sentinel实战及配置讲解 sentinel介绍 什么是sentinel? Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Mas ...

  6. SpringCloudGateway微服务网关实战与源码分析 - 中

    实战 路由过滤器工厂 路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应.路由过滤器的作用域是特定的路由.SpringCloud Gateway包括许多内置的GatewayFilter ...

  7. Redis分布式篇

    Redis分布式篇 1 为什么 需要 Redis 集群 1.1 为什么需要集群? 1.1.1 性能 ​ Redis 本身的 QPS 已经很高了,但是如果在一些并发量非常高的情况下,性能还是会受到影响. ...

  8. 图灵学院JAVA互联网架构师专题学习笔记

    图灵学院JAVA互联网架构师专题学习笔记 下载链接:链接: https://pan.baidu.com/s/1xbxDzmnQudnYtMt5Ce1ONQ 密码: fbdj如果失效联系v:itit11 ...

  9. Spring Boot 如何快速集成 Redis 哨兵?

    上一篇:Spring Boot 如何快速集成 Redis? 前面的分享栈长介绍了如何使用 Spring Boot 快速集成 Redis,上一篇是单机版,也有粉丝留言说有没有 Redis Sentine ...

  10. Redis-sentinel 哨兵(HA)

    Sentinel 介绍 Redis-Sentinel 是 Redis 官方推荐的高可用性(HA)解决方案,当用 Redis 做 Master-slave 的高可用方案时,假如Master 宕机了,Re ...

随机推荐

  1. 移动端 FileReader文件上传

    一.file上传文件 <input type="file" multiple>   multiple 设置多选 通过change事件监听是否上传文件 files 属性获 ...

  2. kali2020 装不上docker

    问题描述 如图,不支持i386体系架构 所以百度了一下啥是i386,以及docker支持哪些体系架构 官网的截图如下: 然后我发现我一直以为我装的是64位debian,实际上我装的是32位的 补充一下 ...

  3. Golang--函数签名相同

    Golang--函数签名相同 条件 必须函数的函数名,参数和返回值(类型,个数,顺序)都相同. 验证 例子: 定义函数类型,让相同签名的函数自动实现某个接口. Negtive: package int ...

  4. SpringBoot从入门到精通教程(一)

    写在前面的话: 在很早之前,记笔记时候,我就一直在思考一个问题,我记笔记是为了什么,我一直想不明白 ,后面发现技术跟新迭代的速度实在太快了,笔记刚纪完,技术又跟新了,于是我想了想干脆边写博客,边记笔记 ...

  5. python3全局函数解析

    python的全局函数: import builtins dir(builtins) [ 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray ...

  6. webform中Repeater中调用后台方法

    前台 <%#RoleNameSpan(Eval("RoleName").ToString())%> 后台 /// <summary> /// 角色名称过长处 ...

  7. Tomcat如何使用线程池处理远程并发请求

    Tomcat如何使用线程池处理远程并发请求 通过了解学习tomcat如何处理并发请求,了解到线程池,锁,队列,unsafe类,下面的主要代码来自 java-jre: sun.misc.Unsafe j ...

  8. springMVC搭建分布式框架

    https://www.cnblogs.com/lr393993507/p/7652717.html https://www.cnblogs.com/Tpf386/p/10987931.html

  9. easyui中连接按钮样式

    方法1. <a href="otherpage.php" class="easyui-linkbutton" data-options="ico ...

  10. Python基础(中篇)

    本篇文章主要内容:数据类型的常用方法,条件语句,循环语句. 在开始正篇之前我们先来看看上一篇留下的题目. 题目: 定义一个字典a,有两个键值对:一个键值对key是可乐,value是18:另一个键值对k ...