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对象了, 因此可以解决循环依赖问题**