SpringBoot + Sentinel +Nacos 构建微服务高可用防护体系

0 阅读14分钟

微服务高可用实战:SpringBoot+Sentinel+Nacos 熔断降级限流全方案

在微服务架构中,服务依赖如同多米诺骨牌,一个服务故障可能引发连锁反应,最终导致整个系统雪崩。尤其是大促活动、流量突增等场景,传统的静态防护手段早已难以应对动态变化的业务需求。本文将基于 SpringBoot+Sentinel+Nacos 技术栈,打造一套「动态配置、实时监控、全方位防护」的微服务高可用体系,从核心功能实现到高级特性扩展,提供可直接复用的完整方案。

一、为什么需要微服务防护体系?

微服务架构下,服务间的依赖关系复杂,任何一个环节出现问题都可能引发系统性风险:

  • 流量过载:秒杀、促销等场景下,瞬时请求量暴涨,直接压垮核心服务;
  • 服务雪崩:某个服务响应超时或宕机,导致上下游依赖服务阻塞排队,最终全面瘫痪;
  • 依赖不稳定:第三方服务(如支付、物流)故障,拖累自身系统正常运行;
  • 配置僵化:限流、熔断规则硬编码,修改需重启服务,无法应对实时流量变化;
  • 监控缺失:无法实时感知服务状态,故障发生后难以快速定位和处理。

而 SpringBoot+Sentinel+Nacos 的组合,恰好能针对性解决这些问题,构建起「防护 + 配置 + 监控」的闭环体系。

二、技术选型深度解析

1. 核心技术栈选型逻辑

技术组件核心定位关键优势
SpringBoot微服务开发框架自动配置简化集成、注解驱动开发、原生支持拦截器与 AOP
Sentinel流量治理与防护核心轻量级无侵入、支持流量控制 / 熔断降级 / 系统保护、实时监控指标丰富
Nacos配置中心 + 服务注册中心动态配置推送(无需重启服务)、高可用集群部署、服务发现与健康检查

三者协同工作:SpringBoot 作为开发底座快速集成组件;Sentinel 负责执行流量控制与熔断降级逻辑;Nacos 提供规则动态配置与持久化,解决 Sentinel 规则重启丢失的问题。

2. 环境准备与依赖配置

(1)项目依赖(pom.xml)
<!-- SpringBoot 核心依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!-- Sentinel 核心依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2022.0.0.0-RC2</version>
</dependency>

<!-- Sentinel 集成 Nacos(规则持久化) -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
    <version>1.8.6</version>
</dependency>

<!-- Nacos 服务注册与配置中心 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2022.0.0-RC2</version>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>2022.0.0-RC2</version>
</dependency>

<!-- 工具类 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>2.0.32</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
(2)核心配置(application.yml)
spring:
  application:
    name: microservice-protection-demo # 应用名称
  cloud:
    # Nacos 配置
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848 # Nacos 服务地址
        group: DEFAULT_GROUP
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml # 配置文件格式
        group: DEFAULT_GROUP
    # Sentinel 配置
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080 # Sentinel 控制台地址
        port: 8719 # 与控制台通信端口(默认8719,冲突可修改)
      eager: true # 饥饿加载,解决首次访问无监控数据问题
      # 规则持久化到 Nacos
      datasource:
        # 流控规则
        flow:
          nacos:
            server-addr: 127.0.0.1:8848
            data-id: ${spring.application.name}-flow-rules
            group-id: SENTINEL_GROUP
            rule-type: flow
        # 熔断规则
        degrade:
          nacos:
            server-addr: 127.0.0.1:8848
            data-id: ${spring.application.name}-degrade-rules
            group-id: SENTINEL_GROUP
            rule-type: degrade

server:
  port: 8081 # 应用端口

management:
  endpoints:
    web:
      exposure:
        include: '*' # 暴露所有监控端点,便于Sentinel采集数据

三、核心功能实现:从基础到实战

1. 流量控制:拦截过载流量

流量控制是微服务防护的第一道防线,Sentinel 支持基于 QPS、并发线程数等多维度限流,通过 @SentinelResource 注解快速集成。

