经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring » 查看文章
SpringCloud Alibaba(二) - Sentinel,整合OpenFeign,GateWay服务网关
来源:cnblogs  作者:化羽羽  时间:2022/11/28 9:12:32  对本文有异议

1、环境准备

1.1Nacos

单机启动:startup.cmd -m standalone

1.2 Sentinel

启动命令:java -Dserver.port=8858 -Dcsp.sentinel.dashboard.server=localhost:8858 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.0.jar

1.3 JMeter

2、流控规则限流

2.0 环境搭建

2.0.1 依赖

  1. <!-- nacos 依赖 -->
  2. <dependency>
  3. <groupId>com.alibaba.cloud</groupId>
  4. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  5. </dependency>
  6. <!-- sentinel 流量防卫依赖 -->
  7. <dependency>
  8. <groupId>com.alibaba.cloud</groupId>
  9. <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  10. </dependency>
  11. <!-- 暴露/actuator/sentinel端点 单独配置,management开头 -->
  12. <dependency>
  13. <groupId>org.springframework.boot</groupId>
  14. <artifactId>spring-boot-starter-actuator</artifactId>
  15. </dependency>

2.0.2 application.yml

  1. # 端口
  2. server:
  3. port: 9604
  4. # 服务名
  5. spring:
  6. application:
  7. name: kgcmall-sentinel
  8. # 数据源配置
  9. datasource:
  10. driver-class-name: com.mysql.cj.jdbc.Driver
  11. url: jdbc:mysql://localhost:3306/kh96_alibaba_kgcmalldb?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT
  12. username: root
  13. password: 17585273765
  14. # jpa配置
  15. jpa:
  16. hibernate:
  17. ddl-auto: update
  18. show-sql: true
  19. cloud:
  20. #nacos 配置
  21. nacos:
  22. discovery:
  23. server-addr: 127.0.0.1:8848
  24. #sentinel 配置
  25. sentinel:
  26. transport:
  27. dashboard: 127.0.0.1:8858 # sentinel 控制台地址
  28. port: 9605 # 客户端(核心应用)和控制台的通信端口,默认8719,子当以一个为被使用的唯一端口即可
  29. web-context-unify: false #关闭收敛 
  30. # 暴露/actuator/sentinel端点 单独配置,management 开顶格写
  31. management:
  32. endpoints:
  33. web:
  34. exposure:
  35. include: '*'

2.0.3 测试

http://localhost:9604/actuator/sentinel

2.1 流控模式

2.1.1 直接模式

2.1.1.1 测试请求
  1. /**
  2. * @param : [sentinelDesc]
  3. * @return : java.lang.String
  4. * @author : huayu
  5. * @date : 26/11/2022
  6. * @description : 测试 Sentinel 流控 - 直接失败
  7. */
  8. @GetMapping("testSentinelFlowFail")
  9. public String testSentinelFlowFail(@RequestParam String sentinelDesc) {
  10. log.info("------ testSentinelFlowFail 接口调用 ------ ");
  11. return sentinelDesc;
  12. }
2.1.1.2 添加直接流控规则
2.1.1.2.1 需要先发起异常请求

2.1.1.2.2 簇点链路 添加流控规则

2.1.1.2.3 设置流控规则

2.1.1.3查看流控规则

2.1.1.4 测试

