提高服务器CPU使用率小工具
如果CPU的使用率没有达到30%,则可以启动工具,使其占用率达到30%
添加依赖
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>6.8.2</version>
</dependency>
实现代码
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 如果CPU的使用率没有达到30%,则启动一个CPU密集型任务,使其占用率达到30%
*
* @author yunze
* @apiNote 启动该任务需要再application.yml配置文件里配置task.cpuUsage.enabled=true,该任务默认是不启动的。
* @since 2025/7/23 14:33
*/
@ConditionalOnProperty(name = "task.cpuUsage.enabled", havingValue = "true", matchIfMissing = false)
@Component
public class OshiScheduler {
// 目标 CPU 使用率(30%)
private static final double TARGET_CPU_USAGE = 0.3;
// 线程池
private static final ExecutorService executor = Executors.newCachedThreadPool();
// 任务运行状态
private static final AtomicBoolean running = new AtomicBoolean(true);
// 任务数
private static final AtomicInteger taskCount = new AtomicInteger(0);
// 需要停止的任务
private static final AtomicInteger needStopTaskCount = new AtomicInteger(0);
private static final CopyOnWriteArraySet<String> taskList = new CopyOnWriteArraySet<>();
@Scheduled(cron = "0/5 * * * * ?")
public void monitorCPUUsage() {
getSystemUsage();
double cpuUsage = getCpuUsage();
System.out.printf(LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.NORM_DATETIME_PATTERN) + " CPU 使用率: %.2f%%,任务数:%d\n", cpuUsage * 100, taskList.size());
}
/**
* 检查操作系统的CPU使用情况
*/
@Scheduled(cron = "0/15 * * * * ?")
public void checkOSHI() {
System.out.println("开始监控并控制 CPU 使用率...");
double cpuUsage = getCpuUsage();
System.out.printf("当前 CPU 使用率: %.2f%%\n", cpuUsage * 100);
if (cpuUsage < TARGET_CPU_USAGE) {
// 当前 CPU 使用率太低,增加任务
startCpuIntensiveTask();
} else if (cpuUsage > TARGET_CPU_USAGE + 0.2) {
// 当前 CPU 使用率太高,减少任务
stopCpuIntensiveTask();
}
}
/**
* 获取当前 CPU 使用率
*/
public static double getCpuUsage() {
SystemInfo systemInfo = new SystemInfo();
CentralProcessor processor = systemInfo.getHardware().getProcessor();
long[] prevTicks = processor.getSystemCpuLoadTicks();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return processor.getSystemCpuLoadBetweenTicks(prevTicks);
}
/**
* 启动一个 CPU 密集型任务
*/
public static void startCpuIntensiveTask() {
System.out.println("启动一个 CPU 密集型任务");
if (taskCount.get() >= 100) { // 限制最大任务数
return;
}
taskCount.incrementAndGet();
if (needStopTaskCount.get() > 0) {
needStopTaskCount.decrementAndGet();
return;
}
executor.submit(() -> {
while (running.get()) {
if (needStopTaskCount.get() > 0) {
needStopTaskCount.decrementAndGet();
System.out.println("停止了一个任务");
taskList.remove(Thread.currentThread().getName());
return;
}
taskList.add(Thread.currentThread().getName());
// 简单的 CPU 密集型计算
double result = 0;
for (int i = 0; i < 100000 && running.get(); i++) {
result += Math.sqrt(i);
}
// 模拟短暂空闲
// LockSupport.parkNanos(WORK_INTERVAL_NS);
}
});
}
/**
* 停止一个任务
*/
public static void stopCpuIntensiveTask() {
needStopTaskCount.addAndGet(1);
if (taskCount.get() > 0) {
taskCount.decrementAndGet();
}
System.out.println("需要停止任务数:" + needStopTaskCount.get());
}
/**
* 停止所有任务(程序退出时调用)
*/
public static void shutdown() {
System.out.println("停止所有任务");
running.set(false);
executor.shutdown();
}
public void getSystemUsage() {
final long GB = 1024 * 1024 * 1024;
// while (true) {
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
String osJson = JSON.toJSONString(operatingSystemMXBean);
// System.out.println("osJson is " + osJson);
JSONObject jsonObject = JSON.parseObject(osJson);
double processCpuLoad = jsonObject.getDouble("processCpuLoad") * 100;
double systemCpuLoad = jsonObject.getDouble("systemCpuLoad") * 100;
Long totalPhysicalMemorySize = jsonObject.getLong("totalPhysicalMemorySize");
Long freePhysicalMemorySize = jsonObject.getLong("freePhysicalMemorySize");
double totalMemory = 1.0 * totalPhysicalMemorySize / GB;
double freeMemory = 1.0 * freePhysicalMemorySize / GB;
double memoryUseRatio = 1.0 * (totalPhysicalMemorySize - freePhysicalMemorySize) / totalPhysicalMemorySize * 100;
StringBuilder result = new StringBuilder();
result.append("系统CPU占用率: ")
.append(twoDecimal(systemCpuLoad))
.append("%,内存占用率:")
.append(twoDecimal(memoryUseRatio))
.append("%,系统总内存:")
.append(twoDecimal(totalMemory))
.append("GB,系统剩余内存:")
.append(twoDecimal(freeMemory))
.append("GB,该进程占用CPU:")
.append(twoDecimal(processCpuLoad))
.append("%");
System.out.println(result.toString());
}
public double twoDecimal(double doubleValue) {
BigDecimal bigDecimal = new BigDecimal(doubleValue).setScale(2, RoundingMode.HALF_UP);
return bigDecimal.doubleValue();
}
}