微服务统一异常处理需网关与业务层分工协作:网关捕获路由层异常(超时、连接失败、配置错误),业务层用自定义异常+@ControllerAdvice处理逻辑错误,共用错误码与响应结构,并透传清洗下游异常、嵌入重试/熔断等容错策略。

微服务中统一异常处理的关键,不是把所有错误都“兜住”,而是让网关和业务层各司其职:网关管路由层面的失败(超时、连不上、下游返回错),业务层管逻辑层面的失败(参数错、权限不足、余额不够)。两者用不同机制捕获,但共用一套错误码和响应结构,才能真正“统一”。
网关层只捕获它该管的异常
Spring Cloud Gateway 基于响应式编程,不能靠传统 try-catch。重点捕获三类明确信号:
- ClientResponseException:下游返回 4xx/5xx 时触发,提取原始 status 和 body,不做重抛,直接映射为标准错误体
-
TimeoutException / ReadTimeoutException:网络或下游响应超时,标记为
GATEWAY_TIMEOUT,状态码设为 504,提示“请稍后重试” - IllegalArgumentException / IllegalStateException:如路由配置缺失、路径参数非法,说明请求本身有问题,返回 400 + 明确提示,不转发给下游
避免 catch Exception 或 Throwable——OOM、StackOverflowError 这类问题必须暴露,不能静默吞掉。
业务层用自定义异常+@ControllerAdvice 分层拦截
业务服务内部抛出的异常,要语义清晰、可分类、可追溯:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 定义枚举型错误码,如
USER_NOT_FOUND(404001, "用户不存在")、INVALID_PARAM(400001, "参数校验失败") - 封装 BusinessException 继承 RuntimeException,在 Service 层主动 throw,不包装成通用 Exception
- 在 Controller 层外统一用 @ControllerAdvice 拦截,按类型返回对应 HTTP 状态码和标准 JSON 响应体
比如参数校验失败走 MethodArgumentNotValidException,用户未登录走 AuthenticationException,每种都有独立的 @ExceptionHandler 方法,响应字段一致、提示语义化。
上下游异常要能透传且不泄露细节
网关调用业务服务时,不能把下游 500 直接透传给前端。需要做一层清洗:
- 若下游返回标准 JSON(含 code/message),复用其
code,补充网关级字段:requestId、timestamp、X-Error-Source - 若下游返回空体、HTML、非 JSON 或格式混乱,网关自动构造兜底响应:
{"code":"GATEWAY_DOWNSTREAM_ERROR","message":"依赖服务返回异常响应"} - 对下游 500 类错误,统一降级为
SERVICE_UNAVAILABLE,避免暴露数据库连接失败、NPE 等内部信息
容错策略要嵌入异常流,不止是捕获
捕获只是起点,真正的“优雅”体现在后续动作是否合理:
- 对 ConnectException、SocketTimeoutException 这类偶发异常,交由 Resilience4j 配置最多 2 次指数退避重试,前端看到的是“正在重试…”而非立刻报错
- 下游连续失败达阈值(如 5 次 5xx),熔断器打开,后续请求短路,返回预设 fallback 响应(如 {"code":503,"message":"服务暂不可用,请稍后再试"})
- fallback 方法自身也需 try-catch 包裹,防止降级逻辑出错导致二次崩溃

