2.1.1.5 自定义sentinel统一已成返回处理
  1. /**
  2. * Created On : 26/11/2022.
  3. * <p>
  4. * Author : huayu
  5. * <p>
  6. * Description: 自定义sentinel统一已成返回处理
  7. */
  8. @Slf4j
  9. @Component
  10. public class MySentinelBlockExceptionHandler implements BlockExceptionHandler {
  11. @Override
  12. public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
  13. // 记录异常日志
  14. log.warn("------ MySentinelBlockExceptionHandler 规则Rule:{} ------", e.getRule());
  15. // 增加自定义统一异常返回对象
  16. RequestResult<String> requestResult = null;
  17. // 针对不同的流控异常,统一返回
  18. if (e instanceof FlowException) {
  19. requestResult = ResultBuildUtil.fail("9621", "接口流量限流");
  20. } else if (e instanceof DegradeException) {
  21. requestResult = ResultBuildUtil.fail("9622", "接口服务降级");
  22. } else if (e instanceof ParamFlowException) {
  23. requestResult = ResultBuildUtil.fail("9623", "热点参数限流");
  24. } else if (e instanceof SystemBlockException) {
  25. requestResult = ResultBuildUtil.fail("9624", "触发系统保护");
  26. } else if (e instanceof AuthorityException) {
  27. requestResult = ResultBuildUtil.fail("9625", "授权规则限制");
  28. }
  29. // 统一返回json结果
  30. httpServletResponse.setStatus(HttpStatus.FORBIDDEN.value());
  31. httpServletResponse.setCharacterEncoding("utf-8");
  32. httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
  33. // 借助SpringMVC自带的Jackson工具,返回结果
  34. new ObjectMapper().writeValue(httpServletResponse.getWriter(), requestResult);
  35. }
  36. }
2.1.1.6 再次测试

2.1.2 关联模式

2.1.2.1 测试请求
  1. /**
  2. * @param : [sentinelDesc]
  3. * @return : java.lang.String
  4. * @author : huayu
  5. * @date : 26/11/2022
  6. * @description : 测试 Sentinel 流控 - 关联
  7. */
  8. @GetMapping("testSentinelFlowLink")
  9. public String testSentinelFlowLink(@RequestParam String sentinelDesc) {
  10. log.info("------ testSentinelFlowLink 接口调用 ------ ");
  11. return sentinelDesc;
  12. }
2.1.1.2 添加关联流控规则

2.1.1.3 JMeter压测配置
2.1.1.3.1 线程组

2.1.1.3.2 Http请求

2.1.3 链路模式

链路流控模式指的是,当从某个接口过来的资源达到限流条件时,开启限流。它的功能有点类似于针对来源配置项,区别在于:针对来源是针对上级微服务,而链路流控是针对上级接口,也就是说它的粒度更细。

2.1.3.1 添加调用方法
2.1.3.1.1 接口
  1. /**
  2. * Created On : 26/11/2022.
  3. * <p>
  4. * Author : huayu
  5. * <p>
  6. * Description: 测试链路 模式
  7. */
  8. public interface SentinelService {
  9. void message();
  10. }
2.1.3.1.2 实现类
  1. /**
  2. * Created On : 26/11/2022.
  3. * <p>
  4. * Author : huayu
  5. * <p>
  6. * Description: 测试链路 模式 实现类
  7. */
  8. @Service
  9. public class SentinelServiceImpl implements SentinelService {
  10. @Override
  11. @SentinelResource("message") // 在@SentinelResource中指定资源名
  12. public void message() {
  13. System.out.println("message");
  14. }
  15. }
2.1.3.2 两个接口,调用相同的资源
  1. @Slf4j
  2. @RestController
  3. public class KgcMallSentinelController {
  4. @Autowired
  5. private SentinelService sentinelService;
  6. //测试 Sentinel 流控 - 直接失败
  7. @GetMapping("testSentinelFlowFail")
  8. public String testSentinelFlowFail(@RequestParam String sentinelDesc) {
  9. log.info("------ testSentinelFlowFail 接口调用 ------ ");
  10. //测试 链路模式调用相同的资源
  11. sentinelService.message();
  12. return sentinelDesc;
  13. }
  14. //测试 Sentinel 流控 - 关联
  15. @GetMapping("testSentinelFlowLink")
  16. public String testSentinelFlowLink(@RequestParam String sentinelDesc) {
  17. log.info("------ testSentinelFlowLink 接口调用 ------ ");
  18. //测试 链路模式调用相同的资源
  19. sentinelService.message();
  20. return sentinelDesc;
  21. }
  22. }
2.1.3.3 添加链路流控规则

2.1.3.4 测试

如果message触发流控,指定的入口就会被限流;

