深入解析:Sentinel 服务保护

Sentinel 服务保护

一、Sentinel 安装与集成

Sentinel是阿里巴巴开源的一款服务保护框架,目前已经加入SpringCloudAlibaba中。官方网站:Sentinel中国官网

1.1 Sentinel 安装

  • 下载 Sentinel 控制台 JAR 包,

    • 下载地址:https://github.com/alibaba/Sentinel/releases
  • 通过命令启动重命名为sentinel-dashboard.jar的jar包:

    • 启动命令示例:

      java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
    • 其它启动时可配置参数可参考官方文档:

      https://github.com/alibaba/Sentinel/wiki/%E5%90%AF%E5%8A%A8%E9%85%8D%E7%BD%AE%E9%A1%B9

  • sentinel控制台的当前访问地址:http://localhost:8090。

    • 输入账号和密码,默认都是:sentinel

1.2 项目集成配置

引入依赖
<!--sentinel-->
  <dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
  </dependency>
服务配置

开启feign对sentinel的支持,配置Sentinel服务信息,开启请求方式前缀:

feign:
okhttp:
enabled: true # 开启OKHttp连接池支持
sentinel:
enabled: true # 开启feign对sentinel的支持
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8090
http-method-specify: true # 开启请求方式前缀

二、服务保护方案配置

2.1 请求限流 (Flow Control)

作用
  • 流量平滑:控制接口访问的并发流量,使请求曲线平稳
  • 故障预防:避免流量激增导致系统故障
配置方式

服务中配置

// 通过注解配置
@SentinelResource(value = "resourceName", blockHandler = "blockHandlerMethod")
public String yourMethod() {
// 业务逻辑
}
// 限流处理方
public String blockHandlerMethod(BlockException ex) {
return "请求过于频繁,请稍后重试";
}

控制台配置:在流控规则中设置QPS或线程数阈值

2.2 线程隔离 (Thread Isolation)

作用
  • 资源隔离:限定接口可用资源范围,防止单服务影响整体系统
  • 故障隔离:避免服务故障扩散到整个系统
配置实现

服务中配置

@SentinelResource(
value = "threadIsolationDemo",
fallback = "fallbackMethod",
blockHandler = "blockHandlerMethod"
)

Sentinel控制台配置

  • 设置线程数限制
  • 配置超时时间
  • 定义降级策略

2.3 服务熔断 (Circuit Breaker)

作用
  • 异常熔断:当服务提供方异常比例过高时,自动拒绝调用
  • 降级保护:执行预设的降级逻辑,避免异常调用影响系统
FallbackFactory 降级实现方案

FallbackFactory,可以对远程调用的异常做处理,我们一般选择这种方式。

思路流程如下:

  1. 自定义类实现FallBackFactory并编写fallback逻辑
  2. 注册自定义的FeignClientFallBackFactory为Bean
  3. 在FeignClient接口中配置fallbackFactory属性
自定义降级工厂处理类

在api模块中给ItemClient定义降级处理类,实现FallbackFactory

package com.hmall.api.client.fallback;
import com.hmall.api.client.ItemClient;
import com.hmall.api.dto.ItemDTO;
import com.hmall.api.dto.OrderDetailDTO;
import com.hmall.common.exception.BizIllegalException;
import com.hmall.common.utils.CollUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import java.util.Collection;
import java.util.List;
@Slf4j
public class ItemClientFallback implements FallbackFactory<ItemClient> {
  @Override
  public ItemClient create(Throwable cause) {
  return new ItemClient() {
  @Override
  public List<ItemDTO> queryItemByIds(Collection<Long> ids) {
    log.error("远程调用ItemClient#queryItemByIds方法出现异常,参数:{}", ids, cause);
    // 查询购物车允许失败,查询失败,返回空集合
    return CollUtils.emptyList();
    }
    @Override
    public void deductStock(List<OrderDetailDTO> items) {
      // 库存扣减业务需要触发事务回滚,查询失败,抛出异常
      throw new BizIllegalException(cause);
      }
      };
      }
      }
注册自定义的FeignClientFallBackFactory为Bean

api模块中的com.hmall.api.config.DefaultFeignConfig类中将ItemClientFallback注册为一个Bean

package com.hmall.api.config;
import com.hmall.api.client.fallback.ItemClientFallBackFactory;
import com.hmall.common.utils.UserContext;
import feign.Logger;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Bean;
public class DefaultFeginConfig {
@Bean
public Logger.Level feignLogLevel(){
return Logger.Level.FULL;
}
@Bean
public RequestInterceptor userInfoRequestInterceptor(){
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate requestTemplate) {
// 获取用户信息
Long userId = UserContext.getUser();
if (userId == null){
return;
}
// 将用户信息传递给下一个微服务
requestTemplate.header("user-info", userId.toString());
}
};
}
@Bean
public ItemClientFallBackFactory itemClientFallBackFactory(){
return new ItemClientFallBackFactory();
}
}
在FeignClient接口中配置fallbackFactory属性

api模块中的ItemClient接口中使用ItemClientFallbackFactory

package com.hmall.api.client;
import com.hmall.api.client.fallback.ItemClientFallBackFactory;
import com.hmall.api.config.DefaultFeginConfig;
import com.hmall.api.dto.ItemDTO;
import com.hmall.api.dto.OrderDetailDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Collection;
import java.util.List;
/**
* @author Peter Pang
*/
@FeignClient(value = "item-service",
configuration = DefaultFeginConfig.class,
fallbackFactory = ItemClientFallBackFactory.class)
public interface ItemClient {
@GetMapping("/items")
List<ItemDTO> queryItemByIds(@RequestParam("ids")Collection<Long> ids);
  @PutMapping("/items/stock/deduct")
  void deductStock(@RequestBody Collection<OrderDetailDTO> items);
    }
断路器状态机工作原理
状态描述行为
Closed关闭状态- 放行所有请求
- 统计异常比例和慢调用比例
- 超过阈值时切换到Open状态
Open打开状态- 服务调用被熔断
- 请求快速失败,直接执行降级逻辑
- 持续一段时间后进入Half-Open状态
Half-Open半开状态- 放行一次试探请求
- 成功:切换到Closed状态
- 失败:切换回Open状态

三、核心配置参数

3.1 限流参数

  • QPS:每秒请求数限制
  • 线程数:并发线程数限制
  • 流控模式:直接、关联、链路
  • 流控效果:快速失败、Warm Up、排队等待

3.2 熔断参数

  • 慢调用比例:响应时间超过阈值的请求比例
  • 异常比例:请求异常的比例阈值
  • 异常数:时间窗口内的异常数量
  • 最小请求数:触发熔断的最小请求数
  • 统计窗口时间:熔断统计的时间范围

四、最佳实践建议

  1. 合理设置阈值:根据系统实际承载能力配置限流参数
  2. 分级降级:设计多级降级策略,保证核心功能可用
  3. 监控告警:配置Sentinel监控告警,及时发现问题
  4. 测试验证:定期进行压力测试,验证保护策略有效性
  5. 日志记录:完善降级日志,便于问题排查和分析

通过以上配置,Sentinel能够有效保护微服务系统,提高系统的稳定性和容错能力。

posted @ 2025-12-22 09:33  gccbuaa  阅读(0)  评论(0)    收藏  举报