概述
1、简介
项目地址:https://github.com/alibaba/Sentinel
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 具有以下特征:
- 丰富的应用场景:Sentinel 承接了阿里巴巴近10 年的双十一大促流量的核心场
景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集
群流量控制、实时熔断下游不可用应用等。 - 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入
应用的单台机器秒级数据,甚至500 台以下规模的集群的汇总运行情况。 - 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如
与Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配
置即可快速地接入Sentinel。 - 完善的SPI 扩展点:Sentinel 提供简单易用、完善的SPI 扩展接口。您可以通过
实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
Sentinel 分为两个部分:
- 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有Java 运行时环境,同时
对Dubbo / Spring Cloud 等框架也有较好的支持。 - 控制台(Dashboard)基于Spring Boot 开发,打包后可以直接运行,不需要额外的
Tomcat 等应用容器。
Sentinel 基本概念
- 资源
资源是Sentinel 的关键概念。它可以是Java 应用程序中的任何内容,例如,由应用程序提
供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文
档中,我们都会用资源来描述代码块。
只要通过Sentinel API 定义的代码,就是资源,能够被Sentinel 保护起来。大部分情况下,
可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。 - 规则
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规
则。所有规则可以动态实时调整。
2、Hystrix 与Sentinel 比较
SpringBoot整合Sentinel
1.添加依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2.下载Sentinel控制台(需要跟自己的依赖版本对应)
下载
3.配置控制台地址信息
sentinel:
enabled: true # 是否开启。默认为 true 开启
eager: true # 是否饥饿加载。默认为 false 关闭
transport:
port: 8719 # 假如被占用了会自动从8719开始依次+1扫描。直至找到未被占用的端口,默认8719
dashboard: localhost:8080 # 指定控制台服务的地址
clientIp: 127.0.0.1
filter:
url-patterns: /**
4.启动控制台端口要跟服务中配置的一样
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
5.启动控制台后访问服务的api
流控规则默认是保存在内存中 重启失效
5.根据访问请求每秒限流快速失败
再次频繁访问Blocked by Sentinel (flow limiting)
实时监控"汇总资源信息 引入依赖即可
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
</dependency>
自定义阻塞返回
package cn.cloud.xmall.seckil.config;
import cn.cloud.xmall.common.exception.BizCodeEnum;
import cn.cloud.xmall.common.utils.R;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;
import org.springframework.context.annotation.Configuration;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @Description: 自定义阻塞返回方法
**/
@Configuration
public class XmallSeckillSentinelConfig implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
R error = R.error(BizCodeEnum.TO_MANY_REQUEST.getCode(),BizCodeEnum.TO_MANY_REQUEST.getMessage());
response.setHeader("Content-Type", "application/json;charset=UTF-8");
response.getWriter().write(JSON.toJSONString(error));
}
}
流控模式
-
基于调用关系的流量控制
调用关系包括调用方、被调用方;一个方法又可能会调用其它方法,形成一个调用链路的层次关系。Sentinel 通过 NodeSelectorSlot 建立不同资源间的调用的关系,并且通过 ClusterBuilderSlot 记录每个资源的实时统计信息。
有了调用链路的统计信息,我们可以衍生出多种流量控制手段。 -
根据调用方限流
ContextUtil.enter(resourceName, origin) 方法中的 origin 参数标明了调用方身份。这些信息会在 ClusterBuilderSlot 中被统计。可通过以下命令来展示不同的调用方对同一个资源的调用数据:
curl http://localhost:8719/origin?id=nodeA
-
根据调用链路入口限流:链路限流
NodeSelectorSlot 中记录了资源之间的调用链路,这些资源通过调用关系,相互之间构成一棵调用树。这棵树的根节点是一个名字为 machine-root 的虚拟节点,调用链的入口都是这个虚节点的子节点。
一棵典型的调用树如下图所示:machine-root / / Entrance1 Entrance2 / /
DefaultNode(nodeA) DefaultNode(nodeA)上图中来自入口 Entrance1 和 Entrance2 的请求都调用到了资源 NodeA,Sentinel 允许只根据某个入口的统计信息对资源限流。比如我们可以设置 strategy 为 RuleConstant.STRATEGY_CHAIN,同时设置 refResource 为 Entrance1 来表示只有从入口 Entrance1 的调用才会记录到 NodeA 的限流统计当中,而不关心经 Entrance2 到来的调用。
调用链的入口(上下文)是通过 API 方法 ContextUtil.enter(contextName) 定义的,其中 contextName 即对应调用链路入口名称。 -
具有关系的资源流量控制:关联流量控制
当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联。比如对数据库同一个字段的读操作和写操作存在争抢,读的速度过高会影响写得速度,写的速度过高会影响读的速度。如果放任读写操作争抢资源,则争抢本身带来的开销会降低整体的吞吐量。可使用关联限流来避免具有关联关系的资源之间过度的争抢,举例来说,read_db 和 write_db 这两个资源分别代表数据库读写,我们可以给 read_db 设置限流规则来达到写优先的目的:设置 strategy 为 RuleConstant.STRATEGY_RELATE 同时设置 refResource 为 write_db。这样当写库操作过于频繁时,读数据的请求会被限流。
熔断降级
1.开启Sentinel对Feign的支持
feign:
sentinel:
enabled: true #开启支持sentinel
开启后可以在控制台监控到远程调用
1.添加远程调用失败回调(调用方 熔断保护)
超大流量的时候必须牺牲一些远程服务,远程服务指定降级策略,提供方是在运行,但是不运行自己 的业务逻辑,返回的是默认的熔断数据,限流后的数据
/**
* fallback远程调用失败回调
*/
@FeignClient(value = "xmall-seckil",fallback = SeckillFeignServiceFallBack.class)
@Component
public class SeckillFeignServiceFallBack implements SeckillFeignService {
@Override
public R getSkuSeckilInfo(Long skuId) {
return R.error(BizCodeEnum.TO_MANY_REQUEST.getCode(),BizCodeEnum.TO_MANY_REQUEST.getMessage());
}
}
哪怕远程服务宕机 也不会出现服务崩溃现象
2.被调用方熔断保护
feign:
sentinel:
enabled: true #开启支持sentinel
调用方手动指定降级策略,远程服务被降级处理默认触发熔断回调方法
自定义受保护的资源
基于代码
try(Entry entry = SphU.entry("SeckillSkus")){
//业务逻辑
Set<String> keys = redisTemplate.keys(SESSION__CACHE_PREFIX + "*");
}catch (BlockException e){
log.error("资源被限流,{}",e.getMessage());
}
2022-04-16 23:04:51.433 ERROR 63008 --- [io-25000-exec-4] c.c.x.s.service.impl.SeckillServiceImpl : 资源被限流,null
2022-04-16 23:04:51.669 INFO 63008 --- [io-25000-exec-9] c.c.x.s.controller.SeckillController : getCurrentSeckillSkus正在执行
基于注解
@SentinelResource(value = “SeckillSkus@Resource”)
添加在方法上
可以指定被流控之后的降级处理方法 是针对指定方法被降级时候触发
@SentinelResource(value = "SeckillSkus@Resource",blockHandler = "blockHandler")
定义限流方法(返回值参数需要一致)
public List<SeckillSkuRedisTo> blockHandler(BlockException e) {
log.error("SentinelResource被限流");
return null;
}
2022-04-16 23:19:42.446 ERROR 37392 --- [io-25000-exec-2] c.c.x.s.service.impl.SeckillServiceImpl : SentinelResource被限流
2022-04-16 23:19:42.525 INFO 37392 --- [io-25000-exec-4] c.c.x.s.controller.SeckillController : getCurrentSeckillSkus正在执行
fallback方法 是所有异常降级
可以写在同一个方法,也可以写在别的类里 写在别的类里必须是静态的且指定 类.class
Sentinel 网关流控
在网关层面引入依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
最后
以上就是孤独黑裤为你收集整理的Alibaba-Sentinel简单入门1、简介2、Hystrix 与Sentinel 比较SpringBoot整合Sentinel的全部内容,希望文章能够帮你解决Alibaba-Sentinel简单入门1、简介2、Hystrix 与Sentinel 比较SpringBoot整合Sentinel所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复