(1)限流接口开发
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

/**
 * 订单服务接口(带流量控制)
 */
@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;

    /**
     * 获取订单详情接口
     * @SentinelResource 核心属性:
     * - value:资源名称(唯一标识,用于配置规则)
     * - blockHandler:限流/熔断后的阻塞处理方法
     * - fallback:接口异常后的降级处理方法
     */
    @GetMapping("/order/{id}")
    @SentinelResource(
        value = "getOrder",
        blockHandler = "handleGetOrderBlock",
        fallback = "handleGetOrderFallback"
    )
    public ResponseEntity<OrderDTO> getOrder(@PathVariable Long id) {
        // 业务逻辑:查询订单详情
        OrderDTO order = orderService.getOrderById(id);
        return ResponseEntity.ok(order);
    }

    /**
     * 限流阻塞处理(流量超出阈值时触发)
     * 注意:参数需与原接口一致,且最后添加 BlockException 异常参数
     */
    public ResponseEntity<OrderDTO> handleGetOrderBlock(Long id, BlockException ex) {
        return ResponseEntity.status(429)
                .body(new OrderDTO(-1L, "服务繁忙,请稍后再试(限流触发)"));
    }

    /**
     * 降级处理(接口抛出异常时触发)
     * 注意:参数需与原接口一致,且最后添加 Throwable 异常参数
     */
    public ResponseEntity<OrderDTO> handleGetOrderFallback(Long id, Throwable ex) {
        // 降级策略:返回缓存数据或默认数据
        return ResponseEntity.ok(new OrderDTO(-1L, "降级处理,返回默认订单数据"));
    }

    // 订单DTO
    @Data
    @AllArgsConstructor
    static class OrderDTO {
        private Long orderId;
        private String message;
    }
}

/**
 * 订单服务实现
 */
@Service
class OrderService {
    public OrderController.OrderDTO getOrderById(Long id) {
        // 模拟数据库查询
        return new OrderController.OrderDTO(id, "订单详情:" + id);
    }
}
(2)Nacos 流控规则配置

在 Nacos 控制台创建配置:

  • Data ID:microservice-protection-demo-flow-rules
  • Group:SENTINEL_GROUP
  • 配置格式:JSON
  • 配置内容:
[
  {
    "resource": "getOrder", // 资源名称(对应 @SentinelResource 的 value)
    "limitApp": "default", // 限制来源(default 表示不区分来源)
    "grade": 1, // 限流阈值类型:1=QPS,0=并发线程数
    "count": 100, // 阈值:每秒最多100个请求
    "strategy": 0, // 限流策略:0=直接限流,1=关联限流,2=链路限流
    "controlBehavior": 0, // 流控效果:0=快速失败,1=Warm Up,2=排队等待
    "clusterMode": false // 是否集群限流(默认false)
  }
]

配置发布后,Sentinel 会自动加载规则,无需重启应用。

2. 熔断降级:避免服务雪崩

当服务调用失败率、响应时间超出阈值时,Sentinel 会自动熔断该服务,快速返回降级结果,避免故障扩散。

(1)熔断接口开发
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import lombok.Builder;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 支付服务(调用第三方支付,带熔断降级)
 */
@Service
public class PaymentService {

    @Autowired
    private ThirdPartyPaymentClient thirdPartyPaymentClient;

    /**
     * 处理支付请求
     * fallbackClass:指定外部降级处理类(需为静态方法)
     */
    @SentinelResource(
        value = "processPayment",
        fallback = "handlePaymentFallback",
        fallbackClass = PaymentFallbackHandler.class
    )
    public PaymentResult processPayment(PaymentRequest request) {
        // 调用第三方支付服务(可能不稳定)
        return thirdPartyPaymentClient.pay(request);
    }

    // 支付请求参数
    @Data
    public static class PaymentRequest {
        private Long orderId;
        private BigDecimal amount;
        private String userId;
    }

    // 支付响应结果
    @Data
    @Builder
    public static class PaymentResult {
        private String status; // SUCCESS/FAIL/DEFERRED
        private String message;
        private String tradeNo;
    }

