参考:Sentinel实现熔断与限流https://blog.csdn.net/qq_42200163/article/details/110038554
参考:SentinelResource注解使用详解https://blog.csdn.net/weixin_42073629/article/details/107117585
一、背景
使用Sentinel来自动切换开关,当发现出现某个异常达到指定数量的时候,触发切换资源不可用的开关
二、Sentinel简介
2.1 Sentinel介绍
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
2.2 Sentinel特征
丰富的应用场景
:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
完备的实时监控
:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态
:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
完善的 SPI 扩展点
:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
2.3、Sentinel的开源生态
2.4 相关地址
1、官网地址
2、中文官网
3、参考文档
三、Sentienl 部署
3.1 组成
3.2 下载地址
下载地址,推荐使用自带浏览器下载,下载速度会很快
3.3 启动
nohup java -jar -Xms256m -Xmx256m -XX:PermSize=512M -XX:MaxPermSize=512m sentinel-dashboard-1.7.0.jar &
- 1
四、Sentinel配置流程规则
4.1 新建Spring-boot工程
- 引入pom依赖
<modelVersion>4.0.0</modelVersion>
<artifactId>sentinel-demo</artifactId>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>com.ssg.demos</groupId>
<artifactId>demo-common</artifactId>
<version>${project.version}</version>
</dependency>
<!--sentinel-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>0.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-common</artifactId>
<version>1.6.1</version>
</dependency>
<!--sentinel end-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>0.9.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 配置application.yml
spring:
application:
name: sentinel-demo
cloud:
sentinel:
transport:
dashboard: localhost:8080
eager: true
- springboot启动类
@Configuration
@SpringBootApplication(scanBasePackages={"com.ssg.demo*"})
@ServletComponentScan
public class SentinelApplication {
public static void main(String[] args) {
SpringApplication.run(SentinelApplication.class, args);
}
// 注解支持的配置Bean
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
}
-
RedisService
/**
* 普通缓存放入
*
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
if (e instanceof RedisConnectionFailureException) {
redisExceptionHelper.processRedisException();
}
return false;
}
}
- Redis连接异常处理类,RedisExceptionHelper类需要使用Service注解,方法上使用SentinelResource注解配置异常兜底方法blockHandler
@Service
public class RedisExceptionHelper {
private static final Logger logger = LoggerFactory.getLogger(RedisExceptionHelper.class);
@SentinelResource(value = "redisExceptionHandler", blockHandler = "handleRedisException")
public void processRedisException() {
logger.warn("process redis exception...");
}
public void handleRedisException(BlockException exception){
// 关闭redis可用开关
logger.info("connect redis fail, turn redis switch off");
}
}
- Sentinel配置流程规则
- 测试结果,Sentinel监控到拒绝数据
- 业务服务端日志,拒绝和通过分别如下