当前位置: 首页 > article >正文

spring cloud alibaba Sentinel详解

spring cloud alibaba Sentinel详解

spring cloud alibaba Sentinel介绍

  • Sentinel 是阿里巴巴开源的一款动态流量控制组件,主要用于保障微服务架构中的服务稳定性。它能够对微服务中的各种资源(如接口、服务方法等)进行实时监控、流量控制、熔断降级等操作。

  • 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Spring Cloud Alibaba Sentinel 以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应过载保护、热点流量防护等多个维度保护服务的稳定性。

  • Sentinel 的核心功能是基于资源的流量控制(限流)和熔断降级。当微服务的流量超过设定的阈值时,Sentinel 可以通过拒绝多余的请求来防止系统过载,就像交通信号灯可以控制道路上的车流量一样。而熔断降级则是在某个服务出现异常时,暂时停止对该服务的调用,避免故障蔓延,给系统一个自我修复的机会。

安装Sentinel控制台

通过网盘分享的文件:sentinel-dashboard-1.8.8.jar
链接: 提取码: 7pa7
链接: https://pan.baidu.com/s/1od_f6KVfeM5tUJloFPbY5w?pwd=7pa7

下载完成后将他放在一个非中文路径的包下

进入这个包下 输入cmd
使用命令 java -jar sentinel-dashboard-1.8.8.jar 运行即可

启动成功后 访问localhost:8080 进入这个页面
在这里插入图片描述
默认用户和密码都为:sentinel

登陆成功后显示这个页面是因为我们还没将微服务接入sentinel
在这里插入图片描述

Sentinel使用步骤

  1. 导入依赖
        <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>
  1. 在微服务中配置sentinel的地址 因为sentinel是懒加载 所以我们给他配置 eager: true 在项目启动的时候就加载
spring.cloud.sentinel.transport.dashboard=localhost:8080
spring.cloud.sentinel.eager=true
  1. 使用@SentinelResource注解
@GetMapping("/create")public Order createOrder(@RequestParam("userId") Long userId,@RequestParam("productId") Long productId){Order order = orderService.createOrder(productId,userId);return order;}
package com.nie.order.service;import com.nie.order.bean.Order;public interface OrderService {Order createOrder(Long productId ,Long userId);
}
package com.nie.order.service.Impl;import com.nie.order.bean.Order;
import com.nie.order.feign.ProductFeignClient;
import com.nie.order.service.OrderService;
import com.nie.product.bean.Product;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;@Slf4j
@Service
public class OrderServiceImpl implements OrderService {@Autowiredprivate DiscoveryClient discoveryClient;@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate ProductFeignClient productFeignClient;@SentinelResource(value = "createOrder")public Order createOrder(Long productId , Long userId) {Product product= productFeignClient.getPoductFeign(productId);Order order = new Order();order.setId(1L);//TODO 总金额order.setTotalAmount(product.getPrice().multiply(new BigDecimal(product.getNum())));order.setUserId(userId);order.setNickName("zhangsan");order.setAddress("小聂");//TODO 远程查询商品列表order.setProductList(Arrays.asList(product));return order;}
}
package com.nie.order.feign;import com.nie.order.feign.fallback.ProductFeignClientFallback;
import com.nie.product.bean.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;@FeignClient(value = "service-product",fallback = ProductFeignClientFallback.class ) //feign客户端
public interface ProductFeignClient {//mvc注解的两套使用逻辑//放在controller上  是接受这样的请求//放在FeignClient上  是发送这样的请求@GetMapping("/product/{id}")Product getPoductFeign(@PathVariable("id") Long id);}

运行之后就是这样的效果
在这里插入图片描述

异常处理

当web接口被限制的时候我们可以自定义异常处理

这里我们给create添加一个流量控制 即每秒只能访问一次
在这里插入图片描述

package com.nie.common;import lombok.Data;@Data
public class R {private Integer code;private String msg;private Object data;public static R ok() {R r = new R();r.setCode(200);return r;}public static R ok(String msg,Object data) {R r = new R();r.setCode(200);r.setMsg(msg);r.setData(data);return r;}public static R error(){R r = new R();r.setCode(500);return r;}public static R error(Integer code, String msg) {R r = new R();r.setCode(code);r.setMsg(msg);return r;}}
package com.nie.order.exception;import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nie.common.R;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;import java.io.PrintWriter;@Component
public class MyBlockExceptionHander implements BlockExceptionHandler {private ObjectMapper objectMapper=new ObjectMapper();@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, String name, BlockException e) throws Exception {PrintWriter writer = response.getWriter();response.setContentType("application/json;charset=utf-8");R error = R.error(500, name + "被Sentinel限制了,原因为:" + e.getMessage());String json = objectMapper.writeValueAsString(error);writer.write(json);}
}

当我们一秒钟连续多次访问后 他给前端返回的就是我们自己写的信息
在这里插入图片描述

当@SentinelResource触发限制规则

如果没有触发限制规则 则正常运行 如果触发了限制规则 则运行我们写的兜底回调的代码 即createOrderFallback方法

