Spring Boot分布式项目异常处理实战:从崩溃边缘到优雅恢复

news/2025/3/25 22:10:34/

当单体应用拆分成分布式系统,异常就像被打开的潘多拉魔盒:RPC调用超时、分布式事务雪崩、第三方接口突然罢工…在最近的电商大促中,我们的系统就经历了这样的至暗时刻。本文将用真实代码示例,展示如何构建分布式异常处理体系。

一、全局异常拦截:最后的防线

@RestControllerAdvice
public class GlobalExceptionHandler {// 处理业务异常@ExceptionHandler(BizException.class)public Result handleBizException(BizException e) {log.error("业务异常: {}", e.getErrorMsg());return Result.fail(e.getErrorCode(), e.getErrorMsg());}// 处理Feign调用异常@ExceptionHandler(FeignException.class)public Result handleFeignException(FeignException e) {log.error("服务调用异常: {}", e.contentUTF8());return Result.fail(ErrorCode.SERVICE_UNAVAILABLE);}// 兜底异常处理@ExceptionHandler(Exception.class)public Result handleException(Exception e) {log.error("系统异常: {}", e.getMessage());return Result.fail(ErrorCode.SYSTEM_ERROR);}
}

关键点:通过@ControllerAdvice实现三层防护,特别注意对Feign异常的单独处理,保留原始错误信息

二、服务间调用异常处理

  1. Feign+Sentinel双保险配置:
feign:client:config:default:connectTimeout: 3000readTimeout: 5000sentinel:scg:fallback:mode: responseresponse-body: '{"code":503,"msg":"服务降级"}'
  1. 自定义FallbackFactory:
@Component
public class OrderServiceFallbackFactory implements FallbackFactory<OrderServiceClient> {@Overridepublic OrderServiceClient create(Throwable cause) {return new OrderServiceClient() {@Overridepublic Result<OrderDTO> getOrder(String orderId) {if(cause instanceof BizException){return Result.fail(((BizException) cause).getErrorCode(), "订单服务异常");}return Result.fail(ErrorCode.SERVICE_DEGRADE);}};}
}

实战经验:在双十一大促中,这种组合策略帮助我们拦截了70%以上的级联故障

三、分布式事务异常处理

使用Seata的TCC模式示例:

@LocalTCC
public interface OrderTccAction {@TwoPhaseBusinessAction(name = "prepareCreateOrder", commitMethod = "commit", rollbackMethod = "rollback")boolean prepare(BusinessActionContext actionContext,@BusinessActionContextParameter(paramName = "order") Order order);boolean commit(BusinessActionContext actionContext);boolean rollback(BusinessActionContext actionContext);
}

补偿策略:

  1. 自动重试:对网络抖动等临时性错误
  2. 人工干预:对数据不一致等严重问题
  3. 事务日志:记录关键操作节点

四、流量洪峰应对策略

  1. Resilience4j熔断配置:
CircuitBreakerConfig config = CircuitBreakerConfig.custom().failureRateThreshold(50).waitDurationInOpenState(Duration.ofMillis(1000)).ringBufferSizeInHalfOpenState(2).ringBufferSizeInClosedState(2).build();
  1. 自适应限流算法:
@Slf4j
public class AdaptiveLimiter {private AtomicInteger currentLimit = new AtomicInteger(100);public boolean tryAcquire() {int current = currentLimit.get();if(current <= 0) return false;// 根据RT和成功率动态调整double successRate = getRecentSuccessRate();long avgRT = getAvgResponseTime();if(successRate < 90% || avgRT > 500ms) {currentLimit.updateAndGet(x -> Math.max(x/2, 10));} else if(successRate > 99% && avgRT < 100ms) {currentLimit.updateAndGet(x -> Math.min(x*2, 1000));}return true;}
}

五、异常追踪三板斧