2.1.3.4.0 高版本此功能直接使用不生效:

1.7.0 版本开始(对应SCA的2.1.1.RELEASE),官方在CommonFilter 引入了WEB_CONTEXT_UNIFY 参数,用于控制是否收敛context。将其配置为 false 即可根据不同的URL 进行链路限流。

  1. spring:
  2. cloud:
  3. #sentinel 配置
  4. sentinel:
  5. web-context-unify: false #关闭收敛 
2.1.3.4.1 testSentinelFlowFail 请求

2.1.3.4.2 testSentinelFlowLink请求 (message 资源对此入口进行了限流)

使用链路规则,会导致统一返回处理,无法生效;

2.2 流控规则

2.2.1 快速失败

快速失败:直接抛出异常,默认的流量控制方式

当QPS超过任意规则的阈值后,新的请求就会被立即拒绝。这种方式适用于对系统处理能力确切已知的情况下;

2.2.2 Warm Up(激增模式)

Warm Up(激增流量)即预热/冷启动方式;

冷加载因子: codeFactor 默认是3,即请求 QPS 从 1 / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。

当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。

2.2.2.1 使用 testSentinelFlowFail 请求测试

请求方法省略;

2.2.2.2 流控配置

2.2.2.3 压测配置

2.2.3.4 实时监控

2.2.3 匀速模式

会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,其余的排队等待,对应的是漏桶算法。

用于处理间隔性突发的流量,例如消息队列,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,这个时候我们不希望一下子把所有的请求都通过,这样可能会把系统压垮;同时我们也期待系统以稳定的速度,逐步处理这些请求,以起到“削峰填谷”的效果,而不是第一秒拒绝所有请求。

选择排队等待的阈值类型必须是QPS,且暂不支持>1000的模式

2.2.3.1 使用 testSentinelFlowFail 请求测试

请求方法省略;

单机阈值:每秒通过的请求个数是5,则每隔200ms通过一次请求;每次请求的最大等待时间为500ms=0.5s,超过0.5S就丢弃请求。

2.2.3.2 流控配置

2.2.3.3 压测配置

2.2.3.4 实时监控

3、降级规则限流

3.1慢调用比例-SLOW_REQUEST_RATIO

选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。

3.1.1 模拟慢调用请求

  1. /**
  2. * @param : [sentinelDesc]
  3. * @return : java.lang.String
  4. * @author : huayu
  5. * @date : 26/11/2022
  6. * @description : 测试 Sentinel-降级-慢调用
  7. */
  8. @GetMapping("testSentinelDown")
  9. public String testSentinelDown(@RequestParam String sentinelDesc) throws InterruptedException {
  10. log.info("------ testSentinelDown 接口调用 ------ ");
  11. //模拟慢调用
  12. TimeUnit.MILLISECONDS.sleep(100);
  13. return sentinelDesc;
  14. }

3.1.2 降级策略

3.1.3 压测配置

3.1.4 实时监控

3.1.5 从浏览器请求测试

3.2 异常比例-ERROR_RATIO

当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。

经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。

3.2.1 模拟异常比例请求

  1. /**
  2. * @param : [sentinelDesc]
  3. * @return : java.lang.String
  4. * @author : huayu
  5. * @date : 26/11/2022
  6. * @description : 测试 Sentinel-降级-异常比例 异常数
  7. */
  8. @GetMapping("testSentinelDownExpScale")
  9. public String testSentinelDownExpScale(@RequestParam String sentinelDesc) throws InterruptedException {
  10. log.info("------ testSentinelDownExpScale 接口调用 ------ ");
  11. //模拟异常
  12. int num = new Random().nextInt(10);
  13. if (num % 2 == 1) {
  14. num = 10 / 0;
  15. }
  16. return sentinelDesc;
  17. }

3.2.2 降级策略

3.2.3 压测配置

3.2.4 实时监控

3.2.5 从浏览器请求测试

3.3 异常数-ERROR_COUNT

当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

注意:异常降级仅针对业务异常,对 Sentinel 限流降级本身的异常(BlockException)不生效。

