随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。
简单的来说 sentinel和hystrix所起的作用相差无几,不过sentinel是可以通过控制台来进行配置,减少了代码的编写,提高了灵活性。
sentinel提供两种方式与springcloud的整合,一种是控制台(sentinel提供的jar包)+客户端(被监控的微服务),一种是直接在代码工程里面编写配置,个人比较推荐前者,因为可以灵活配置,而后者再变更时则需要修改代码。
链接: 下载jar包地址.
(此处是的版本是1.8,window版本,其他版本请自行选择)
使用命令提示框输入:java -jar sentinel-dashboard.jar
出现以上画面启动成功。
访问:localhost:8080
客户端pom引入
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
server:
port: 8401
spring:
application:
name: cloud-sentinel-service
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080
port: 8719
spring.cloud.sentinel.transport.dashboard:控制台地址
@SpringBootApplication
@EnableDiscoveryClient
public class SentinelMain8401 {
public static void main(String[] args) {
SpringApplication.run(SentinelMain8401.class,args);
}
}
为了方便测试sentinel的功能,所以写一个简单的业务类。
FlowLimitController
@RestController
@Slf4j
public class FlowLimitController {
@GetMapping("/testA")
public String getTestA(){
return "this is testA!!!";
}
}
今天主要学习流量控制,熔断降级,热点参数限流功能。
1.启动控制台
2.启动客户端
(首次启动客户端,请求不会立即被控制台监控,因为setinel使用了懒加载,所以需要主动访问一次以客户端请求)
下面测试一下 :“直接”模式,和“快速失败”的流控效果
设置QPS阈值为1,流控模式:直接,流控效果:快速失败
访问:http://localhost:8401/testA
修改业务类,添加睡眠1s,设置RT为200ms
FlowLimitController
@RestController
@Slf4j
public class FlowLimitController {
@GetMapping("/testA")
public String getTestA(){
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "this is testA!!!";
}
}
访问:http://localhost:8401/testA
使用jemter进行压测,设置1秒钟同时10个请求一起访问,
热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。
比如:当请求中第一个参数的时候,限流规则触发,当为其他参数的时候限流规则则不被触发。
要使用热点参数限流功能,需要引入以下依赖:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-parameter-flow-control</artifactId>
</dependency>
修改业务类:
FlowLimitController
@RestController
@Slf4j
public class FlowLimitController {
@GetMapping("/getId/{id}")
@SentinelResource(value = "getId")
public String getId(@PathVariable("id") String id){
return "热点key值限流"+id;
}
}
@SentinelResource注解标记此资源为sentinel监控资源,资源名为 getId
控制台配置:
访问:http://localhost:8401/getId/1
每秒单次点击正常返回:
每秒多次点击,则被限流
除此之外还可以在高级选项中设置参数例外项,当设置的参数为某一值的时候,则执行另一套限流规则。
说明如下:
作用一:标记监控资源的名称,唯一标识
在上述功能测试中发现 在流量控制和熔断降级中资源名为访问路径名,而在热点中使用了@SentinelResource标记了监控资源名称。
作用二:设置统一的流量控制响应
例如:
@SentinelResource(value = “getId”, blockHandlerClass = BlockHandler.class ,blockHandler = “getId”)
表示如果发生流控,那么就会调用BlockHandler类中的getId方法作为自定义的流控响应。
作用三:设置统一的异常响应(fallback)
sentinel中流控规则的异常通常(异常数除外)只能捕捉到超过控制台设置的异常,并不能捕捉到系统中的代码异常,所以@SentinelResource支持设置异常响应fallback
比如:
@SentinelResource(value = “getId”,fallbackClass = BlockHandler.class,fallback = “getId”)
表示若是发生异常,则会调用BlockHandler类中的getId作为异常响应结果返回。
同样sentinel的监控同样支持rpc框架,如:RestTemplate,feign。
RestTemplate在实例化的时候,添加@SentinelRestTemplate即可。
sentinel对fegin做了整合,所以兼容fegin,只需要在配置文件中开启,fegin对sentinel的支持即可:feign.sentinel.enabled=true
以上两种配置具体可以参照官网:sentinel配合RPC.
通过以上测试发现,每次在重新启动客户端服务时,sentinel控制台的配置都会消失,需要重新配置规则。若是在平时测试当中那勉强尚可,但是一旦正式使用,就让人抓狂。
所以将sentinel持久化配置迫在眉睫。
sentinel持久化的解决方案:
将sentinel的配置保存在配置中心,如nacos中(不清楚nacos的同学点击这里),由配置中心完成持久化。
以nacos为例
第一步:引入pom
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
第二步:配置文件
server:
port: 8401
spring:
application:
name: cloud-sentinel-service
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080
port: 8719
datasource:
ds1:
nacos:
server-addr: 127.0.0.1:8848
dataId: ${spring.application.name}
groupId: DEFAUT_GROUP
data-type: json
rule-type: flow
nacos:
discovery:
server-addr: 127.0.0.1:8848
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
官网教程地址.
规则含义
resource 资源名,即规则的作用对象
grade 熔断策略,支持慢调用比例/异常比例/异常数策略 慢调用比例
count 慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值
timeWindow 熔断时长,单位为 s
minRequestAmount 熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入) 5
statIntervalMs 统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入) 1000 ms
slowRatioThreshold 慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)
至此,sentinel的持久化完成。
sentinel的很多功能其实在实践中才能更好的体会,所以此篇文章作为学习记录和交流。欢迎大家指正。