Spring Boot微服务链路追踪与Sentinel熔断降级实战

微服务调用链故障定位是服务治理的首要挑战

微服务架构下,一个前端请求可能跨越5-10个后端服务。当接口响应超时或报错,只看单个服务的日志无法定位根因——是下游服务慢?还是数据库阻塞?还是网络抖动?链路追踪系统为每个请求生成全局唯一的Trace ID,贯穿整个调用链,配合熔断降级策略在故障发生时自动切断异常链路,是服务治理的标配方案。

SkyWalking链路追踪接入配置

Apache SkyWalking是目前主流的开源APM方案,Java Agent方式零代码侵入:

1. 部署SkyWalking OAP Server

docker run -d --name oap \
  -p 11800:11800 -p 12800:12800 \
  -e SW_STORAGE=elasticsearch \
  -e SW_STORAGE_ES_CLUSTER_NODES=es:9200 \
  apache/skywalking-oap-server:9.7.0

2. Java Agent挂载

启动Spring Boot应用时挂载Agent:

java -javaagent:/path/to/skywalking-agent.jar \
  -Dskywalking.agent.service_name=order-service \
  -Dskywalking.collector.backend_grpc=oap:11800 \
  -jar order-service.jar

Docker部署方式:

FROM openjdk:17-jdk-slim
COPY target/app.jar /app.jar
COPY skywalking-agent/ /skywalking-agent/
ENTRYPOINT ["java", "-javaagent:/skywalking-agent/skywalking-agent.jar", \
  "-Dskywalking.agent.service_name=order-service", \
  "-Dskywalking.collector.backend_grpc=oap:11800", \
  "-jar", "/app.jar"]

Kubernetes环境下用Init Container自动注入Agent更优雅:

initContainers:
- name: skywalking-agent
  image: apache/skywalking-java-agent:9.7.0-java17
  command: ['cp', '-r', '/skywalking-agent', '/agent']
  volumeMounts:
  - name: agent-volume
    mountPath: /agent
containers:
- name: app
  env:
  - name: JAVA_TOOL_OPTIONS
    value: "-javaagent:/agent/skywalking-agent.jar"
  - name: SW_AGENT_NAME
    value: "order-service"
  volumeMounts:
  - name: agent-volume
    mountPath: /agent

3. 自定义Trace标注

在关键业务方法上添加Span标注,记录业务上下文:

@TraceCrossThread
@Trace
public OrderResult createOrder(OrderRequest request) {
    Tags.SPAN_KIND.set("business");
    Span activeSpan = ContextManager.activeSpan();
    activeSpan.tag("user_id", request.getUserId());
    activeSpan.tag("order_amount", String.valueOf(request.getAmount()));
    
    // 业务逻辑...
    return orderResult;
}

跨服务调用链追踪实战

OpenFeign + SkyWalking自动传播Trace上下文:

@FeignClient(name = "inventory-service", fallbackFactory = InventoryFallback.class)
public interface InventoryClient {
    
    @PostMapping("/api/inventory/deduct")
    DeductResult deduct(@RequestBody DeductRequest request);
}

@Component
public class InventoryFallback implements FallbackFactory<InventoryClient> {
    @Override
    public InventoryClient create(Throwable cause) {
        return request -> {
            log.error("Inventory service fallback triggered", cause);
            return DeductResult.fail("库存服务暂不可用,请稍后重试");
        };
    }
}

SkyWalking Agent自动拦截OpenFeign调用,注入sw_traceid到请求头,下游服务提取后继续串联Span。Trace ID在整个调用链路中保持一致。

异步线程池场景下Trace上下文默认丢失,需要用SkyWalking提供的包装类:

@Bean
public Executor traceExecutor() {
    ThreadPoolExecutor executor = new ThreadPoolExecutor(
        10, 50, 60, TimeUnit.SECONDS,
        new LinkedBlockingQueue<>(1000)
    );
    return new TraceRunnableExecutor(executor);
}

Sentinel熔断降级配置