    // 第三方支付客户端(模拟不稳定服务)
    @Component
    static class ThirdPartyPaymentClient {
        public PaymentResult pay(PaymentRequest request) {
            // 模拟随机失败(实际场景可能是超时、异常)
            if (Math.random() > 0.9) {
                throw new RuntimeException("第三方支付服务异常");
            }
            return PaymentResult.builder()
                    .status("SUCCESS")
                    .message("支付成功")
                    .tradeNo("TRADE_" + System.currentTimeMillis())
                    .build();
        }
    }
}

/**
 * 外部降级处理类(解耦降级逻辑)
 */
public class PaymentFallbackHandler {

    /**
     * 降级处理方法(必须是静态方法)
     */
    public static PaymentService.PaymentResult handlePaymentFallback(
            PaymentService.PaymentRequest request, Throwable ex) {
        // 记录降级日志
        System.err.println("支付服务降级,原因:" + ex.getMessage());
        // 降级策略:返回"处理中"状态,后续通过异步回调更新结果
        return PaymentService.PaymentResult.builder()
                .status("DEFERRED")
                .message("支付处理中,请稍后查询结果")
                .tradeNo(null)
                .build();
    }
}
(2)Nacos 熔断规则配置

在 Nacos 控制台创建配置:

  • Data ID:microservice-protection-demo-degrade-rules
  • Group:SENTINEL_GROUP
  • 配置格式:JSON
  • 配置内容:
[
  {
    "resource": "processPayment", // 资源名称
    "grade": 2, // 熔断策略:1=平均RT,2=异常比例,3=异常数
    "count": 0.1, // 阈值:异常比例10%
    "timeWindow": 10, // 熔断时长(秒):10秒后自动尝试恢复
    "minRequestAmount": 10, // 最小请求数:10个请求后才触发熔断(避免少量请求误判)
    "statIntervalMs": 1000 // 统计时间窗口(毫秒):1秒内的异常比例
  }
]

3. 系统保护:基于系统指标的全局防护

除了接口级防护,Sentinel 还支持基于系统负载、CPU 使用率、平均 RT 等指标的全局保护,避免系统因资源耗尽而崩溃。

import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRuleConstants;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * 系统全局保护配置
 */
@Component
public class SystemProtectionConfig {

    /**
     * 初始化系统保护规则(项目启动时执行)
     */
    @PostConstruct
    public void initSystemRules() {
        List<SystemRule> rules = new ArrayList<>();

        // 1. 系统负载保护:负载超过3.0时触发保护
        SystemRule loadRule = new SystemRule();
        loadRule.setHighestSystemLoad(3.0);
        loadRule.setStrategy(SystemRuleConstants.FULL_PROTECTION);
        rules.add(loadRule);

        // 2. CPU使用率保护:CPU使用率超过80%时触发保护
        SystemRule cpuRule = new SystemRule();
        cpuRule.setHighestCpuUsage(0.8);
        rules.add(cpuRule);

        // 3. 平均RT保护:所有接口平均RT超过500ms时触发保护
        SystemRule rtRule = new SystemRule();
        rtRule.setAvgRt(500);
        rules.add(rtRule);

        // 4. 并发线程数保护:系统总并发线程数超过200时触发保护
        SystemRule threadRule = new SystemRule();
        threadRule.setHighestThread(200);
        rules.add(threadRule);

        // 加载规则
        SystemRuleManager.loadRules(rules);
    }
}

4. 动态配置:规则实时更新(Nacos 联动)

通过 Nacos 实现规则动态配置,修改规则后无需重启应用,Sentinel 会实时感知并生效。核心是通过 Nacos 配置监听机制,当规则变更时自动刷新 Sentinel 规则。

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.Executor;

/**
 * Sentinel 规则动态刷新配置(监听Nacos配置变更)
 */
@Component
public class DynamicRuleConfig {

    @Autowired
    private ConfigService configService;

    // 应用名称(与application.yml一致)
    private static final String APP_NAME = "microservice-protection-demo";

