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

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【29】Sentinel


持续学习&持续更新中…

守破离


【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【29】Sentinel

  • 简介
  • 熔断降级
    • 什么是熔断
    • 什么是降级
    • 相同点
    • 不同点
  • 整合Sentinel
  • 自定义sentinel流控返回数据
  • 使用Sentinel来保护feign远程调用
  • 自定义资源
  • 给网关整合Sentinel
  • 参考

简介

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

熔断降级

什么是熔断

A 服务调用 B 服务的某个功能,由于网络不稳定问题,或者 B 服务卡机,导致功能时间超长。

如果这样子的次数太多。我们就可以直接将 B 断路了(A 不再请求 B 接口),凡是调用 B 的直接返回降级数据,不必等待 B 的超长执行。 这样 B 的故障问题,就不会级联影响到 A。

什么是降级

整个网站处于流量高峰期,服务器压力剧增,根据当前业务情况及流量,对一些服务和页面进行有策略的降级:停止服务,所有的调用直接返回降级数据。

缓解服务器资源的的压力,保证核心业务的正常运行,保持了大部分客户得到正确的响应。

相同点

  1. 为了保证集群大部分服务的可用性和可靠性,防止崩溃,牺牲小我,成就全局
  2. 用户最终都是体验到某个功能不可用

不同点

  1. 熔断是被调用方故障,触发的系统主动规则
  2. 降级是基于全局考虑,停止一些正常服务,释放资源

整合Sentinel

https://sentinelguard.io/zh-cn/docs/quick-start.html

导入依赖 spring-cloud-starter-alibaba-sentinel

  <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>

下载sentinel的控制台,直接在命令行启动sentinel-dashboard-1.6.3.jar,这是Sentinel的控制台,用户名密码是sentinel,默认是8080端口,如果该端口被占用,使用java -jar sentinel-dashboard-1.6.3.jar --server.port=xxxx启动

配置sentinel控制台地址信息

spring.cloud.sentinel.transport.dashboard=localhost:8080
spring.cloud.sentinel.transport.port=8719 【默认,可以不用配】

Sentinel默认对SpringCloud进行了适配,每个请求默认就是一个资源,访问Controller的请求接口后,就可以在Sentinel的控制台看到簇点链路了

建议给每一个微服务都导入spring-boot-starter-actuator ,并配合management.endpoints.web.exposure.include=*,就可以在控制台看到Sentinel的实时监控了

自定义sentinel流控返回数据

@Configuration
public class MySentinelConfig {public MySentinelConfig() {WebCallbackManager.setUrlBlockHandler(new UrlBlockHandler() {@Overridepublic void blocked(HttpServletRequest request, HttpServletResponse response, BlockException ex) throws IOException {R error = R.error(BizCodeEnume.TOO_MANY_REQUEST.getCode(), BizCodeEnume.TOO_MANY_REQUEST.getMsg());response.setCharacterEncoding("UTF-8");response.setContentType("application/json");response.getWriter().write(JSON.toJSONString(error));}});}
}

使用Sentinel来保护feign远程调用

调用方:

feign.sentinel.enabled=true
@Slf4j
@Component
public class SeckillFeignServiceFallBack implements SeckillFeignService {@Overridepublic R getSkuSeckillInfo(Long skuId) {log.info("熔断方法调用...getSkuSeckillInfo");return R.error(BizCodeEnume.TOO_MANY_REQUEST.getCode(),BizCodeEnume.TOO_MANY_REQUEST.getMsg());}
}
@FeignClient(value = "gulimall-seckill", fallback = SeckillFeignServiceFallBack.class)
public interface SeckillFeignService {@GetMapping("/sku/seckill/{skuId}")R getSkuSeckillInfo(@PathVariable("skuId") Long skuId);
}

远程服务:当然也可以自己配置自己的流控/降级规则

自定义资源

无论是方式1还是2一定要配置好被限流以后的返回内容

方式1:

在这里插入图片描述

方式2:

在这里插入图片描述
在这里插入图片描述

    public List<SecKillSkuRedisTo> blockHandler(BlockException e) {log.error("getCurrentSeckillSkusResource被限流了..");return null;}
    //返回当前时间可以参与的秒杀商品信息/*** blockHandler 函数会在原方法被限流/降级/系统保护的时候调用,而 fallback 函数会针对所有类型的异常。*/@SentinelResource(value = "getCurrentSeckillSkusResource", blockHandler = "blockHandler"/*, fallback = "getCurrentSeckillSkusFallback"*/)@Overridepublic List<SecKillSkuRedisTo> getCurrentSeckillSkus() {//1、确定当前时间属于哪个秒杀场次。long time = new Date().getTime();//        try (Entry entry = SphU.entry("resourceName")) {Set<String> keys = redisTemplate.keys(SESSIONS_CACHE_PREFIX + "*");for (String key : keys) {//seckill:sessions:1582250400000_1582254000000String replace = key.replace(SESSIONS_CACHE_PREFIX, "");String[] s = replace.split("_");Long start = Long.parseLong(s[0]);Long end = Long.parseLong(s[1]);if (time >= start && time <= end) {//2、获取这个秒杀场次需要的所有商品信息List<String> range = redisTemplate.opsForList().range(key, -1000, 1000);BoundHashOperations<String, String, String> hashOps = redisTemplate.boundHashOps(SKUKILL_CACHE_PREFIX);List<String> list = hashOps.multiGet(range);if (list != null) {List<SecKillSkuRedisTo> collect = list.stream().map(item -> {SecKillSkuRedisTo redis = JSON.parseObject((String) item, SecKillSkuRedisTo.class);
