sentinel

# Sentinel ## Sentinel和Hystrix的比较 ![image.png](https://cos.easydoc.net/13568421/files/lmtzt8tk) ### 什么是线程池隔离? > **线程池隔离即, 给每一个自定义或路径资源都创建一个线程池, 线程池里面有有限的线程, 通过有限的线程来实现限流等** #### 线程池隔离的优缺 ##### 优点 > 使用线城市隔离能非常彻底地隔离多个资源 ##### 缺点 > **如果使用线程池隔离, 当资源变多的时候, 所需要的线程池也变多, 在大量线程池的情况下, 线程和线程池的维护成本变得非常高, 消耗很多的系统资源, 因此, <font color="red">线程池资源总体来说是不推荐的</font>** ### 什么是信号量隔离? > **信号量隔离即每个资源都有对应的信号量, 通过获取信号量才能执行逻辑, 类似于秒杀服务的信号量** ##### 优点 > 维护成本低 ##### 缺点 > 不能达到彻底的隔离 ## Sentinel的介绍 [官网文档](https://sentinelguard.io/zh-cn/docs/basic-api-resource-rule.html) **(认真看完!!!)** ## 整合Sentinel 1. 下载[控制台](https://github.com/alibaba/Sentinel/releases/tag/1.7.1) 2. 引入依赖 ```xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel</artifactId> </dependency> ``` 3. 配置文件 ```yaml spring: cloud: sentinel: transport: dashboard: localhost:9912 ``` 4. 启动sentinel ```bash java -jar -Dserver.port=9912 sentinel-dashboard-1.7.1.jar ``` 5. 测试 ![image.png](https://cos.easydoc.net/13568421/files/lmu2b3g4.png) ### 相关说明 #### 为什么一开始Sentinel页面时空白的 > Sentinel使用了懒加载, 如果不发请求, 对应的资源和监控信息都没有, 我们发送请求才会有 #### yaml说明 > 这里有两个端口, 一个端口是sentinel的bashboard可视化界面启动的端口, 另一个端口是dashboard与程序连接的端口 ## 整合actuator ### 什么是actuator > 在Springboot的时候, 已经讲过actuator了, **actuator依赖可以实时监控微服务的健康状态** ## 如何整合 1. 引入依赖 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> ``` 2. 配置 ```yaml management: endpoints: web: exposure: include: "*" ``` 3. 测试 ![image.png](https://cos.easydoc.net/13568421/files/lmu9np1s.png) ![image.png](https://cos.easydoc.net/13568421/files/lmu9rgbx.png) ## 自定义流控响应 ### 普通微服务的流控响应设置 ```java @Configuration @Slf4j public class SentinelConfig { /** * 自定义流控详情 */ public SentinelConfig() { WebCallbackManager.setUrlBlockHandler((httpServletRequest, httpServletResponse, e) -> { httpServletResponse.sendRedirect("http://bitmall.com/static/error/index.html"); }); } } ``` ### 网关的流控响应设置(配置文件) ```yaml sentinel: scg: fallback: mode: redirect redirect: http://bitmall/static/error/index.html ``` > **上面是第一种模式(重定向模式), 一旦网关发生了流控或降级, 立刻重定向到指定网址** ```yaml sentinel: scg: fallback: mode: response response-status: 403 # 响应状态 response-body: error # 响应体 content-type: application/json # 内容类型 ``` > 上面是第二种模式(响应体模式), 一旦网管发生流控或降级, 立刻按照上面的形式相应 ### 网关的流控响应设置(代码) ```java @Configuration public class SentinelConfig { /** * 自定义流控降级返回 */ public SentinelConfig() { GatewayCallbackManager.setBlockHandler((serverWebExchange, throwable) -> // ServerResponse.ok() 返回的状态为成功 // .body() 响应体里面的内容 // Mono.just(T t) 放一个响应的内容进去 // String.class 响应内容的类型 ServerResponse.ok().body(Mono.just("错误数据"), String.class) ); } } ``` [更多请了解响应式编程(老文档)](doc:BgtipYHW) # Bug ## RabbitMQ的循环依赖问题 ### 为什么会发生循环依赖问题? ![image.png](https://cos.easydoc.net/13568421/files/lmu8uaep.png) ![image.png](https://cos.easydoc.net/13568421/files/lmu8unlp.png) > 因为在Redis的自动配置类中, 其构造器注入了消息转换器, 该消息转换器在我们的配置类中定义了, 在我们的配置类中, 注入了自动配置类的RabbitTemplate, 造成了循环依赖问题 ### 如何解决循环依赖问题 ![image.png](https://cos.easydoc.net/13568421/files/lmu9csl2.png) > **用一个静态内部类解决循环依赖问题, 因为这个静态内部类本质是一个独立的对象, 整体来说, RabbitMQConfig依赖RabbitTemple, 而RabbitTemplate依赖静态内部类的对象, 并不是Config对象了, 因此可以解决循环依赖问题**