3.3.1 模拟异常参数请求

  1. /**
  2. * @param : [sentinelDesc]
  3. * @return : java.lang.String
  4. * @author : huayu
  5. * @date : 26/11/2022
  6. * @description : 测试 Sentinel-降级-异常比例 异常数
  7. */
  8. @GetMapping("testSentinelDownExpScale")
  9. public String testSentinelDownExpScale(@RequestParam String sentinelDesc) throws InterruptedException {
  10. log.info("------ testSentinelDownExpScale 接口调用 ------ ");
  11. //模拟异常
  12. int num = new Random().nextInt(10);
  13. if (num % 2 == 1) {
  14. num = 10 / 0;
  15. }
  16. return sentinelDesc;
  17. }

3.3.2 降级策略

3.3.3 压测配置

3.3.4 实时监控

3.3.5 从浏览器请求测试

4、热点规则限流

何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的数据,并对其访问进行限制。

热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效

4.1 单机阈值

单机阈值: 针对所有参数的值进行设置的一个公共的阈值

  1. 假设当前 参数 大部分的值都是热点流量, 单机阈值就是针对热点流量进行设置, 额外针对普通流量进行参数值流控;
  2. 假设当前 参数 大部分的值都是普通流量, 单机阈值就是针对普通流量进行设置, 额外针对热点流量进行参数值流控

配置热点参数规则:

资源名必须是@SentinelResource(value="资源名")中 配置的资源名,热点规则依赖于注解;

单独指定参数例外的参数具体值,必须是指定的7种数据类型才会生效;

4.1.1 模拟 单机阈值请求

  1. /**
  2. * @param : [sentinelDesc]
  3. * @return : java.lang.String
  4. * @author : huayu
  5. * @date : 26/11/2022
  6. * @description : 测试 Sentinel-热点
  7. */
  8. @GetMapping("testSentinelHotParam")
  9. @SentinelResource(value = "sentinelHotParam", blockHandlerClass = MySentinelHotBlockExceptionHandler.class, blockHandler = "hotBlockExceptionHandle")
  10. //热点参数,必须使用此注解,指定资源名
  11. //注意使用此注解无法处理BlockExecption,会导致统一异常处理失效
  12. public String testSentinelHotParam(@RequestParam String sentinelDesc) {
  13. log.info("------ testSentinelHotParam 接口调用 ------ ");
  14. return sentinelDesc;
  15. }

4.1.2注意使用此注解无法处理BlockExecption,会导致统一异常处理失效

4.1.2.1 方法一:类内处理方法
  1. @GetMapping("testSentinelHotParam")
  2. @SentinelResource(value = "sentinelHotParam",blockHandler = "hotBlockExceptionHandle")
  3. //热点参数,必须使用此注解,指定资源名
  4. //注意使用此注解无法处理BlockExecption,会导致统一异常处理失效
  5. public String testSentinelHotParam(@RequestParam String sentinelDesc) {
  6. log.info("------ testSentinelHotParam 接口调用 ------ ");
  7. return sentinelDesc;
  8. }
  9. /**
  10. * @author : huayu
  11. * @date : 26/11/2022
  12. * @param : [sentinelDesc, e]
  13. * @return : java.lang.String
  14. * @description : 类内处理方法 增加一个自定义处理方法,参数必须跟入口一致
  15. */
  16. public String hotBlockExceptionHandle(@RequestParam String sentinelDesc, BlockException e){
  17. //记录异常日志
  18. log.warn("------ hotBlockExceptionHandle 规则Rule:{} ------", e.getRule());
  19. return JSON.toJSONString(ResultBuildUtil.fail("9623", "热点参数限流")) ;
  20. }
