目录
- 一、简介
- Sentinel 是什么
- 如何引入Sentinel
- 二、服务搭建
- 1.安装Sentinel控制台
- 1.1 下载
- 1.2 启动
- 1.3 访问
- 2.改造服务提供者cloud-provider服务
- 2.1 引入依赖
- 2.2 添加API
- 2.3 添加配置文件
- 3.改造cloud-consumer-feign服务
- 3.1 引入依赖
- 3.2 添加Feign接口
- 3.3 添加服务降级类
- 3.4 改造FeignService
- 3.5 修改配置文件
- 三、运行测试
- 1.启动项目
- 1.1 启动服务提供者
- 1.2 启动服务消费者
- 2.调用测试接口
- 2.1 OpenFeign服务降级测试
- 2.2 Sentinel流控规则测试
温馨提示:全套教程请查看 教程总览
一、简介
Sentinel 是什么
Sentinel是分布式系统的流量防卫兵。
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应过载保护、热点流量防护等多个维度保护服务的稳定性。
Sentinel 具有以下特征:
- 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控:Sentinel 同时提供实时的监控功能。我们可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
- 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Apache Dubbo、gRPC、Quarkus 的整合。我们只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。同时 Sentinel 提供Java/Go/C++ 等多语言的原生实现。
- 完善的 SPI 扩展机制:Sentinel 提供简单易用、完善的 SPI 扩展接口。我们可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
Sentinel 分为两个部分:
- 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
- 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
如何引入Sentinel
如果要在我们的项目中引入 Sentinel,使用 group ID 为 com.alibaba.cloud
和 artifact ID 为 spring-cloud-starter-alibaba-sentinel
的 starter。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
参考文档 请查看 官网
二、服务搭建
1.安装Sentinel控制台
1.1 下载
Sentinel提供了多种安装方式,包括:
- 下载源码通过Maven构建
- 下载发行包解压安装
这里我们通过下载 最新稳定版本 发行包的方式安装。
1.2 启动
注意:启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
其中 -Dserver.port=8080
用于指定 Sentinel 控制台端口为 8080
。
1.3 访问
打开浏览器访问:http://localhost:8080/
默认用户名和密码都是 sentinel
。
2.改造服务提供者cloud-provider服务
有关 cloud-provider
服务的搭建过程,请参考之前的章节 基于Spring Boot 3.x 搭建教程
2.1 引入依赖
pom.xml
内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.ash</groupId>
<artifactId>spring-cloud-alibaba-demo</artifactId>
<version>${revision}</version>
</parent>
<artifactId>cloud-provider</artifactId>
<description>服务提供者</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Nacos注册中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Nacos配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- bootstrap配置 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--alibaba-sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 打包插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<!-- 将源码中的xml文件打包到jar中 -->
<resources>
<resource>
<directory>src/main/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</build>
</project>
2.2 添加API
新建 TestSentinelController.java
,添加测试API,并且定义sentinel资源
Sentinel 提供了
@SentinelResource
注解用于定义资源,并提供了 AspectJ 的扩展用于自动定义资源、处理 BlockException 等。
value
:资源名称,必需项(不能为空)blockHandler / blockHandlerClass
:blockHandler
对应处理BlockException
的函数名称,可选项。blockHandler
函数访问范围需要是public
,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为BlockException
。blockHandler
函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定blockHandlerClass
为对应的类的Class
对象,注意对应的函数必需为static
函数,否则无法解析。
内容如下:
package org.ash.provider.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestSentinelController {
@GetMapping("/provider/sentinel/test/{message}")
@SentinelResource(value = "providerSentinelTest", blockHandler = "handlerBlockHandler")
public String providerSentinelTest(@PathVariable("message") String message) {
return "sentinel测试:" + message;
}
public String handlerBlockHandler(@PathVariable("message") String message, BlockException exception) {
return "providerSentinelTest服务不可用," + "触发sentinel流控配置规则"+"\t"+"o(╥﹏╥)o";
}
}
2.3 添加配置文件
resources目录下新建 application.yml
配置文件,内容如下:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 #配置Sentinel dashboard控制台服务地址
port: 8719 #默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
3.改造cloud-consumer-feign服务
有关 cloud-consumer-feign
服务的搭建过程,请参考之前的章节 基于Spring Boot 3.x 搭建教程
3.1 引入依赖
pom.xml
内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.ash</groupId>
<artifactId>spring-cloud-alibaba-demo</artifactId>
<version>${revision}</version>
</parent>
<artifactId>cloud-consumer-feign</artifactId>
<description>服务消费者-feign</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Nacos注册中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- loadbalancer负载均衡 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 打包插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<!-- 将源码中的xml文件打包到jar中 -->
<resources>
<resource>
<directory>src/main/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</build>
</project>
3.2 添加Feign接口
在 FeignService.java
中新增调用服务提供者接口
内容如下:
package org.ash.consumer.feign.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value = "cloud-provider")
public interface FeignService {
@GetMapping("/provider/test/{message}")
public String getProviderTest(@PathVariable("message") String message);
@GetMapping("/provider/sentinel/test/{message}")
public String providerSentinelTest(@PathVariable("message") String message);
}
3.3 添加服务降级类
新建 FeignServiceFallback.java
服务降级类,实现 FeignService.java
并实现方法
内容如下:
package org.ash.consumer.feign.service.fallback;
import org.ash.consumer.feign.service.FeignService;
import org.springframework.stereotype.Component;
@Component
public class FeignServiceFallback implements FeignService {
@Override
public String getProviderTest(String message) {
return "对方服务不可用,开始服务降级处理";
}
@Override
public String providerSentinelTest(String message) {
return "对方服务不可用,开始服务降级处理";
}
}
3.4 改造FeignService
改造 FeignService.java
的 @FeignClient
注解,添加 fallback
属性
内容如下:
package org.ash.consumer.feign.service;
import org.ash.consumer.feign.service.fallback.FeignServiceFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value = "cloud-provider", fallback = FeignServiceFallback.class)
public interface FeignService {
@GetMapping("/provider/test/{message}")
public String getProviderTest(@PathVariable("message") String message);
@GetMapping("/provider/sentinel/test/{message}")
public String providerSentinelTest(@PathVariable("message") String message);
}
3.5 修改配置文件
默认 sentinel 对 feign 的支持是关闭的,我们需要在配置文件中打开。
内容如下:
server:
port: 9003
spring:
application:
# 服务名称
name: cloud-consumer-feign
cloud:
nacos:
# nacos注册中心
discovery:
# 服务ip:port
server-addr: 127.0.0.1:8848
openfeign:
client:
config:
default:
#连接超时时间
connectTimeout: 5000
#读取超时时间
readTimeout: 5000
# 开启feign集成sentinel服务降级
feign:
sentinel:
enabled: true
management:
endpoints:
web:
exposure:
include: '*'
三、运行测试
1.启动项目
1.1 启动服务提供者
1.2 启动服务消费者
2.调用测试接口
2.1 OpenFeign服务降级测试
打开浏览器调用我们之前写的测试接口 http://localhost:9003/consumer/feign/sentinel/test/sentinel
,成功返回消息
这时我们停止服务提供者 cloud-provider
服务
然后再次通过浏览器调用测试接口 http://localhost:9003/consumer/feign/sentinel/test/sentinel
,看到返回服务降级的信息,表示服务降级成功
2.2 Sentinel流控规则测试
重新启动 cloud-provider
服务提供者
再次通过浏览器调用测试接口 http://localhost:9003/consumer/feign/sentinel/test/sentinel
,然后打开Sentinel 控制台,刷新页面,找到测试接口添加流控规则
- 流控规则
资源名
对应代码@SentinelResource
的value
值。- 流控规则
单机阈值
为1
表示1秒钟内请求1次就是正常,若超过1次,就会失败,执行服务提供者的blockHandler
通过浏览器快速调用测试接口 http://localhost:9003/consumer/feign/sentinel/test/sentinel
,查看是否返回流控配置规则消息,如果返回流控配置规则消息,则表示 Sentinel 流控规则配置成功。
至此,OpenFeign集成Sentinel实现服务降级成功!!!
温馨提示:全套教程请查看 教程总览