  1. 全链路追踪:
@Slf4j
public class TraceInterceptor extends HandlerInterceptorAdapter {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {MDC.put("traceId", UUID.randomUUID().toString());}
}
  1. 异常画像系统:
@Aspect
@Component
public class ExceptionMonitor {@AfterThrowing(pointcut = "execution(* com..*.*(..))", throwing = "ex")public void monitorException(Exception ex) {ExceptionMetric metric = new ExceptionMetric(ex.getClass().getSimpleName(),Thread.currentThread().getName(),System.currentTimeMillis());KafkaTemplate.send("exception_metrics", metric);}
}
  1. 智能告警:基于ELK的异常模式识别

总结

在分布式系统中,异常处理不是简单的try-catch,而是需要建立完整的防御体系:

  1. 全局异常拦截:统一异常出口
  2. 服务治理:熔断/限流/降级三板斧
  3. 事务补偿:最终一致性保障
  4. 智能监控:快速定位问题根源

当系统吞吐量从100TPS提升到5000TPS时,我们的异常处理体系经受住了真实流量的考验。记住:好的异常处理方案,不是消灭异常,而是让系统优雅地与之共处。


http://www.ppmy.cn/news/1582561.html

相关文章

路由Vue Router基本用法

路由的作用是根据URL来匹配对应的组件&#xff0c;并且无刷新切换模板的内容。vue.js中&#xff0c;可使用Vue Router来管理路由&#xff0c;让构建单页应用更加简单。 一、效果 二、实现 1.项目中安装Vue Router插件 pnpm install vue-routerlastest 2.main.js import { …

数据结构:二叉树(二)·(重点)

前言 文章结尾有彩蛋哦~~ 前面我们已经知道了什么是树&#xff0c;树是⼀种⾮线性的数据结构&#xff0c;它是由 n &#xff08; n>0 &#xff09; 个有限结点组成⼀个具有层次关系的集合。 那么这篇文章就让我们来了解一下什么是二叉树吧&#xff01; 二叉树的概念与结…

2025年01月02日浙江鼎永前端面试

目录 webpack 和 vite 区别react fiber 架构vue diff 算法react diff 算法hooks 源码垂直水平布局项目介绍单点登录大文件上传微前端 1. webpack 和 vite 区别 Webpack 和 Vite 是两种不同的前端构建工具&#xff0c;它们在设计理念、性能表现和使用场景上存在显著差异。以下…

最近比突出的DeepSeek与ChatGPT的详细比较分析

引言 随着人工智能技术的快速发展&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域涌现出了许多强大的模型和工具。DeepSeek和ChatGPT作为其中的代表&#xff0c;各自在特定领域和应用场景中展现了卓越的性能。本文将从多个维度对DeepSeek和ChatGPT进行比较分析&…

【Spring IoC DI】深入解析 IoC & DI :Spring框架的核心设计思想和 IoC 与 DI 的思想和解耦优势

Spring IoC&DI 本节目标 了解Spring, Spring MVC, Spring Boot 之间的联系及区别掌握IoC&DI的概念以及写法 IoC & DI 入门 在前面的章节中&#xff0c;我们学习了Spring Boot和Spring MVC的开发&#xff0c;可以完成一些基本功能的开发了&#xff0c;但是什么是S…

Rust基础语法

文章目录 Rust输出到命令行关于变量常量vs不可变变量 数据类型整数浮点数bool字符类型复合类型 注释 Rust输出到命令行 输出到命令行主要可以使用println!()和print!() 1. 这两个都有!是因为他们并非是函数&#xff0c;而是宏&#xff0c;具体我们以后再介绍&#xff0c;普通函…

Linux探秘坊-------9.进程控制

1.进程终止 1.终止情况 终止情况只有三种&#xff1a; 2.终止方式 从main函数返回 exit&#xff08;n&#xff09;的参数n就是退出码&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xf…

k8s搭建kube-prometheus

后续再补一个k8s集群搭建的博客&#xff0c;从0开始搭建k8s集群。使用kube-prometheus非常方便&#xff0c;主要问题只在于拉取镜像。除了拉取镜像外其他时间5分钟即可。耐心等待拉取镜像。 一.kube-prometheus简介 kube-prometheus 是一个专为 Kubernetes 设计的开源监控解决…