//                        redis.setRandomCode(null); 当前秒杀开始就需要随机码return redis;}).collect(Collectors.toList());return collect;}break;}}
//        } catch (BlockException e) {
//            log.error("资源被限流,{}", e.getMessage());
//        }return null;}

给网关整合Sentinel

使用sentinel-dashboard-1.7.1.jar这个控制台

<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency><!-- https://mvnrepository.com/artifact/com.alibaba.csp/sentinel-spring-cloud-gateway-adapter -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId><version>2.1.0.RELEASE</version>
</dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
spring.cloud.sentinel.transport.dashboard=localhost:8080
management.endpoints.web.exposure.include=*spring.cloud.sentinel.scg.fallback.content-type=application/json

在这里插入图片描述

@Configuration
public class SentinelGatewayConfig {//TODO 响应式编程//GatewayCallbackManagerpublic SentinelGatewayConfig(){GatewayCallbackManager.setBlockHandler(new BlockRequestHandler(){//网关限流了请求,就会调用此回调  Mono Flux@Overridepublic Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable t) {R error = R.error(BizCodeEnume.TOO_MANY_REQUEST.getCode(), BizCodeEnume.TOO_MANY_REQUEST.getMsg());String errJson = JSON.toJSONString(error);
//                Mono<String> aaa = Mono.just("aaa");Mono<ServerResponse> body = ServerResponse.ok().body(Mono.just(errJson), String.class);return body;}});//        FlowRule flowRule = new FlowRule();
//        flowRule.setRefResource("gulimall_seckill_route");
        flowRule.set
//        FlowRuleManager.loadRules(Arrays.asList(flowRule));}
}

在这里插入图片描述

在这里插入图片描述

参考

雷丰阳: Java项目《谷粒商城》Java架构师 | 微服务 | 大型电商项目.


本文完,感谢您的关注支持!


相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 生成式AI未来趋势预测
  • 系统架构设计师①:计算机组成与体系结构
  • 【数据结构】堆的实现以及建堆算法和堆排序
  • Unity UGUI 之 图集
  • 【精品资料】数据安全治理解决方案(27页PPT)
  • Electron 和 React 开发桌面应用程序
  • CPU与IO设备交互
  • 什么是服务器带宽
  • vue+watermark-dom实现页面水印效果
  • ESP32CAM人工智能教学15
  • React中Hooks几个有用的 ref
  • go语言Gin框架的学习路线(八)
  • 基于3D开发引擎HOOPS平台的大型三维PLM系统的设计、开发与应用
  • Linux之基础IO(上)
  • TeraTerm 使用技巧
  • docker python 配置
  • Java多态
  • Java知识点总结(JavaIO-打印流)
  • JS专题之继承
  • Laravel 菜鸟晋级之路
  • nginx 配置多 域名 + 多 https
  • node 版本过低
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • Python语法速览与机器学习开发环境搭建
  • Redis 中的布隆过滤器
  • SpiderData 2019年2月13日 DApp数据排行榜
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • Vue UI框架库开发介绍
  • web标准化(下)
  • 阿里云Kubernetes容器服务上体验Knative
  • 安装python包到指定虚拟环境
  • 闭包--闭包作用之保存(一)
  • 给github项目添加CI badge
  • 给初学者:JavaScript 中数组操作注意点
  • 讲清楚之javascript作用域
  • 看域名解析域名安全对SEO的影响
  • 源码安装memcached和php memcache扩展
  • 从如何停掉 Promise 链说起
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • (2)STM32单片机上位机
  • (done) 两个矩阵 “相似” 是什么意思?
  • (MTK)java文件添加简单接口并配置相应的SELinux avc 权限笔记2
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (十六)串口UART
  • (一)项目实践-利用Appdesigner制作目标跟踪仿真软件
  • (转)Oracle存储过程编写经验和优化措施
  • .NET 8 跨平台高性能边缘采集网关
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .Net Core/.Net6/.Net8 ,启动配置/Program.cs 配置
  • .NET Windows:删除文件夹后立即判断,有可能依然存在