    // 流控规则配置DataID
    private static final String FLOW_RULE_DATA_ID = APP_NAME + "-flow-rules";
    // 熔断规则配置DataID
    private static final String DEGRADE_RULE_DATA_ID = APP_NAME + "-degrade-rules";
    // 配置分组
    private static final String GROUP = "SENTINEL_GROUP";

    /**
     * 初始化监听
     */
    @PostConstruct
    public void initListener() {
        // 监听流控规则变更
        listenFlowRuleChanges();
        // 监听熔断规则变更
        listenDegradeRuleChanges();
    }

    /**
     * 监听流控规则
     */
    private void listenFlowRuleChanges() {
        try {
            configService.addListener(FLOW_RULE_DATA_ID, GROUP, new Listener() {
                @Override
                public void receiveConfigInfo(String configInfo) {
                    // 解析Nacos配置的流控规则
                    List<FlowRule> flowRules = JSON.parseObject(
                            configInfo, new TypeReference<List<FlowRule>>() {});
                    // 刷新Sentinel流控规则
                    FlowRuleManager.loadRules(flowRules);
                    System.out.println("流控规则更新成功:" + flowRules);
                }

                @Override
                public Executor getExecutor() {
                    return null;
                }
            });
        } catch (Exception e) {
            System.err.println("监听流控规则失败:" + e.getMessage());
        }
    }

    /**
     * 监听熔断规则
     */
    private void listenDegradeRuleChanges() {
        try {
            configService.addListener(DEGRADE_RULE_DATA_ID, GROUP, new Listener() {
                @Override
                public void receiveConfigInfo(String configInfo) {
                    List<DegradeRule> degradeRules = JSON.parseObject(
                            configInfo, new TypeReference<List<DegradeRule>>() {});
                    DegradeRuleManager.loadRules(degradeRules);
                    System.out.println("熔断规则更新成功:" + degradeRules);
                }

                @Override
                public Executor getExecutor() {
                    return null;
                }
            });
        } catch (Exception e) {
            System.err.println("监听熔断规则失败:" + e.getMessage());
        }
    }
}

四、高级特性扩展:适配复杂场景

1. 参数限流:针对热点参数精准控制

对于高频访问的接口,可针对特定参数(如用户 ID、商品 ID)进行限流,避免单个参数占用过多资源。

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowItem;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.Collections;

/**
 * 热点参数限流示例(针对用户ID限流)
 */
@RestController
public class HotParamLimitController {

    /**
     * 创建订单接口(针对用户ID限流)
     */
    @PostMapping("/order")
    public ResponseEntity<String> createOrder(@RequestBody OrderRequest request) {
        Entry entry = null;
        try {
            // 针对用户ID进行限流(参数索引为0:request.getUserId())
            entry = SphU.entry("createOrder", 1, request.getUserId());
            // 业务逻辑:创建订单
            return ResponseEntity.ok("订单创建成功:" + request.getOrderId());
        } catch (BlockException ex) {
            return ResponseEntity.status(429).body("您的请求过于频繁,请稍后再试");
        } finally {
            if (entry != null) {
                entry.exit();
            }
        }
    }

    /**
     * 初始化热点参数限流规则
     */
    @PostConstruct
    public void initHotParamRules() {
        ParamFlowRule rule = new ParamFlowRule("createOrder")
                .setParamIdx(0) // 参数索引(0表示第一个参数,即userId)
                .setCount(5); // 普通用户阈值:每秒最多5次请求

        // 针对VIP用户设置更高阈值(如VIP用户ID:10086)
        rule.setParamFlowItemList(Collections.singletonList(
                new ParamFlowItem().setObject("10086").setCount(20)
        ));

        // 加载规则
        ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
    }

    // 订单请求参数
    @lombok.Data
    static class OrderRequest {
        private Long orderId;
        private Long userId;
        private String goodsName;
    }
}

2. 异步调用防护:适配异步微服务

对于异步调用场景(如 @Async 注解),Sentinel 支持异步资源防护,确保异步线程中的服务也能被限流和熔断。

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import java.util.concurrent.CompletableFuture;

/**
 * 异步服务防护示例
 */
