这是一个典型的资源耗尽问题,需要从多个层面来解决。以下是系统的处理方案:
1. 立即缓解措施
调整线程池配置
// 增加线程池容量(临时方案)
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize * 2, // 核心线程数翻倍
maximumPoolSize * 2, // 最大线程数翻倍
60L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1000) // 增大队列容量
);
使用拒绝策略处理溢出
ThreadPoolExecutor executor = new ThreadPoolExecutor(
// ... 参数
new ThreadPoolExecutor.CallerRunsPolicy() // 由调用线程执行
// 或 AbortPolicy() 抛出异常,或 DiscardPolicy() 静默丢弃
);
2. 代码层面优化
异步化处理
// 使用 CompletableFuture 进行异步处理
public CompletableFuture<Result> processAsync(Request request) {
return CompletableFuture.supplyAsync(() -> {
return computeHeavyLogic(request);
}, executor);
}
// 批量处理多个请求
public CompletableFuture<List<Result>> processBatchAsync(List<Request> requests) {
List<CompletableFuture<Result>> futures = requests.stream()
.map(this::processAsync)
.collect(Collectors.toList());
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()));
}
分布式计算框架:采用Hadoop或Spark等框架将任务分解为多个子任务并行处理,例如通过MapReduce模型实现分而治之。对于图计算等特定场景,可选用GraphChi等单机外存计算系统避免分布式环境复杂性
3. 架构层面解决方案
如果要求实时性不高的需求,可以引入消息队列将计算逻辑解耦合
@Component
public class RequestProcessor {
@Autowired
private TaskQueue taskQueue;
// 接收请求,放入队列
public String submitRequest(Request request) {
String taskId = generateTaskId();
taskQueue.addTask(taskId, request);
return taskId;
}
// 消费者处理
@EventListener
public void processTask(TaskEvent event) {
// 从线程池获取资源处理
executor.submit(() -> {
try {
Result result = computeHeavyLogic(event.getRequest());
taskQueue.completeTask(event.getTaskId(), result);
} catch (Exception e) {
taskQueue.failTask(event.getTaskId(), e);
}
});
}
}
水平扩展
// 使用分布式锁确保同一数据不会被重复处理
@Autowired
private DistributedLock lock;
public Result processWithLock(String dataKey, Request request) {
if (lock.tryLock(dataKey, 30, TimeUnit.SECONDS)) {
try {
return computeHeavyLogic(request);
} finally {
lock.unlock(dataKey);
}
} else {
throw new BusyException("系统繁忙,请稍后重试");
}
}
4. 性能优化策略
缓存优化
@Service
public class HeavyComputeService {
@Autowired
private CacheManager cacheManager;
// 缓存计算结果
@Cacheable(value = "heavyCompute", key = "#request.hash")
public Result computeWithCache(Request request) {
return computeHeavyLogic(request);
}
// 预加载热点数据
@PostConstruct
public void preloadHotData() {
// 预加载常用数据到缓存
}
}
算法优化
public class OptimizedComputer {
// 使用更高效的算法
public Result optimizedCompute(Request request) {
// 1. 数据分片处理
List<DataSlice> slices = splitData(request.getData());
// 2. 并行处理分片
List<CompletableFuture<SliceResult>> futures = slices.stream()
.map(slice -> CompletableFuture.supplyAsync(
() -> processSlice(slice), sliceExecutor))
.collect(Collectors.toList());
// 3. 合并结果
return mergeResults(futures);
}
private List<DataSlice> splitData(Data data) {
// 根据数据特征进行智能分片
return dataSplitter.split(data, optimalSliceSize);
}
}
5. 监控和限流
限流保护,可以避免大批量的请求将数据库搞挂
@Component
public class RateLimiter {
private final RateLimiter limiter = RateLimiter.create(100); // 100 QPS
public Result processWithLimit(Request request) {
if (limiter.tryAcquire()) {
return computeHeavyLogic(request);
} else {
throw new RateLimitExceededException("请求过于频繁");
}
}
}
资源监控
@RestController
public class MonitorController {
@Autowired
private ThreadPoolExecutor executor;
@GetMapping("/monitor/thread-pool")
public ThreadPoolStatus getThreadPoolStatus() {
return new ThreadPoolStatus(
executor.getActiveCount(),
executor.getQueue().size(),
executor.getCompletedTaskCount(),
executor.getPoolSize()
);
}
}
6. 推荐的整体架构
客户端 → API网关(限流) → 消息队列 → 计算集群 → 缓存 → 数据库
↓
快速失败/排队提示
实施建议
- 短期:调整线程池配置 + 增加队列容量
- 中期:引入消息队列解耦 + 添加缓存
- 长期:算法优化 + 水平扩展 + 架构重构
关键是要根据业务场景选择最合适的方案组合,同时建立完善的监控告警机制。