4.1.2.2 方法二:单独处理类
  1. @GetMapping("testSentinelHotParam")
  2. @SentinelResource(value = "sentinelHotParam", blockHandlerClass = MySentinelHotBlockExceptionHandler.class, blockHandler = "hotBlockExceptionHandle")
  3. //热点参数,必须使用此注解,指定资源名
  4. //注意使用此注解无法处理BlockExecption,会导致统一异常处理失效
  5. public String testSentinelHotParam(@RequestParam String sentinelDesc) {
  6. log.info("------ testSentinelHotParam 接口调用 ------ ");
  7. return sentinelDesc;
  8. }
  9. //==========处理类
  10. /**
  11. * Created On : 26/11/2022.
  12. * <p>
  13. * Author : huayu
  14. * <p>
  15. * Description: 方式2 自定义热点参数限流处理异常并指定治理方法
  16. */
  17. @Slf4j
  18. public class MySentinelHotBlockExceptionHandler {
  19. /**
  20. * @param : [sentinelDesc, e]
  21. * @return : java.lang.String
  22. * @author : huayu
  23. * @date : 26/11/2022
  24. * @description : hotBlockExceptionHandle 方法 必须是 静态的 增加一个自定义处理方法,参数必须跟入口一致
  25. */
  26. public static String hotBlockExceptionHandle(@RequestParam String sentinelDesc, BlockException e) {
  27. //记录异常日志
  28. log.warn("------ hotBlockExceptionHandle 规则Rule:{} ------", e.getRule());
  29. return JSON.toJSONString(ResultBuildUtil.fail("9623", "热点参数限流"));
  30. }
  31. }

4.1.3 热点参数策略和规则(sentinelHotParam)

4.1.4 浏览器快速请求测试

5、授权规则限流

根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源访问控制的功能。

来源访问控制根据资源的请求来源(origin)限制资源是否通过:

  • 若配置白名单,则只有请求来源位于白名单内时才可通过;
  • 若配置黑名单,则请求来源位于黑名单时不通过,其余的请求通过。

配置项:

  • 资源名resource,即限流规则的作用对象
  • 流控应用limitApp,对应的黑名单/白名单,不同 origin 用 , 分隔,如 appA,appB
    • Sentinel提供了 RequestOriginParser 接口来处理来源
    • 只要Sentinel保护的接口资源被访问,Sentinel就会调用 RequestOriginParser 的实现类去解析访问来源。
  • 限制模式strategy,AUTHORITY_WHITE 为白名单模式,AUTHORITY_BLACK 为黑名单模式,默认为白名单模式

5.1 自定义来源处理规则

  1. /**
  2. * Created On : 26/11/2022.
  3. * <p>
  4. * Author : huayu
  5. * <p>
  6. * Description: 自定义授权规则解析 来源 处理类
  7. */
  8. @Component
  9. public class MySentinelAuthRequestOriginParser implements RequestOriginParser {
  10. @Override
  11. public String parseOrigin(HttpServletRequest httpServletRequest) {
  12. // TODO 实际应用场景中,可以根据请求来源ip,进行ip限制
  13. //模拟,通过请求参数中,是否携带了自定义的来源参数OriginAuth
  14. //根据授权规则中的流控应用规则指定的参数列表,限制是否可以访问
  15. //授权规则,指定白名单,就代表请求携带的参数OriginAuth,参数值必须是在流控应用指定的参数列表中,才可以访问,否者不允许
  16. //黑名单相反
  17. return httpServletRequest.getParameter("originAuth");
  18. }
  19. }

5.2 模拟授权请求

  1. /**
  2. * @param : [sentinelDesc]
  3. * @return : java.lang.String
  4. * @author : huayu
  5. * @date : 26/11/2022
  6. * @description : 测试 Sentinel-授权
  7. */
  8. @GetMapping("testSentinelAuth")
  9. public String testSentinelAuth(@RequestParam String sentinelDesc,
  10. @RequestParam String originAuth) {
  11. log.info("------ testSentinelHotParam 接口调用 ------ ");
  12. return "sentinelDesc:" + sentinelDesc + "\n,originAuth:" + originAuth;
  13. }

5.3 白名单

5.3.1 配置白名单

5.3.2 测试

5.4黑名单

5.4.1 配置黑名单

5.4.2 测试

6、系统规则限流

