目录
Sentinel概述
基本介绍
Sentinel 基本核心概念
Sentinel安装
简单安装启动
启动配置项
SpringCloud简单整合
实战架构
父工程pom文件
teacher-service服务
student-service服务
测试
整合Sentinel
Sentinel是阿里巴巴开源的一款微服务流量控制组件。官网地址:home | Sentinel
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
Sentinel 具有以下特征:
•丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
•完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
•广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
•完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等
早期比较流行的是Hystrix框架,但目前国内实用最广泛的还是阿里巴巴的Sentinel框架,这里我们做下对比:
Sentinel | Hystrix | |
隔离策略 | 信号量隔离 | 线程池隔离/信号量隔离 |
熔断降级策略 | 基于慢调用比例或异常比例 | 基于失败比率 |
实时指标实现 | 滑动窗口 | 滑动窗口(基于 RxJava) |
规则配置 | 支持多种数据源 | 支持多种数据源 |
扩展性 | 多个扩展点 | 插件的形式 |
基于注解的支持 | 支持 | 支持 |
限流 | 基于 QPS,支持基于调用关系的限流 | 有限的支持 |
流量整形 | 支持慢启动、匀速排队模式 | 不支持 |
系统自适应保护 | 支持 | 不支持 |
控制台 | 开箱即用,可配置规则、查看秒级监控、机器发现等 | 不完善 |
常见框架的适配 | Servlet、Spring Cloud、Dubbo、gRPC 等 | Servlet、Spring Cloud Netflix |
资源
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。
只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
规则
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。
sentinel官方提供了UI控制台,方便我们对系统做限流设置。可以在GitHub下载。
Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。这里,我们将会详细讲述如何通过简单的步骤就可以使用这些功能。
Sentinel 控制台包含如下功能:
下载地址: https://github.com/alibaba/Sentinel/releases
将jar包放到任意非中文目录
启动jar包:
java -jar sentinel-dashboard-1.8.1.jar
指定端口:
java -jar sentinel-dashboard-1.8.1.jar -Dserver.port=8090
修改其他配置看官网: https://sentinelguard.io/zh-cn/
访问 localhost:8080 默认账号密码都是:sentinel
可以看到现在是一片空白的,稍后整合服务以后就可以出现信息的。
Sentinel 提供如下的配置方式:
其中,project.name
参数只能通过 JVM -D 参数方式配置(since 1.8.0 取消该限制),其它参数支持所有的配置方式。
优先级顺序:JVM -D 参数的优先级最高。若 properties 和 JVM 参数中有相同项的配置,以 JVM 参数配置的为准。
用户可以通过 -Dcsp.sentinel.config.file
参数配置 properties 文件的路径,支持 classpath 路径配置(如 classpath:sentinel.properties
)。默认 Sentinel 会尝试从 classpath:sentinel.properties
文件读取配置,读取编码默认为 UTF-8。
如果要修改Sentinel的默认端口、账户、密码,可以通过下列配置:
配置项 | 默认值 | 说明 |
---|---|---|
server.port | 8080 | 服务端口 |
sentinel.dashboard.auth.username | sentinel | 默认用户名 |
sentinel.dashboard.auth.password | sentinel | 默认密码 |
我们进行整合的时候,先搭建一个简单的微服务项目架构。
俩个为俩个不同的端口的service端,客户端向8002端口的studentservice发送一个请求(/getInfo/{id})以后,8002端口的studentservice需要往teacherservice发送一个请求(/getTeacher/{id})返回数据。
统一管理版本信息
org.example
eurek-test
1.0-SNAPSHOT
eurek-serve
student-service
teacher-service
pom
org.springframework.boot
spring-boot-starter-parent
2.3.12.RELEASE
UTF-8
UTF-8
1.8
Hoxton.SR10
5.1.47
2.1.1
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2.2.5.RELEASE
pom
import
org.projectlombok
lombok
pom文件
org.springframework.boot
spring-boot-starter-web
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
启动类
@SpringBootApplication
public class TeacherApplication {
public static void main(String[] args) {
SpringApplication.run(TeacherApplication.class,args);
}
}
yml配置文件
server:
port: 8002
spring:
application:
name: teacherservice
cloud:
nacos:
server-addr: localhost:8848
Teacher类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher implements Serializable {
private String name;
private String sex;
}
TeachertController
@RestController
public class TeacherController {
@GetMapping("/getTeacher/{id}")
public Teacher getInfo(@PathVariable("id") String id){
return new Teacher("张三-"+id,"男");
}
}
pom文件
org.springframework.boot
spring-boot-starter-web
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
org.springframework.cloud
spring-cloud-starter-openfeign
yml配置文件
server:
port: 8002
spring:
application:
name: studentservice
cloud:
nacos:
server-addr: localhost:8848
启动类
@SpringBootApplication
@EnableFeignClients
public class StudentApplication {
public static void main(String[] args) {
SpringApplication.run(StudentApplication.class,args);
}
}
Teacher类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher implements Serializable {
private String name;
private String sex;
}
TeacherServiceFeign
@FeignClient("teacherservice")
public interface TeacherServiceFeign {
@GetMapping("/getTeacher/{id}")
Teacher getInfo(@PathVariable("id") String id);
}
个客户端主要是基于SpringMVC的注解来声明远程调用的信息,比如:
服务名称:teacherservice
请求方式:GET
请求路径:/getTeacher/{id}
请求参数:String id
返回值类型:Teacher
这样,Feign就可以帮助我们发送http请求,无需自己使用RestTemplate来发送了。
StudentController
@RestController
public class StudentController implements Serializable {
@Autowired
TeacherServiceFeign teacherServiceFeign;
@GetMapping("/getInfo")
public Teacher getInfo(){
Teacher teacher = teacherServiceFeign.getInfo("111");
return teacher;
}
}
GET http://localhost:8002/getInfo
HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Date: Tue, 17 Oct 2023 02:46:43 GMT
Keep-Alive: timeout=60
Connection: keep-alive{
"name": "张三-111",
"sex": "男"
}
我们在student-service服务的pom文件中添加以下依赖:
com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel
修改application.yaml文件,添加下面内容:
server:
port: 8088
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080
重新启动student-service。
GET http://localhost:8002/getInfo
HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 26 Oct 2023 02:58:44 GMT
Keep-Alive: timeout=60
Connection: keep-alive{
"name": "张三-111",
"sex": "男"
}
查看sentinel控制台:
但注意默认只有controller中的方法会被监控,Service层的方法没有被监控,也就不能配置限流规则,要标记其它方法,需要利用@SentinelResource注解。
链路模式中,是对不同来源的两个链路做监控。但是sentinel默认会给进入SpringMVC的所有请求设置同一个root资源,会导致链路模式失效。
我们需要关闭这种对SpringMVC的资源聚合,修改服务的application.yml文件:
spring: cloud: sentinel: web-context-unify: false # 关闭context整合