@Service
@EnableAsync // 开启异步支持
public class AsyncOrderService {

    /**
     * 异步处理订单
     * @SentinelResource 同样适用于异步方法
     */
    @Async
    @SentinelResource(
        value = "processOrderAsync",
        fallback = "handleProcessOrderFallback"
    )
    public CompletableFuture<String> processOrderAsync(Long orderId) {
        // 模拟异步业务逻辑(如订单异步通知、日志记录)
        if (orderId == null) {
            throw new RuntimeException("订单ID不能为空");
        }
        String result = "异步处理订单成功:" + orderId;
        return CompletableFuture.completedFuture(result);
    }

    /**
     * 异步方法降级处理
     */
    public CompletableFuture<String> handleProcessOrderFallback(Long orderId, Throwable ex) {
        return CompletableFuture.completedFuture("异步订单处理降级:" + ex.getMessage());
    }
}

3. 自定义异常处理:统一限流 / 熔断响应

通过实现 UrlBlockHandler 接口,自定义限流、熔断后的响应格式,统一返回给前端。

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.fastjson.JSON;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 自定义限流/熔断异常处理器
 */
@Component
public class CustomUrlBlockHandler implements com.alibaba.csp.sentinel.adapter.servlet.callback.UrlBlockHandler {

    @Override
    public void blocked(HttpServletRequest request, HttpServletResponse response, BlockException ex) throws IOException {
        // 设置响应格式
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(429);

        // 根据异常类型返回不同提示
        String message;
        if (ex instanceof FlowException) {
            message = "请求过于频繁(流控限制)";
        } else if (ex instanceof DegradeException) {
            message = "服务暂时不可用(熔断降级)";
        } else if (ex instanceof ParamFlowException) {
            message = "参数访问过于频繁(热点参数限流)";
        } else {
            message = "系统繁忙,请稍后再试";
        }

        // 构建响应结果
        ResultDTO result = new ResultDTO(429, message);
        response.getWriter().write(JSON.toJSONString(result));
    }

    // 统一响应DTO
    @lombok.Data
    @lombok.AllArgsConstructor
    static class ResultDTO {
        private int code;
        private String message;
    }
}

五、监控与告警:实时掌控系统状态

1. 自定义监控指标采集

通过 MeterRegistry 集成 Prometheus 等监控工具,采集限流、熔断等核心指标,实现可视化监控。

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 自定义监控指标采集
 */
@Component
public class SentinelMetricsCollector {

    private final Counter blockCounter;
    private final Counter passCounter;

    public SentinelMetricsCollector(MeterRegistry meterRegistry) {
        // 限流/熔断次数计数器
        this.blockCounter = Counter.builder("sentinel_block_total")
                .description("Sentinel 限流/熔断总次数")
                .register(meterRegistry);

        // 正常通过次数计数器
        this.passCounter = Counter.builder("sentinel_pass_total")
                .description("Sentinel 正常通过总次数")
                .register(meterRegistry);
    }

    /**
     * 记录限流/熔断事件
     */
    public void recordBlockEvent(String resource, String ruleType) {
        blockCounter.increment();
        // 可添加标签维度(如resource、ruleType),便于精细化监控
        Counter.builder("sentinel_block_total")
                .tag("resource", resource)
                .tag("rule_type", ruleType)
                .register(blockCounter.getMeterRegistry())
                .increment();
    }

    /**
     * 记录正常通过事件
     */
    public void recordPassEvent(String resource) {
        passCounter.increment();
    }
}

2. 实时监控接口:暴露核心指标

开发监控接口,暴露当前 QPS、线程数、平均 RT 等核心指标,便于运维人员实时查看。

import com.alibaba.csp.sentinel.command.handler.ModifyParamFlowRulesCommandHandler;
import com.alibaba.csp.sentinel.node.MetricsNode;
import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
import com.alibaba.csp.sentinel.util.TimeUtil;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Sentinel 监控接口
 */
@RestController
@RequestMapping("/monitor")
public class SentinelMonitorController {