系统保护规则是从应用级别的入口流量进行控制,从单台机器的总体 Load、RT、入口 QPS 、CPU使用
率和线程数五个维度监控应用数据,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。系统
保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量 (进入应用的流量) 生效。

  • Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护。系统容量由系统的 maxQps * minRt 估算得出。设定参考值一般是 CPU cores * 2.5。
  • CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0- - 1.0),比较灵敏。
  • 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
  • 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
  • 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护

6.1 模拟系统限流请求

  1. /**
  2. * @param : [sentinelDesc]
  3. * @return : java.lang.String
  4. * @author : huayu
  5. * @date : 26/11/2022
  6. * @description : 测试 Sentinel-系统
  7. * //设置一个, 全部请求都受限制
  8. */
  9. @GetMapping("testSentinelSys")
  10. public String testSentinelSys(@RequestParam String sentinelDesc) {
  11. log.info("------ testSentinelHotParam 接口调用 ------ ");
  12. return "sentinelDesc:" + sentinelDesc;
  13. }

6.2 系统规则配置

6.3 压测配置

6.4 浏览器测试

7、Sentinel 规则持久化

Dashboard控制台来为每个Sentinel客户端设置各种各样的规则,但是这里有一个问题,就是这些规则默认是存放在内存中,每次微服务重新启动,设置的各种规则都会消失。

7.1 方式1:本地文件(测试,线上不推荐)

本地文件数据源会定时轮询文件的变更,读取规则。这样我们既可以在应用本地直接修改文件来更新规则,也可以通过 Sentinel 控制台推送规则。

原理:首先 Sentinel 控制台通过 API 将规则推送至客户端并更新到内存中,接着注册的写数据源会将新的规则保存到本地的文件中。

7.1.1 配置类

创建配置类: SentinelFilePersistence

