Spring Boot全局异常处理与日志监控实战指南

Spring Boot全局异常处理与日志监控实战指南

全局异常处理机制

1. @ControllerAdvice基础用法

使用@ControllerAdvice注解可以创建全局异常处理器,它会拦截所有控制器抛出的异常。典型实现方式如下:

@ControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleAllExceptions(Exception ex) {
        ErrorResponse error = new ErrorResponse(
            HttpStatus.INTERNAL_SERVER_ERROR.value(),
            "系统发生异常",
            ex.getMessage(),
            System.currentTimeMillis()
        );
        return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

2. 自定义业务异常处理

针对特定业务异常创建自定义处理逻辑:

@ExceptionHandler(BusinessException.class)
public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex) {
    ErrorResponse error = new ErrorResponse(
        ex.getErrorCode(),
        ex.getErrorType(),
        ex.getMessage(),
        System.currentTimeMillis()
    );
    return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}

3. 异常分类处理策略

按异常类型分类处理:

  • 客户端异常(4xx):处理参数校验、资源不存在等异常
  • 服务端异常(5xx):处理数据库、第三方服务等系统异常
  • 业务异常:处理特定业务规则触发的异常

日志监控体系搭建

1. 日志配置最佳实践

application.yml配置示例:

logging:
  level:
    root: INFO
    org.springframework.web: DEBUG
    com.example: TRACE
  file:
    name: logs/app.log
    max-history: 30
    max-size: 10MB
  pattern:
    file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
    console: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx"

2. 关键日志埋点位置

建议在以下位置添加详细日志:

  1. 请求入口:记录请求参数、请求头
  2. 业务处理:关键业务步骤和决策点
  3. 异常捕获:记录异常堆栈和上下文
  4. 外部调用:记录请求/响应数据

3. 日志监控方案选型

方案特点适用场景
ELK Stack完整日志收集分析方案中大型分布式系统
Splunk商业日志分析工具企业级应用
Prometheus+Grafana指标监控+日志联动云原生环境
Loki轻量级日志聚合资源受限环境

实战案例分析

案例1:电商订单异常处理

@ExceptionHandler(OrderException.class)
public ResponseEntity<ErrorResponse> handleOrderException(OrderException ex) {
    log.error("订单处理异常,订单号:{},用户:{}", 
        ex.getOrderId(), ex.getUserId(), ex);
    
    ErrorResponse error = new ErrorResponse(
        ex.getErrorCode(),
        "订单处理失败",
        ex.getMessage(),
        System.currentTimeMillis()
    );
    
    // 发送告警通知
    alertService.sendOrderErrorAlert(ex);
    
    return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}

案例2:微服务链路日志追踪

使用MDC实现请求链路追踪:

@Slf4j
@Aspect
@Component
public class RequestLogAspect {
    
    @Around("execution(* com.example..*Controller.*(..))")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        String traceId = UUID.randomUUID().toString();
        MDC.put("traceId", traceId);
        
        log.info("请求开始: {} {}", 
            joinPoint.getSignature().getDeclaringTypeName(),
            joinPoint.getSignature().getName());
            
        try {
            Object result = joinPoint.proceed();
            log.info("请求成功: {}", result);
            return result;
        } catch (Exception ex) {
            log.error("请求异常", ex);
            throw ex;
        } finally {
            MDC.clear();
        }
    }
}

性能优化建议

异常处理性能优化:

  1. 避免在异常处理中执行耗时操作

    • 异常处理流程应尽量轻量级,避免在catch块中执行数据库查询、远程调用等耗时操作
    • 示例:将耗时的业务逻辑移出异常处理块,改为在正常流程中处理
    • 典型场景:支付系统异常处理中不应包含订单状态更新等复杂操作
  2. 对高频异常进行缓存处理

    • 对频繁出现的相同异常可建立缓存机制
    • 实现方式:使用LRU缓存存储最近N次的异常信息
    • 应用场景:接口限流异常、参数校验异常等高频异常

日志输出优化:

  1. 使用占位符{}代替字符串拼接

    • 优势:避免不必要的字符串拼接开销
    • 示例:log.info("用户{}登录成功", userId) 优于 log.info("用户"+userId+"登录成功")
    • 支持框架:Log4j2、SLF4J等主流日志框架
  2. 合理设置日志级别

    • 生产环境建议配置:
      • 常规日志:INFO级别
      • 调试日志:WARN级别
      • 错误日志:ERROR级别
    • 开发环境可开启DEBUG级别方便调试
  3. 敏感信息脱敏处理

    • 必须脱敏的信息类型:
      • 用户身份证号(保留前3位后4位)
      • 银行卡号(保留前4位后4位)
      • 手机号码(保留前3位后4位)
    • 实现方式:自定义Logback/Log4j2的Converter

监控系统调优:

  1. 日志采样率设置

    • 高流量系统建议采用1%-10%的采样率
    • 关键业务日志可适当提高采样率
    • 实现方式:通过日志框架的Sampler组件配置
  2. 关键指标告警配置

    • 必须监控的核心指标:
      • 错误率(5分钟内>1%触发告警)
      • 响应时间(P99>500ms触发告警)
      • 系统负载(CPU>80%持续5分钟触发告警)
    • 告警方式:企业微信/钉钉/SMS多通道通知
  3. 日志数据清理

    • 清理策略建议:
      • 调试日志保留7天
      • 业务日志保留30天
      • 审计日志保留180天
    • 实现方案:ELK的Curator工具或自定义清理脚本
    • 存储优化:冷热数据分离存储
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值