Sentinel提供流量控制、熔断降级、系统保护三个层面的服务治理能力:

1. 引入依赖

<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
  <version>1.8.7</version>
</dependency>
<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-datasource-nacos</artifactId>
  <version>1.8.7</version>
</dependency>

2. 熔断规则配置

@Bean
public FlowRule orderFlowRule() {
    FlowRule rule = new FlowRule();
    rule.setResource("createOrder");
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    rule.setCount(500);  // QPS限制500
    rule.setLimitApp("default");
    return rule;
}

@Bean
public DegradeRule orderDegradeRule() {
    DegradeRule rule = new DegradeRule();
    rule.setResource("inventoryDeduct");
    rule.setGrade(CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType());
    rule.setCount(1000);        // 慢调用阈值1秒
    rule.setSlowRatioThreshold(0.6);  // 慢调用比例60%触发熔断
    rule.setMinRequestAmount(10);      // 最小请求数
    rule.setStatIntervalMs(10000);    // 统计窗口10秒
    rule.setTimeWindow(30);            // 熔断持续30秒
    return rule;
}

3. 异常比例熔断

DegradeRule exceptionRule = new DegradeRule();
exceptionRule.setResource("paymentService");
exceptionRule.setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType());
exceptionRule.setCount(0.3);         // 异常比例30%触发熔断
exceptionRule.setMinRequestAmount(5);  // 最少5次请求
exceptionRule.setStatIntervalMs(10000);
exceptionRule.setTimeWindow(60);     // 熔断60秒
exceptionRule.setLimitApp("default");

4. Fallback降级处理

@SentinelResource(value = "getUserInfo", 
    fallback = "getUserInfoFallback", 
    blockHandler = "getUserInfoBlock")
public UserInfo getUserInfo(Long userId) {
    return userClient.getById(userId);
}

// 业务异常降级
public UserInfo getUserInfoFallback(Long userId, Throwable t) {
    log.warn("getUserInfo fallback, userId={}, error={}", userId, t.getMessage());
    return UserInfo.defaultUser(userId);
}

// 流控/熔断降级
public UserInfo getUserInfoBlock(Long userId, BlockException ex) {
    log.warn("getUserInfo blocked, userId={}, rule={}", userId, ex.getRule());
    throw new ServiceUnavailableException("用户服务暂时不可用");
}

Sentinel Dashboard动态规则管理

部署Dashboard并对接Nacos做规则持久化:

docker run -d --name sentinel-dashboard \
  -p 8080:8080 \
  -e SENTINEL_NACOS_ADDR=nacos:8848 \
  -e SENTINEL_NACOS_NAMESPACE=prod \
  bladex/sentinel-dashboard:1.8.7

Dashboard上可以实时调整熔断阈值、QPS限流、热点参数限流,修改即时生效无需重启应用。Nacos持久化保证规则不丢失,新实例启动后自动拉取最新规则。

链路追踪与熔断联动告警

SkyWalking告警规则关联Sentinel熔断事件:

# SkyWalking alarm_rules.yml
rules:
  service_sla_rule:
    metrics-name: service_sla
    threshold: 95.0
    op: "<"
    period: 10
    silence-period: 5
    message: "服务SLA低于95%,可能触发Sentinel熔断"
    
  endpoint_avg_rule:
    metrics-name: endpoint_avg
    threshold: 2000
    op: ">"
    period: 10
    message: "接口平均响应超过2秒"
    
hooks:
  webhook:
    - http://alertmanager:9093/api/v1/alerts

告警触发后结合Trace ID快速跳转到SkyWalking UI查看完整调用链,定位慢服务或异常节点,再通过Sentinel Dashboard调整对应资源的熔断策略。这种链路追踪+熔断降级的联动机制,使故障发现到止损的MTTR(平均恢复时间)从分钟级降到秒级。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/springboot-wei-fu-wu-lian-lu-zhui-zong-yu-sentinel-rong/

(0)
小编小编
上一篇 8小时前
下一篇 8小时前

相关推荐