点击查看代码
  1. import com.alibaba.csp.sentinel.command.handler.ModifyParamFlowRulesCommandHandler;
  2. import com.alibaba.csp.sentinel.datasource.*;
  3. import com.alibaba.csp.sentinel.init.InitFunc;
  4. import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
  5. import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
  6. import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
  7. import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
  8. import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
  9. import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
  10. import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
  11. import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
  12. import com.alibaba.csp.sentinel.slots.system.SystemRule;
  13. import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
  14. import com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry;
  15. import com.alibaba.fastjson.JSON;
  16. import com.alibaba.fastjson.TypeReference;
  17. import lombok.extern.slf4j.Slf4j;
  18. import java.io.File;
  19. import java.io.IOException;
  20. import java.util.List;
  21. /**
  22. * Created On : 26/11/2022.
  23. * <p>
  24. * Author : huayu
  25. * <p>
  26. * Description: MySentinelRulePersistenceDunc
  27. */
  28. public class MySentinelRulePersistencefunc implements InitFunc{
  29. // String ruleDir = System.getProperty("user.home") + "/sentinel/rules/";
  30. //填写 规则存放的绝对路径
  31. String ruleDir = "D:/KEGONGCHANG/DaiMa/IDEA/KH96/SpringCloud/springcloud-alibaba-96/kgcmall96-sentinel/sentinel/rules/";
  32. // String ruleDir = "/kgcmall96-sentinel/sentinel/rules/";
  33. String flowRulePath = ruleDir + "/flow-rule.json";
  34. String degradeRulePath = ruleDir + "/degrade-rule.json";
  35. String systemRulePath = ruleDir + "/system-rule.json";
  36. String authorityRulePath = ruleDir + "/authority-rule.json";
  37. String paramFlowRulePath = ruleDir + "/param-flow-rule.json";
  38. @Override
  39. public void init() throws Exception {
  40. // 创建规则存放目录
  41. this.mkdirIfNotExits(ruleDir);
  42. // 创建规则存放文件
  43. this.createFileIfNotExits(flowRulePath);
  44. this.createFileIfNotExits(degradeRulePath);
  45. this.createFileIfNotExits(systemRulePath);
  46. this.createFileIfNotExits(authorityRulePath);
  47. this.createFileIfNotExits(paramFlowRulePath);
  48. // 注册一个可读数据源,用来定时读取本地的json文件,更新到规则缓存中
  49. // 流控规则
  50. ReadableDataSource<String, List<FlowRule>> flowRuleRDS =
  51. new FileRefreshableDataSource<>(flowRulePath, flowRuleListParser);
  52. // 将可读数据源注册至FlowRuleManager,这样当规则文件发生变化时,就会更新规则到内存
  53. FlowRuleManager.register2Property(flowRuleRDS.getProperty());
  54. WritableDataSource<List<FlowRule>> flowRuleWDS = new FileWritableDataSource<>(
  55. flowRulePath,
  56. this::encodeJson
  57. );
  58. // 将可写数据源注册至transport模块的WritableDataSourceRegistry中
  59. // 这样收到控制台推送的规则时,Sentinel会先更新到内存,然后将规则写入到文件中
  60. WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS);
  61. // 降级规则
  62. ReadableDataSource<String, List<DegradeRule>> degradeRuleRDS = new FileRefreshableDataSource<>(
  63. degradeRulePath,
  64. degradeRuleListParser
  65. );
  66. DegradeRuleManager.register2Property(degradeRuleRDS.getProperty());
  67. WritableDataSource<List<DegradeRule>> degradeRuleWDS = new FileWritableDataSource<>(
  68. degradeRulePath,
  69. this::encodeJson
  70. );
  71. WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleWDS);
  72. // 系统规则
  73. ReadableDataSource<String, List<SystemRule>> systemRuleRDS = new FileRefreshableDataSource<>(
  74. systemRulePath,
  75. systemRuleListParser
  76. );
  77. SystemRuleManager.register2Property(systemRuleRDS.getProperty());
  78. WritableDataSource<List<SystemRule>> systemRuleWDS = new FileWritableDataSource<>(
  79. systemRulePath,
  80. this::encodeJson
  81. );
  82. WritableDataSourceRegistry.registerSystemDataSource(systemRuleWDS);
  83. // 授权规则
  84. ReadableDataSource<String, List<AuthorityRule>> authorityRuleRDS = new FileRefreshableDataSource<>(
  85. authorityRulePath,
  86. authorityRuleListParser
  87. );
  88. AuthorityRuleManager.register2Property(authorityRuleRDS.getProperty());
  89. WritableDataSource<List<AuthorityRule>> authorityRuleWDS = new FileWritableDataSource<>(
  90. authorityRulePath,
  91. this::encodeJson
  92. );
  93. WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleWDS);
  94. // 热点参数规则
  95. ReadableDataSource<String, List<ParamFlowRule>> paramFlowRuleRDS = new FileRefreshableDataSource<>(
  96. paramFlowRulePath,
  97. paramFlowRuleListParser
  98. );
  99. ParamFlowRuleManager.register2Property(paramFlowRuleRDS.getProperty());
  100. WritableDataSource<List<ParamFlowRule>> paramFlowRuleWDS = new FileWritableDataSource<>(
  101. paramFlowRulePath,
  102. this::encodeJson
  103. );
  104. ModifyParamFlowRulesCommandHandler.setWritableDataSource(paramFlowRuleWDS);
  105. }
  106. private Converter<String, List<FlowRule>> flowRuleListParser = source -> JSON.parseObject(
  107. source,
  108. new TypeReference<List<FlowRule>>() {
  109. }
  110. );
  111. private Converter<String, List<DegradeRule>> degradeRuleListParser = source -> JSON.parseObject(
  112. source,
  113. new TypeReference<List<DegradeRule>>() {
  114. }
  115. );
  116. private Converter<String, List<SystemRule>> systemRuleListParser = source -> JSON.parseObject(
  117. source,
  118. new TypeReference<List<SystemRule>>() {
  119. }
  120. );
  121. private Converter<String, List<AuthorityRule>> authorityRuleListParser = source -> JSON.parseObject(
  122. source,
  123. new TypeReference<List<AuthorityRule>>() {
  124. }
  125. );
  126. private Converter<String, List<ParamFlowRule>> paramFlowRuleListParser = source -> JSON.parseObject(
  127. source,
  128. new TypeReference<List<ParamFlowRule>>() {
  129. }
  130. );
  131. private void mkdirIfNotExits(String filePath) throws IOException {
  132. File file = new File(filePath);
  133. if (!file.exists()) {
  134. file.mkdirs();
  135. }
  136. }
  137. private void createFileIfNotExits(String filePath) throws IOException {
  138. File file = new File(filePath);
  139. if (!file.exists()) {
  140. file.createNewFile();
  141. }
  142. }
  143. private <T> String encodeJson(T t) {
  144. return JSON.toJSONString(t);
  145. }
  146. }

