1. 减少异常抛出频率
- 提前检查条件:在可能抛出异常的操作前,通过条件判断避免异常的产生。例如在访问数组元素前先检查索引是否越界。
int[] arr = new int[10];
int index = 15;
if (index >= 0 && index < arr.length) {
int value = arr[index];
}
- 使用特定返回值替代异常:对于一些非严重错误场景,使用特定的返回值表示异常情况,而不是抛出异常。比如在读取文件操作中,如果文件不存在,返回一个特殊值(如 -1 表示文件未找到),而不是抛出
FileNotFoundException
。
2. 优化异常处理对线程池性能的影响
- 自定义线程池拒绝策略:当线程池任务队列已满且线程数达到最大时,自定义拒绝策略来处理新任务,避免因异常导致任务丢失或线程池不稳定。例如使用
ThreadPoolExecutor.CallerRunsPolicy
,让提交任务的线程自己执行任务。
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5,
10,
10L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(10),
new ThreadPoolExecutor.CallerRunsPolicy());
- 捕获异常并处理:在线程池执行的任务代码中,捕获异常并进行相应处理,避免异常抛出导致线程池中的线程终止。
executor.submit(() -> {
try {
// 业务逻辑
} catch (Exception e) {
// 异常处理
}
});
3. 分布式环境下统一管理和处理异常
- 使用分布式日志系统:如 ELK(Elasticsearch、Logstash、Kibana)或 Splunk,将各个节点的异常日志集中收集和分析,方便定位问题。在应用程序中配置日志框架(如 Log4j、SLF4J)将日志发送到分布式日志系统。
- 定义统一的异常结构:在分布式系统中,定义统一的异常结构,包含异常码、异常信息等,方便不同服务之间传递和处理异常。可以通过自定义异常类实现,例如:
public class CustomDistributedException extends RuntimeException {
private int errorCode;
public CustomDistributedException(int errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
// getters and setters
}
- 全局异常处理机制:在每个服务中设置全局异常处理器,捕获所有未处理的异常,并进行统一处理,如返回统一格式的错误响应给调用方。在 Spring Boot 中,可以使用
@ControllerAdvice
和 @ExceptionHandler
注解实现。
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(CustomDistributedException.class)
@ResponseBody
public ResponseEntity<ErrorResponse> handleCustomException(CustomDistributedException ex) {
ErrorResponse errorResponse = new ErrorResponse(ex.getErrorCode(), ex.getMessage());
return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
- 异常传播与处理链:在分布式服务调用中,合理传播异常,确保异常能被合适的服务层处理。例如通过 Feign 调用时,可以自定义错误解码器处理远程服务返回的异常。
@Configuration
public class FeignConfiguration {
@Bean
public ErrorDecoder errorDecoder() {
return new CustomErrorDecoder();
}
}
public class CustomErrorDecoder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
// 自定义异常解码逻辑
return new CustomDistributedException(500, "Remote service error");
}
}