    @GetMapping("/metrics")
    public ResponseEntity<Map<String, Object>> getMetrics() {
        Map<String, Object> metrics = new HashMap<>();

        // 获取所有资源的监控数据
        Set<ResourceWrapper> resources = ModifyParamFlowRulesCommandHandler.getResources();
        for (ResourceWrapper resource : resources) {
            MetricsNode node = com.alibaba.csp.sentinel.context.ContextUtil.getContext().getCurNode().getClusterNode().getMetricNode();
            if (node != null) {
                Map<String, Object> resourceMetrics = new HashMap<>();
                resourceMetrics.put("qps", node.getQps()); // 当前QPS
                resourceMetrics.put("avgRt", node.getRt()); // 平均RT
                resourceMetrics.put("activeThread", node.getActiveThreadCount()); // 活跃线程数
                resourceMetrics.put("blockQps", node.getBlockQps()); // 限流QPS
                metrics.put(resource.getName(), resourceMetrics);
            }
        }

        metrics.put("timestamp", TimeUtil.currentTimeMillis());
        return ResponseEntity.ok(metrics);
    }
}

3. 异常告警:及时响应故障

通过事件监听机制,当触发限流、熔断时,发送告警通知(如短信、邮件、钉钉),便于快速响应。

import com.alibaba.csp.sentinel.event.BlockEvent;
import com.alibaba.csp.sentinel.event.BlockExceptionEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

/**
 * Sentinel 异常告警处理器
 */
@Component
public class SentinelAlertHandler {

    /**
     * 监听限流/熔断事件
     */
    @EventListener
    public void handleBlockEvent(BlockExceptionEvent event) {
        String resource = event.getResource(); // 触发防护的资源名称
        String exceptionType = event.getBlockException().getClass().getSimpleName(); // 异常类型

        // 构建告警信息
        String alertMsg = String.format("资源[%s]触发防护,异常类型:%s", resource, exceptionType);
        System.out.println("告警通知:" + alertMsg);

        // 实际场景可集成钉钉、短信、邮件等告警渠道
        // dingTalkAlert.send(alertMsg);
        // emailAlert.send(alertMsg);
    }
}

六、最佳实践与性能优化

1. 规则设计原则

  • 分级防护:核心接口(支付、下单)设置更严格的限流阈值,非核心接口(查询、统计)可适当放宽;
  • 渐进式降级:降级策略优先返回缓存数据,其次返回默认数据,最后才拒绝服务;
  • 快速恢复:熔断时长设置合理(如 10-30 秒),避免长时间熔断影响用户体验;
  • 动态调整:根据流量变化(如大促、日常)动态调整阈值,避免过度防护或防护不足。

2. 性能优化建议

  • 异步处理:防护逻辑与业务逻辑异步分离,避免阻塞业务线程;
  • 规则缓存:Sentinel 规则默认内存存储,高频访问无需额外优化;
  • 批量上报:监控数据批量上报,减少网络 IO 开销;
  • 资源命名规范:资源名称(@SentinelResource 的 value)统一格式(如 service:method:resource),便于监控和规则管理。

3. 安全考虑

  • 权限控制:限制 Nacos 配置中心的访问权限,避免规则被恶意修改;
  • 审计日志:记录规则变更历史,便于追溯问题;
  • 防刷机制:结合 IP、用户 ID 等维度进行多层防护,避免恶意请求绕过 Sentinel。

七、总结

本文基于 SpringBoot+Sentinel+Nacos 技术栈,构建了一套从「流量控制、熔断降级、系统保护」到「动态配置、实时监控、异常告警」的完整微服务防护体系。核心优势在于:

  1. 无侵入集成:通过注解快速接入,无需改造原有业务代码;
  2. 动态灵活:规则存储在 Nacos,修改实时生效,适配动态业务场景;
  3. 全方位防护:覆盖接口级、系统级、异步场景,避免雪崩风险;
  4. 可观测性:完善的监控与告警机制,实时掌控系统状态。

这套方案不仅适用于电商、支付等核心业务系统,也可迁移到各类微服务架构中,帮助开发者告别系统雪崩的烦恼,打造稳定、高可用的微服务应用。