SpringBoot + 任务执行资源隔离 + CPU/内存配额:关键任务独占资源,避免被其他任务拖垮
1. 问题背景:为什么需要任务执行资源隔离?
在现代应用中,我们经常需要处理各种类型的任务,有些是关键任务(如订单处理、支付交易),有些是非关键任务(如日志分析、数据导出)。如果所有任务都在同一个线程池和资源环境中执行,可能会导致以下问题:
- 资源竞争:非关键任务占用大量CPU和内存资源,导致关键任务执行缓慢
- 系统不稳定:某个任务出现内存泄漏或CPU占用过高,可能影响整个应用的稳定性
- 难以调优:无法针对不同类型的任务设置不同的资源限制和执行策略
- 故障隔离:一个任务的故障可能会影响其他任务的执行
因此,实现任务执行资源隔离,为不同类型的任务分配独立的资源配额,成为保证系统稳定性和关键任务执行质量的重要手段。
2. 核心概念:任务执行资源隔离的原理
2.1 资源隔离的基本概念
资源隔离是指将系统资源(如CPU、内存、网络等)划分为不同的资源池,不同类型的任务只能使用分配给它们的资源池,从而避免资源竞争和相互影响。
2.2 资源隔离的实现方式
在Spring Boot应用中,实现任务执行资源隔离的主要方式有:
- 线程池隔离:为不同类型的任务创建独立的线程池,控制每个线程池的线程数量和队列大小
- 进程隔离:将不同类型的任务部署在不同的进程中,完全隔离资源
- 容器隔离:使用Docker容器等技术,为不同类型的任务创建独立的容器,隔离CPU、内存等资源
- 资源配额:为不同类型的任务设置CPU和内存配额,限制它们的资源使用
2.3 CPU/内存配额的实现原理
CPU/内存配额是指为任务或进程设置的CPU和内存使用上限,超过上限后系统会限制其资源使用。在Java应用中,可以通过以下方式实现:
- JVM参数:通过JVM参数设置堆内存大小、线程栈大小等
- 操作系统限制:使用操作系统的资源限制机制,如Linux的cgroups
- 应用级限制:在应用层面实现资源使用监控和限制
3. 实现方案:Spring Boot任务执行资源隔离
3.1 线程池隔离实现
在Spring Boot中,我们可以使用ThreadPoolTaskExecutor或ThreadPoolExecutor为不同类型的任务创建独立的线程池。
配置不同类型的线程池:
@Configuration
public class TaskExecutorConfig {
// 关键任务线程池
@Bean("criticalTaskExecutor")
public TaskExecutor criticalTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("critical-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
// 非关键任务线程池
@Bean("nonCriticalTaskExecutor")
public TaskExecutor nonCriticalTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(50);
executor.setThreadNamePrefix("non-critical-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
使用不同的线程池执行任务:
@Service
public class TaskService {
@Autowired
@Qualifier("criticalTaskExecutor")
private TaskExecutor criticalTaskExecutor;
@Autowired
@Qualifier("nonCriticalTaskExecutor")
private TaskExecutor nonCriticalTaskExecutor;
// 执行关键任务
public void executeCriticalTask(Runnable task) {
criticalTaskExecutor.execute(task);
}
// 执行非关键任务
public void executeNonCriticalTask(Runnable task) {
nonCriticalTaskExecutor.execute(task);
}
}
3.2 资源配额实现
在Spring Boot中,我们可以使用Java的ThreadMXBean和Runtime类监控和限制任务的资源使用。
CPU使用监控:
public class CpuMonitor {
private static final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
// 监控线程CPU使用情况
public static double getThreadCpuUsage(long threadId) {
if (threadMXBean.isThreadCpuTimeSupported()) {
long cpuTime = threadMXBean.getThreadCpuTime(threadId);
long userTime = threadMXBean.getThreadUserTime(threadId);
return (cpuTime - userTime) / 1000000.0; // 转换为毫秒
}
return 0.0;
}
// 监控进程CPU使用情况
public static double getProcessCpuUsage() {
if (threadMXBean.isCurrentThreadCpuTimeSupported()) {
long cpuTime = threadMXBean.getCurrentThreadCpuTime();
long userTime = threadMXBean.getCurrentThreadUserTime();
return (cpuTime - userTime) / 1000000.0; // 转换为毫秒
}
return 0.0;
}
}
内存使用监控:
public class MemoryMonitor {
private static final Runtime runtime = Runtime.getRuntime();
// 获取已用内存
public static long getUsedMemory() {
return runtime.totalMemory() - runtime.freeMemory();
}
// 获取最大内存
public static long getMaxMemory() {
return runtime.maxMemory();
}
// 获取内存使用百分比
public static double getMemoryUsagePercentage() {
return (double) getUsedMemory() / getMaxMemory() * 100;
}
}
资源配额控制:
public class ResourceQuotaManager {
// 检查CPU使用是否超过配额
public static boolean isCpuUsageExceeded(double cpuUsage, double quota) {
return cpuUsage > quota;
}
// 检查内存使用是否超过配额
public static boolean isMemoryUsageExceeded(double memoryUsage, double quota) {
return memoryUsage > quota;
}
// 限制任务执行时间
public static void executeWithTimeout(Runnable task, long timeoutMs) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> future = executor.submit(task);
try {
future.get(timeoutMs, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
future.cancel(true);
throw new RuntimeException("任务执行超时", e);
} catch (Exception e) {
throw new RuntimeException("任务执行失败", e);
} finally {
executor.shutdown();
}
}
}
3.3 任务执行隔离框架
我们可以创建一个任务执行隔离框架,为不同类型的任务提供独立的执行环境和资源配额。
任务执行器接口:
public interface TaskExecutor {
// 执行任务
void execute(Runnable task);
// 执行任务并返回结果
<T> Future<T> submit(Callable<T> task);
// 获取线程池名称
String getName();
// 获取资源配额
ResourceQuota getResourceQuota();
}
资源配额类:
public class ResourceQuota {
private double cpuQuota; // CPU使用上限(百分比)
private long memoryQuota; // 内存使用上限(字节)
private long timeout; // 任务执行超时时间(毫秒)
// 构造方法、getter和setter
}
任务执行器实现:
public class IsolatedTaskExecutor implements TaskExecutor {
private final String name;
private final ExecutorService executorService;
private final ResourceQuota resourceQuota;
public IsolatedTaskExecutor(String name, int corePoolSize, int maxPoolSize, int queueCapacity, ResourceQuota resourceQuota) {
this.name = name;
this.executorService = new ThreadPoolExecutor(
corePoolSize,
maxPoolSize,
60L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(queueCapacity),
new ThreadFactoryBuilder().setNameFormat(name + "-%d").build(),
new ThreadPoolExecutor.CallerRunsPolicy()
);
this.resourceQuota = resourceQuota;
}
@Override
public void execute(Runnable task) {
executorService.execute(() -> {
// 监控资源使用
monitorResourceUsage(task);
});
}
@Override
public <T> Future<T> submit(Callable<T> task) {
return executorService.submit(() -> {
// 监控资源使用
return monitorResourceUsage(task);
});
}
// 监控资源使用
private void monitorResourceUsage(Runnable task) {
long startTime = System.currentTimeMillis();
long threadId = Thread.currentThread().getId();
try {
task.run();
} finally {
long endTime = System.currentTimeMillis();
double cpuUsage = CpuMonitor.getThreadCpuUsage(threadId);
long memoryUsage = MemoryMonitor.getUsedMemory();
// 检查资源使用是否超过配额
if (ResourceQuotaManager.isCpuUsageExceeded(cpuUsage, resourceQuota.getCpuQuota())) {
System.out.println(name + " CPU使用超过配额: " + cpuUsage + "% > " + resourceQuota.getCpuQuota() + "%");
}
if (ResourceQuotaManager.isMemoryUsageExceeded(memoryUsage, resourceQuota.getMemoryQuota())) {
System.out.println(name + " 内存使用超过配额: " + memoryUsage + "B > " + resourceQuota.getMemoryQuota() + "B");
}
// 检查任务执行时间是否超过超时时间
if (endTime - startTime > resourceQuota.getTimeout()) {
System.out.println(name + " 任务执行超时: " + (endTime - startTime) + "ms > " + resourceQuota.getTimeout() + "ms");
}
}
}
// 监控资源使用(带返回值)
private <T> T monitorResourceUsage(Callable<T> task) throws Exception {
long startTime = System.currentTimeMillis();
long threadId = Thread.currentThread().getId();
try {
return task.call();
} finally {
long endTime = System.currentTimeMillis();
double cpuUsage = CpuMonitor.getThreadCpuUsage(threadId);
long memoryUsage = MemoryMonitor.getUsedMemory();
// 检查资源使用是否超过配额
if (ResourceQuotaManager.isCpuUsageExceeded(cpuUsage, resourceQuota.getCpuQuota())) {
System.out.println(name + " CPU使用超过配额: " + cpuUsage + "% > " + resourceQuota.getCpuQuota() + "%");
}
if (ResourceQuotaManager.isMemoryUsageExceeded(memoryUsage, resourceQuota.getMemoryQuota())) {
System.out.println(name + " 内存使用超过配额: " + memoryUsage + "B > " + resourceQuota.getMemoryQuota() + "B");
}
// 检查任务执行时间是否超过超时时间
if (endTime - startTime > resourceQuota.getTimeout()) {
System.out.println(name + " 任务执行超时: " + (endTime - startTime) + "ms > " + resourceQuota.getTimeout() + "ms");
}
}
}
@Override
public String getName() {
return name;
}
@Override
public ResourceQuota getResourceQuota() {
return resourceQuota;
}
// 关闭线程池
public void shutdown() {
executorService.shutdown();
}
}
任务执行隔离配置:
@Configuration
public class TaskIsolationConfig {
// 关键任务执行器
@Bean("criticalTaskExecutor")
public TaskExecutor criticalTaskExecutor() {
ResourceQuota resourceQuota = new ResourceQuota();
resourceQuota.setCpuQuota(50.0); // CPU使用上限50%
resourceQuota.setMemoryQuota(1024 * 1024 * 1024); // 内存使用上限1GB
resourceQuota.setTimeout(60000); // 任务执行超时时间60秒
return new IsolatedTaskExecutor(
"critical-task-executor",
10,
20,
100,
resourceQuota
);
}
// 非关键任务执行器
@Bean("nonCriticalTaskExecutor")
public TaskExecutor nonCriticalTaskExecutor() {
ResourceQuota resourceQuota = new ResourceQuota();
resourceQuota.setCpuQuota(30.0); // CPU使用上限30%
resourceQuota.setMemoryQuota(512 * 1024 * 1024); // 内存使用上限512MB
resourceQuota.setTimeout(300000); // 任务执行超时时间5分钟
return new IsolatedTaskExecutor(
"non-critical-task-executor",
5,
10,
50,
resourceQuota
);
}
}
4. 最佳实践:任务执行资源隔离的设计原则
4.1 任务分类
在设计任务执行资源隔离时,首先需要对任务进行分类,根据任务的重要性、执行时间、资源需求等因素,将任务分为不同的类别。
任务分类建议:
- 关键任务:如订单处理、支付交易、用户认证等,需要优先保证执行质量和响应速度
- 重要任务:如数据同步、消息处理等,需要保证执行质量,但对响应速度要求较低
- 普通任务:如日志处理、数据统计等,对执行质量和响应速度要求都较低
- 后台任务:如系统维护、数据清理等,对执行质量和响应速度要求最低
4.2 资源分配策略
根据任务的分类,为不同类型的任务分配不同的资源配额和执行策略。
资源分配建议:
- 关键任务:分配较多的CPU和内存资源,设置较短的执行超时时间,使用独立的线程池
- 重要任务:分配适中的CPU和内存资源,设置中等的执行超时时间,使用独立的线程池
- 普通任务:分配较少的CPU和内存资源,设置较长的执行超时时间,使用共享的线程池
- 后台任务:分配最少的CPU和内存资源,设置最长的执行超时时间,使用共享的线程池
4.3 监控和告警
为了及时发现和处理资源使用异常,需要对任务的资源使用情况进行监控和告警。
监控和告警建议:
- 实时监控:实时监控任务的CPU和内存使用情况
- 阈值告警:当资源使用超过阈值时,触发告警
- 历史分析:分析历史资源使用数据,优化资源分配策略
- 自动调优:根据历史数据,自动调整资源配额和执行策略
4.4 故障处理
为了保证系统的稳定性,需要对任务执行过程中的故障进行处理。
故障处理建议:
- 任务隔离:一个任务的故障不会影响其他任务的执行
- 故障重试:对于临时性故障,进行自动重试
- 故障降级:当系统资源不足时,降级非关键任务的执行质量
- 故障恢复:当系统资源恢复时,恢复任务的执行质量
5. 代码示例:Spring Boot任务执行资源隔离
5.1 项目结构
task-isolation-demo/
├── src/
│ ├── main/
│ │ ├── java/com/example/task/
│ │ │ ├── config/ # 配置类
│ │ │ ├── executor/ # 执行器
│ │ │ ├── monitor/ # 监控工具
│ │ │ ├── quota/ # 资源配额
│ │ │ ├── service/ # 服务类
│ │ │ ├── controller/ # 控制器
│ │ │ └── TaskIsolationDemoApplication.java # 应用入口
│ │ └── resources/ # 配置文件
│ └── test/ # 测试代码
└── pom.xml # Maven 依赖
5.2 核心代码
资源配额类:
package com.example.task.quota;
import lombok.Data;
@Data
public class ResourceQuota {
private double cpuQuota; // CPU使用上限(百分比)
private long memoryQuota; // 内存使用上限(字节)
private long timeout; // 任务执行超时时间(毫秒)
public ResourceQuota() {
this.cpuQuota = 100.0;
this.memoryQuota = Long.MAX_VALUE;
this.timeout = Long.MAX_VALUE;
}
}
CPU监控工具:
package com.example.task.monitor;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
public class CpuMonitor {
private static final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
// 监控线程CPU使用情况
public static double getThreadCpuUsage(long threadId) {
if (threadMXBean.isThreadCpuTimeSupported()) {
long cpuTime = threadMXBean.getThreadCpuTime(threadId);
long userTime = threadMXBean.getThreadUserTime(threadId);
return (cpuTime - userTime) / 1000000.0; // 转换为毫秒
}
return 0.0;
}
// 监控进程CPU使用情况
public static double getProcessCpuUsage() {
if (threadMXBean.isCurrentThreadCpuTimeSupported()) {
long cpuTime = threadMXBean.getCurrentThreadCpuTime();
long userTime = threadMXBean.getCurrentThreadUserTime();
return (cpuTime - userTime) / 1000000.0; // 转换为毫秒
}
return 0.0;
}
}
内存监控工具:
package com.example.task.monitor;
public class MemoryMonitor {
private static final Runtime runtime = Runtime.getRuntime();
// 获取已用内存
public static long getUsedMemory() {
return runtime.totalMemory() - runtime.freeMemory();
}
// 获取最大内存
public static long getMaxMemory() {
return runtime.maxMemory();
}
// 获取内存使用百分比
public static double getMemoryUsagePercentage() {
return (double) getUsedMemory() / getMaxMemory() * 100;
}
}
资源配额管理:
package com.example.task.quota;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class ResourceQuotaManager {
// 检查CPU使用是否超过配额
public static boolean isCpuUsageExceeded(double cpuUsage, double quota) {
return cpuUsage > quota;
}
// 检查内存使用是否超过配额
public static boolean isMemoryUsageExceeded(double memoryUsage, double quota) {
return memoryUsage > quota;
}
// 限制任务执行时间
public static void executeWithTimeout(Runnable task, long timeoutMs) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> future = executor.submit(task);
try {
future.get(timeoutMs, TimeUnit.MILLISECONDS);
} catch (Exception e) {
future.cancel(true);
throw new RuntimeException("任务执行超时", e);
} finally {
executor.shutdown();
}
}
}
任务执行器接口:
package com.example.task.executor;
import com.example.task.quota.ResourceQuota;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
public interface TaskExecutor {
// 执行任务
void execute(Runnable task);
// 执行任务并返回结果
<T> Future<T> submit(Callable<T> task);
// 获取线程池名称
String getName();
// 获取资源配额
ResourceQuota getResourceQuota();
}
隔离任务执行器:
package com.example.task.executor;
import com.example.task.monitor.CpuMonitor;
import com.example.task.monitor.MemoryMonitor;
import com.example.task.quota.ResourceQuota;
import com.example.task.quota.ResourceQuotaManager;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.*;
public class IsolatedTaskExecutor implements TaskExecutor {
private final String name;
private final ExecutorService executorService;
private final ResourceQuota resourceQuota;
public IsolatedTaskExecutor(String name, int corePoolSize, int maxPoolSize, int queueCapacity, ResourceQuota resourceQuota) {
this.name = name;
this.executorService = new ThreadPoolExecutor(
corePoolSize,
maxPoolSize,
60L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(queueCapacity),
new ThreadFactoryBuilder().setNameFormat(name + "-%d").build(),
new ThreadPoolExecutor.CallerRunsPolicy()
);
this.resourceQuota = resourceQuota;
}
@Override
public void execute(Runnable task) {
executorService.execute(() -> {
// 监控资源使用
monitorResourceUsage(task);
});
}
@Override
public <T> Future<T> submit(Callable<T> task) {
return executorService.submit(() -> {
// 监控资源使用
return monitorResourceUsage(task);
});
}
// 监控资源使用
private void monitorResourceUsage(Runnable task) {
long startTime = System.currentTimeMillis();
long threadId = Thread.currentThread().getId();
try {
task.run();
} finally {
long endTime = System.currentTimeMillis();
double cpuUsage = CpuMonitor.getThreadCpuUsage(threadId);
long memoryUsage = MemoryMonitor.getUsedMemory();
// 检查资源使用是否超过配额
if (ResourceQuotaManager.isCpuUsageExceeded(cpuUsage, resourceQuota.getCpuQuota())) {
System.out.println(name + " CPU使用超过配额: " + cpuUsage + "% > " + resourceQuota.getCpuQuota() + "%");
}
if (ResourceQuotaManager.isMemoryUsageExceeded(memoryUsage, resourceQuota.getMemoryQuota())) {
System.out.println(name + " 内存使用超过配额: " + memoryUsage + "B > " + resourceQuota.getMemoryQuota() + "B");
}
// 检查任务执行时间是否超过超时时间
if (endTime - startTime > resourceQuota.getTimeout()) {
System.out.println(name + " 任务执行超时: " + (endTime - startTime) + "ms > " + resourceQuota.getTimeout() + "ms");
}
}
}
// 监控资源使用(带返回值)
private <T> T monitorResourceUsage(Callable<T> task) throws Exception {
long startTime = System.currentTimeMillis();
long threadId = Thread.currentThread().getId();
try {
return task.call();
} finally {
long endTime = System.currentTimeMillis();
double cpuUsage = CpuMonitor.getThreadCpuUsage(threadId);
long memoryUsage = MemoryMonitor.getUsedMemory();
// 检查资源使用是否超过配额
if (ResourceQuotaManager.isCpuUsageExceeded(cpuUsage, resourceQuota.getCpuQuota())) {
System.out.println(name + " CPU使用超过配额: " + cpuUsage + "% > " + resourceQuota.getCpuQuota() + "%");
}
if (ResourceQuotaManager.isMemoryUsageExceeded(memoryUsage, resourceQuota.getMemoryQuota())) {
System.out.println(name + " 内存使用超过配额: " + memoryUsage + "B > " + resourceQuota.getMemoryQuota() + "B");
}
// 检查任务执行时间是否超过超时时间
if (endTime - startTime > resourceQuota.getTimeout()) {
System.out.println(name + " 任务执行超时: " + (endTime - startTime) + "ms > " + resourceQuota.getTimeout() + "ms");
}
}
}
@Override
public String getName() {
return name;
}
@Override
public ResourceQuota getResourceQuota() {
return resourceQuota;
}
// 关闭线程池
public void shutdown() {
executorService.shutdown();
}
}
任务执行隔离配置:
package com.example.task.config;
import com.example.task.executor.IsolatedTaskExecutor;
import com.example.task.executor.TaskExecutor;
import com.example.task.quota.ResourceQuota;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TaskIsolationConfig {
// 关键任务执行器
@Bean("criticalTaskExecutor")
public TaskExecutor criticalTaskExecutor() {
ResourceQuota resourceQuota = new ResourceQuota();
resourceQuota.setCpuQuota(50.0); // CPU使用上限50%
resourceQuota.setMemoryQuota(1024 * 1024 * 1024); // 内存使用上限1GB
resourceQuota.setTimeout(60000); // 任务执行超时时间60秒
return new IsolatedTaskExecutor(
"critical-task-executor",
10,
20,
100,
resourceQuota
);
}
// 非关键任务执行器
@Bean("nonCriticalTaskExecutor")
public TaskExecutor nonCriticalTaskExecutor() {
ResourceQuota resourceQuota = new ResourceQuota();
resourceQuota.setCpuQuota(30.0); // CPU使用上限30%
resourceQuota.setMemoryQuota(512 * 1024 * 1024); // 内存使用上限512MB
resourceQuota.setTimeout(300000); // 任务执行超时时间5分钟
return new IsolatedTaskExecutor(
"non-critical-task-executor",
5,
10,
50,
resourceQuota
);
}
}
任务服务:
package com.example.task.service;
import com.example.task.executor.TaskExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class TaskService {
@Autowired
@Qualifier("criticalTaskExecutor")
private TaskExecutor criticalTaskExecutor;
@Autowired
@Qualifier("nonCriticalTaskExecutor")
private TaskExecutor nonCriticalTaskExecutor;
// 执行关键任务
public void executeCriticalTask(Runnable task) {
criticalTaskExecutor.execute(task);
}
// 执行非关键任务
public void executeNonCriticalTask(Runnable task) {
nonCriticalTaskExecutor.execute(task);
}
}
测试控制器:
package com.example.task.controller;
import com.example.task.service.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private TaskService taskService;
// 测试关键任务
@GetMapping("/critical")
public String testCriticalTask() {
taskService.executeCriticalTask(() -> {
System.out.println("执行关键任务");
// 模拟任务执行
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
return "关键任务已提交";
}
// 测试非关键任务
@GetMapping("/non-critical")
public String testNonCriticalTask() {
taskService.executeNonCriticalTask(() -> {
System.out.println("执行非关键任务");
// 模拟任务执行
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
return "非关键任务已提交";
}
}
5.3 配置文件
application.yml:
spring:
application:
name: task-isolation-demo
# 任务执行资源隔离配置
task:
isolation:
critical:
cpu-quota: 50.0
memory-quota: 1024MB
timeout: 60s
non-critical:
cpu-quota: 30.0
memory-quota: 512MB
timeout: 300s
# 服务器配置
server:
port: 8080
5.4 测试场景
测试关键任务:
curl http://localhost:8080/test/critical
测试非关键任务:
curl http://localhost:8080/test/non-critical
测试资源使用监控:
- 执行关键任务,观察CPU和内存使用情况
- 执行非关键任务,观察CPU和内存使用情况
- 同时执行多个任务,观察资源隔离效果
6. 总结
通过不断优化和扩展,我们可以构建一个更加智能、高效、可靠的任务执行资源隔离系统,为应用程序的稳定运行提供有力保障。
更多技术文章,欢迎关注公众号:服务端技术精选
标题:SpringBoot + 任务执行资源隔离 + CPU/内存配额:关键任务独占资源,避免被其他任务拖垮
作者:jiangyi
地址:http://jiangyi.space/articles/2026/04/13/1775892313337.html
公众号:服务端技术精选
评论