7.1.2 InitFunc 文件

在resources文件下创建META-INF/services文件夹;

创建文档com.alibaba.csp.sentinel.init.InitFunc,文档名就是配置类实现接口的全类名;

在文件中添加第一步配置类的全类名即可;

测试:启动服务,当访问系统规则限流接口,自动创建目录和文件,添加规则后,重启服务,刚进来,之前的配置看不到,必须先访问对应的入口才可以,要注意

  1. com.kgc.scda.config.MySentinelRulePersistencefunc

8、Openfeign 远程调用

8.1 依赖

  1. <!-- openfeign 远程调用 -->
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-openfeign</artifactId>
  5. <version>2.1.1.RELEASE</version>
  6. </dependency>

8.2 配置

  1. # 整合Sentinel 和OpenFeign ,默认关闭
  2. feign:
  3. sentinel:
  4. enabled: true #开启

8.3 注解

  1. 著启动类: @EnableFeignClients
  2. 接口:@FeignClient(value = "服务名")

8.4 测试 (与单独使用Openfeign一样不在赘述)

9、GateWay 服务网关

9.1 依赖

  1. <!-- Gatway 网关会和springMvc冲突,不能添加web依赖 -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter</artifactId>
  5. </dependency>
  6. <!-- gateway 依赖 -->
  7. <dependency>
  8. <groupId>org.springframework.cloud</groupId>
  9. <artifactId>spring-cloud-starter-gateway</artifactId>
  10. </dependency>

9.2 配置

  1. # 端口
  2. server:
  3. port: 9606
  4. # 服务名
  5. spring:
  6. application:
  7. name: kgcmall-gatway
  8. cloud:
  9. #nacos 配置
  10. nacos:
  11. discovery:
  12. server-addr: 127.0.0.1:8848
  13. # 网关配置
  14. gateway:
  15. routes: # 路由,是list集合,可以配置多个路由
  16. #product模块
  17. - id: kh96_route_first # 当前route路由的唯一标识,不能重复
  18. #uri: http://localhost:9602 # 路由转发的目标资源地址,不支持多负载调用,不利于扩展,不推荐
  19. uri: lb://kgcmall96-prod # lb 从nacos注册中心的服务列表中,根据指定的服务名,调用服务,推荐用法
  20. predicates: # 指定路由断言配置,支持多个断言,只要断言成功(满足路由转发条件),才会执行转发到目标资源地址访问
  21. - Path=/prod-gateway/** # 指定path路径断言,必须满足请求地址是/prod-gateway开始,才会执行路由转发
  22. filters: # 指定路由过滤配置,支持多个过滤器,在断言成功,执行路由转发时,对请求和响应数据进行过滤处理
  23. - StripPrefix=1 # 在请求断言成功后,执行路由转发时,自动去除第一层的访问路径/prod-gateway
  24. #user模块
  25. - id: kh96_route_second
  26. uri: lb://kgcmall96-user
  27. predicates:
  28. - Path=/user-gateway/**
  29. filters:
  30. - StripPrefix=1

9.3 测试

9.3.1 nacos

9.3.2 请求测试

9.3.2.1 通过gateway网关调用prod模块

9.3.2.1 通过gateway网关调用user模块




原文链接:https://www.cnblogs.com/xiaoqigui/p/16931297.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号