    @SentinelResource(value = "createOrder",blockHandler = "createOrderFallback")public Order createOrder(Long productId , Long userId) {Product product= productFeignClient.getPoductFeign(productId);Order order = new Order();order.setId(1L);//TODO 总金额order.setTotalAmount(product.getPrice().multiply(new BigDecimal(product.getNum())));order.setUserId(userId);order.setNickName("zhangsan");order.setAddress("小聂");//TODO 远程查询商品列表order.setProductList(Arrays.asList(product));return order;}//写兜底回调的业务逻辑public Order createOrderFallback(Long productId , Long userId, BlockException e) {Order order = new Order();order.setId(1L);order.setTotalAmount(productFeignClient.getPoductFeign(productId).getPrice());order.setUserId(userId);order.setNickName("zhangsan");return order;}

openFeign触发限制规则

package com.nie.order.feign;import com.nie.order.feign.fallback.ProductFeignClientFallback;
import com.nie.product.bean.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;@FeignClient(value = "service-product",fallback = ProductFeignClientFallback.class ) //feign客户端
public interface ProductFeignClient {//mvc注解的两套使用逻辑//放在controller上  是接受这样的请求//放在FeignClient上  是发送这样的请求@GetMapping("/product/{id}")Product getPoductFeign(@PathVariable("id") Long id);}
package com.nie.order.feign.fallback;import com.nie.order.feign.ProductFeignClient;
import com.nie.product.bean.Product;
import org.springframework.stereotype.Component;import java.math.BigDecimal;@Component
public class ProductFeignClientFallback implements ProductFeignClient {@Overridepublic Product getPoductFeign(Long id) {System.out.println("兜底回调.......");Product product = new Product();product.setId(id);product.setNum(1);product.setProductName("未知商品");product.setPrice(new BigDecimal(3));return product;}
}

流控规则

流量控制:限制多余的请求,从而保护系统资源不被耗尽
在这里插入图片描述

在这里插入图片描述

流控模式

  • 直接:直接对资源进行设置 多余的资源直接丢弃
    在这里插入图片描述
  • 关联:假如一个操作有读和写的时候 当写的操作量过大的时候就会对读进行限制
    当出现资源竞争的时候会使用关联
  • 链路: 根据不同的调用链 去来只限制某一个调用链
    注意这里要关闭上下文统一
web-context-unify: false

在这里插入图片描述

熔断规则

熔断降级

熔断降级作为保护自己的手段,通常在客户端(调用端)j进行配置.
在这里插入图片描述

  • 慢调用比例
    慢调用比例是指在一定时间内,响应时间超过预设阈值的请求占总请求数的比例。这个指标可以帮助开发者识别性能瓶颈,即哪些服务调用或方法执行时间较长,
  • 异常比例
    异常比例是指在一定时间内,发生异常(如抛出异常、错误返回等)的请求占总请求数的比例。这个指标可以帮助开发者了解服务的稳定性和错误处理能力。
  • 异常数
    异常数是指在一定时间内,发生异常的请求的总次数。这个指标提供了一个具体的数值,帮助开发者量化异常的发生频率。

热点规则

    @GetMapping("/seckill")@SentinelResource(value = "seckill-order", fallback = "seckillFallback")public Order seckill(@RequestParam("userId") Long userId,@RequestParam("productId") Long productId){Order order = orderService.createOrder(productId, userId);order.setId(Long.MAX_VALUE);return order;}public Order seckillFallback(Long userId, Long productId, BlockException exception){System.out.println("已经开始限制了");Order order = new Order();order.setId(productId);order.setUserId(userId);order.setAddress("异常信息:" + exception.getClass());return order;}

在这里插入图片描述

这是说明我们按照第一个参数来规定 一个用户每一秒只能访问一次

当访问过快的时候的结果就是这样
在这里插入图片描述

注意 当我们在使用fallback 时 将错误写为Throwable
在使用blockHandler时,将错误写为BlockException

http://www.lryc.cn/news/2385758.html

相关文章:

  • Kafka + Flink + Spark 构建实时数仓全链路实战
  • React19源码系列之渲染阶段performUnitOfWork
  • Redis中的事务和原子性
  • 怎样把B站的视频保存到本地
  • Vue3前后端分离用户信息显示方案
  • DL00987-基于深度学习YOLOv11的红外鸟类目标检测含完整数据集
  • 黑马程序员C++2024新版笔记 第4章 函数和结构体
  • 数据仓库,扫描量
  • Day126 | 灵神 | 二叉树 | 层数最深的叶子结点的和
  • Python实例题:人机对战初体验Python基于Pygame实现四子棋游戏
  • Vue3性能优化: 大规模列表渲染解决方案
  • 笔记:将一个文件服务器上的文件(一个返回文件数据的url)作为另一个http接口的请求参数
  • 【RocketMQ 生产者和消费者】- 生产者启动源码 - MQClientInstance 定时任务(4)
  • 超全GPT-4o 风格提示词案例,持续更新中,附使用方式
  • Android 自定义SnackBar和下滑取消
  • Netty学习专栏(三):Netty重要组件详解(Future、ByteBuf、Bootstrap)
  • 详解 C# 中基于发布-订阅模式的 Messenger 消息传递机制:Messenger.Default.Send/Register
  • 多场景游戏AI新突破!Divide-Fuse-Conquer如何激发大模型“顿悟时刻“?
  • Java 函数式接口(Functional Interface)
  • 分布式锁总结
  • 使用MybatisPlus实现sql日志打印优化
  • springboot中redis的事务的研究
  • 为什么我输入对了密码,还是不能用 su 切换到 root?
  • client.chat.completions.create方法参数详解
  • 量子计算与云计算的融合:技术前沿与应用前景
  • 《企业级日志该怎么打?Java日志规范、分层设计与埋点实践》
  • python模块管理环境变量
  • 【泛微系统】后端开发Action常用方法
  • 【算法】力扣体系分类
  • sql:如何查询一个数据表字段:Scrp 数据不为空?