在微服务架构中,服务和服务之间的稳定性变得越来越重要,Sentinel以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
1、Sentinel Sentinel 是阿里巴巴开源的分布式系统的流量防卫组件。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
Sentinel基本概念(摘自官网):
- 资源:是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码;只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
- 规则:围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整;
Sentinel主要功能(摘自官网):
-
流量控制:流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据。然而,从系统稳定性角度考虑,在处理请求的速度上,也有非常多的讲究。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状; -
熔断降级:当调用链路中某个资源出现不稳定,例如,表现为 timeout,异常比例升高的时候,则对这个资源的调用进行限制,并让请求快速失败,避免影响到其它的资源,最终产生雪崩的效果; -
系统负载保护:Sentinel 同时提供系统维度的自适应保护能力;让系统的入口流量和系统的负载达到一个平衡,保证系统在能力范围之内处理最多的请求;
2、springcloud+sentinel实例 Sentinel的使用分为两种方式:
- 核心库:java客户端,不依赖任何框架/库,能够运行于java 8及以上版本的运行时环境,同时对Dubbo/Spring Cloud等框架也有较好的支持;
- 控制台:Dashboard,主要负责管理推送规则,监控,管理机器等;
下面在Spring Cloud应用中使用Sentinel starter实现限流管理。
①下载、安装、启动 下载地址:https://github.com/alibaba/Sentinel/tags 此处下载1.8.0版本,通过如下命令启动:
java -jar sentinel-dashboard-1.8.0.jar
默认情况下sentinel-dashboard以8080端口启动,所以可以通过访问localhost:8080来验证是否已经成功启动。 默认的登录账号为:用户名:sentinel,密码:sentinel。 ②springcloud整合sentinel a.添加pom依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
此处依赖的alibaba版本为2021.1,对应的sentinel版本为1.8.0。 b.配置yml
# 限流
sentinel:
transport:
dashboard: localhost:8080
c.启动服务,访问接口,因为访问接口以后才会注册到sentinel中。
此时就可以看到order服务实例了。 d.实时监控,可以查看接口访问情况,如下: e.在簇点链路中,对指定接口配置限流规则,如下: 其中,阈值类型选择QPS,单机阈值为2,则该限流规则为每秒最多允许2个请求进入。若每秒超过2次时被流控,如下: 自定义流控返回:
@GetMapping("/hello2")
@SentinelResource(value = "hello2",blockHandler = "handleException")
public String hello2() {
return "hello, this is order service";
}
public String handleException(BlockException e) {
return "你已被流控" + e;
}
value将该方法定义为sentinel的资源,blockHandler是流控时调用的方法,如下: 注:方法返回类型必须和兜底方法返回类型一致;不要将blockHandler打错,打成了blockedHandler;不要将BlockException打错,打成了BlockException;流控规则里的资源名必须和@SentinelResource注解声明的资源一致; 自定义全局流控返回:
@Slf4j
@Component
public class GlobalExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException ex) throws Exception {
log.info("===>流控自定义返回");
response.setContentType("application/json;charset=utf-8");
response.setStatus(200);
response.getWriter().write("你已被流控");
}
}
请求返回如下: f.熔断降级 RT指平均响应时间超出阈值且通过的请求>=5,阈值为0.1时触发降级。 慢调用,假设在 1秒内(统计时长=1000ms) 有10个请求过来(满足了最小请求数5), 这10个请求 中有4个请求的响应时间超过了300ms(最大RT300),属于慢调用。 10个请求乘以比例阈值0.1 = 1。 4个慢请求 > 1 (阈值比例)。 所以触发熔断,熔断时长10秒。 使用jmeter调用接口,如下 通过浏览器再次访问,如下 也可以自定义返回,同流控。
g.OpenFeign整合Sentinel 添加配置
# 开启openFeign对sentinel的整合
feign:
sentinel:
enabled: true
openFeign调用接口
@FeignClient(value = "mall-product", contextId = "product", fallback = ProductFeignFallbackClient.class)
public interface ProductFeignClient {
/**
* 远程调用product微服务的hello接口
* @return
*/
@GetMapping("/product/hello")
String getHello();
}
添加fallback对应的失败时回调的实现类
@Slf4j
@Component
public class ProductFeignFallbackClient implements ProductFeignClient {
@Override
public String getHello() {
log.error("feign远程调用服务异常后的降级方法");
return "feign远程调用服务异常后的降级方法";
}
}
当接口请求失败时便会调用失败类里的方法,这里不启动远程服务调用的product服务,访问结果如下: 后续还需在工程化应用时不断深入理解原理和场景,加油吧,少年。
|