系统监控

本指南将介绍如何使用 tio-utils 中的 SystemMonitorUtils 获取系统信息,以及如何将监控数据记录到数据库中。

一、使用 SystemMonitorUtils 获取系统信息

tio-utils 提供了 SystemMonitorUtils 类,方便用户获取系统的各种信息。以下是使用方法:

import com.litongjava.tio.utils.monitor.SystemMonitorUtils;

public class SystemInfoExample {
  public static void main(String[] args) {
    SystemInfo systemInfo = SystemMonitorUtils.getSystemInfo();
    // 处理 systemInfo 对象
  }
}

执行上述代码后,您将获得一个 SystemInfo 对象,包含系统的详细信息,例如:

{
  "availableProcessors": 1,
  "cpuUsage": 0,
  "fileRoots": ["/"],
  "freePhysicalMemorySize": 496308224,
  "heapMemoryMax": 2027290624,
  "heapMemoryUsed": 51288992,
  "javaVersion": "1.8.0_391",
  "jvmUptime": 116108,
  "jvmVendor": "Oracle Corporation",
  "nonHeapMemoryMax": -1,
  "nonHeapMemoryUsed": 29923864,
  "osArch": "amd64",
  "osName": "Linux",
  "osVersion": "5.15.98-fly",
  "systemLoadAverage": 0.009765625,
  "totalPhysicalMemorySize": 1014972416,
  "usedMemory": 0
}

SystemInfo 参数解释

以下是 SystemInfo 对象中各参数的详细解释:

  1. availableProcessors: 1
    可用的处理器核心数量。在此系统中,只有一个处理器核心。

  2. cpuUsage: 0
    当前的 CPU 使用率为 0%,表示系统处于空闲状态,没有明显的 CPU 负载。

  3. fileRoots: ["/"]
    系统的文件系统根目录。在此系统中,根目录为 /

  4. freePhysicalMemorySize: 496,308,224
    系统当前可用的物理内存大小(以字节为单位),约为 496 MB。

  5. heapMemoryMax: 2,027,290,624
    JVM 堆内存的最大值(以字节为单位),约为 2 GB。

  6. heapMemoryUsed: 51,288,992
    当前 JVM 已使用的堆内存大小(以字节为单位),约为 51 MB。

  7. javaVersion: "1.8.0_391"
    JVM 使用的 Java 版本为 1.8.0_391。

  8. jvmUptime: 116,108
    JVM 已运行的时间(以毫秒为单位),约为 116 秒。

  9. jvmVendor: "Oracle Corporation"
    提供 JVM 的厂商是 Oracle 公司。

  10. nonHeapMemoryMax: -1
    JVM 非堆内存的最大值为未指定(-1 通常表示不限制或未知)。

  11. nonHeapMemoryUsed: 29,923,864
    当前 JVM 已使用的非堆内存大小(以字节为单位),约为 29 MB。

  12. osArch: "amd64"
    操作系统的架构为 AMD64(64 位架构)。

  13. osName: "Linux"
    操作系统的名称为 Linux。

  14. osVersion: "5.15.98-fly"
    操作系统的版本号为 5.15.98-fly。

  15. systemLoadAverage: 0.009765625
    系统的 1 分钟平均负载,接近于 0,表示系统几乎没有负载。

  16. totalPhysicalMemorySize: 1,014,972,416
    系统的物理内存总大小(以字节为单位),约为 1 GB。

  17. usedMemory: 0
    当前已使用的内存为 0(可能因为未显式统计或未计算)。

计算已使用的物理内存大小

要计算系统已使用的物理内存大小,可以使用以下公式:

已使用的物理内存大小 = 总物理内存大小 - 可用的物理内存大小

根据上面的数据:

  • 总物理内存大小 (totalPhysicalMemorySize) = 1,014,972,416 字节
  • 可用的物理内存大小 (freePhysicalMemorySize) = 496,308,224 字节

计算结果为:

已使用的物理内存大小 = 1,014,972,416 - 496,308,224 = 518,664,192 字节

约为 518.66 MB

二、将监控数据记录到数据库

为了持续监控系统性能并记录历史数据,我们可以将收集到的系统信息保存到数据库中。

1. 添加 Maven 依赖

首先,在项目的 pom.xml 文件中添加 Quartz 调度框架的依赖,用于定时任务的调度:

<dependency>
  <groupId>org.quartz-scheduler</groupId>
  <artifactId>quartz</artifactId>
  <version>2.3.0</version>
</dependency>
<dependency>
  <groupId>org.quartz-scheduler</groupId>
  <artifactId>quartz-jobs</artifactId>
  <version>2.3.0</version>
</dependency>

2. 创建数据库表

在数据库中创建一张用于存储监控数据的表。以下是 PostgreSQL 的建表语句:

DROP TABLE IF EXISTS sys_monitor_performance;

CREATE TABLE public.sys_monitor_performance (
  id BIGINT NOT NULL PRIMARY KEY,
  ip VARCHAR,
  connections INTEGER,
  available_processors INTEGER,
  system_load_average NUMERIC DEFAULT 0,
  total_physical_memory_size BIGINT DEFAULT 0,
  free_physical_memory_size BIGINT DEFAULT 0,
  heap_memory_max BIGINT DEFAULT 0,
  heap_memory_used BIGINT DEFAULT 0,
  non_heap_memory_max BIGINT DEFAULT -1,
  non_heap_memory_used BIGINT DEFAULT 0,
  remark VARCHAR,
  creator VARCHAR DEFAULT '',
  create_time TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updater VARCHAR DEFAULT '',
  update_time TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
  deleted SMALLINT DEFAULT 0,
  tenant_id BIGINT NOT NULL DEFAULT 0
);

3. 编写数据收集和保存的服务类

创建一个服务类,用于收集系统信息并保存到数据库。以下是示例代码:

import com.litongjava.db.activerecord.Db;
import com.litongjava.db.activerecord.Record;
import com.litongjava.tio.boot.server.TioBootServer;
import com.litongjava.tio.core.Tio;
import com.litongjava.tio.utils.mcid.McIdUtils;
import com.litongjava.tio.utils.monitor.SystemMonitorUtils;
import com.litongjava.tio.utils.monitor.SystemInfo;
import com.litongjava.tio.utils.network.IpUtils;

public class SysMonitorPerformanceService {

  public void collectAndSave() {
    // 获取当前在线连接数
    int connections = Tio.getAll(TioBootServer.me().getServerTioConfig()).getObj().size();

    // 获取系统信息
    SystemInfo systemInfo = SystemMonitorUtils.getSystemInfo();

    // 创建记录对象
    Record record = Record.by("id", McIdUtils.id());
    record.set("ip", IpUtils.getLocalIp());
    record.set("connections", connections);
    record.set("available_processors", systemInfo.getAvailableProcessors());
    record.set("system_load_average", systemInfo.getSystemLoadAverage());
    record.set("total_physical_memory_size", systemInfo.getTotalPhysicalMemorySize());
    record.set("free_physical_memory_size", systemInfo.getFreePhysicalMemorySize());
    record.set("heap_memory_max", systemInfo.getHeapMemoryMax());
    record.set("heap_memory_used", systemInfo.getHeapMemoryUsed());
    record.set("non_heap_memory_max", systemInfo.getNonHeapMemoryMax());
    record.set("non_heap_memory_used", systemInfo.getNonHeapMemoryUsed());

    // 保存到数据库
    Db.save("sys_monitor_performance", record);
  }
}

代码说明:

  • 获取在线连接数:使用 Tio.getAll() 方法获取当前所有的连接数。
  • 获取系统信息:调用 SystemMonitorUtils.getSystemInfo() 方法获取系统信息。
  • 创建并设置记录:使用 Record 对象存储要保存的数据。
  • 保存到数据库:调用 Db.save() 方法将数据保存到 sys_monitor_performance 表中。

4. 编写定时任务

为了定期收集系统监控数据,我们可以使用 Quartz 调度框架来创建定时任务。

任务类代码:

import org.quartz.JobExecutionContext;
import com.litongjava.jfinal.aop.Aop;
import com.litongjava.tio.utils.quartz.AbstractJobWithLog;

public class CollectTask extends AbstractJobWithLog {

  @Override
  public void run(JobExecutionContext context) throws Exception {
    // 获取服务实例并调用数据收集方法
    Aop.get(SysMonitorPerformanceService.class).collectAndSave();
  }
}

代码说明:

  • 继承 AbstractJobWithLogCollectTask 继承自 AbstractJobWithLog,可以方便地记录任务执行日志。
  • 实现 run 方法:在 run 方法中,调用 SysMonitorPerformanceServicecollectAndSave 方法。

5. 配置定时任务

在 Quartz 的配置文件中,添加任务的调度配置。例如,使用 Cron 表达式配置任务每分钟执行一次:

com.red.book.task.CollectTask = 0 * * * * ?

说明:

  • 0 * * * * ?:表示每分钟的第 1 秒执行一次任务。

三、总结

通过以上步骤,我们实现了使用 SystemMonitorUtils 获取系统信息,并定期将监控数据保存到数据库中。这为我们监控系统性能、分析历史数据提供了基础。

注意事项:

  • 依赖库:确保项目中已添加必要的依赖库,例如 tio-utilsquartz 等。
  • 数据库连接:配置好数据库连接信息,确保数据能够正确保存。
  • 异常处理:在实际应用中,应添加必要的异常处理,确保程序的健壮性。