From 22f6c407055b7515a5c88b5ec274ba42a70b8e6d Mon Sep 17 00:00:00 2001 From: 12600k-rog-d4 Date: Thu, 20 Aug 2026 08:09:01 +0800 Subject: [PATCH] Update auto-check config and stress modules --- auto-check/auto-check.yaml | 4 + auto-check/pkg/config/config.go | 18 ++- auto-check/pkg/sshclient/sshclient.go | 2 +- auto-check/pkg/stress/metrics.go | 11 +- auto-check/pkg/stress/runner.go | 43 +++--- auto-check/pkg/stress/tools.go | 71 ++++------ auto-check/run.log | 184 +++++++++++++------------- 7 files changed, 164 insertions(+), 169 deletions(-) diff --git a/auto-check/auto-check.yaml b/auto-check/auto-check.yaml index 736edd8..0d482cd 100644 --- a/auto-check/auto-check.yaml +++ b/auto-check/auto-check.yaml @@ -19,6 +19,10 @@ stress: types: "cpu,memory,disk,full" # 单项在前、综合(full)最后 duration: 30s threads: 4 + mem_size_mb: 0 # 内存压测占用(MB),0=自动(可用内存60%) + disk_size_mb: 1024 # 磁盘压测文件大小(MB) + disk_dir: "" # 磁盘压测目录,空=自动临时目录 + temp_interval: 10s # 温度采样间隔 temp_limit: 90 # 温度上限(°C),超过判失败,0=不判定 auto_install: true # 缺工具时在线安装(apt/dnf/yum 等),需要目标机可联网 use_mirror: false # 在线安装是否切换国内镜像源(清华TUNA)。国内网络卡顿/超时再改 true diff --git a/auto-check/pkg/config/config.go b/auto-check/pkg/config/config.go index 8576774..fd9bae8 100644 --- a/auto-check/pkg/config/config.go +++ b/auto-check/pkg/config/config.go @@ -46,6 +46,10 @@ type StressConfig struct { Types string `yaml:"types"` Duration time.Duration `yaml:"duration"` Threads int `yaml:"threads"` + MemSizeMB int `yaml:"mem_size_mb"` // 内存压测占用(MB),0=自动(可用60%) + DiskSizeMB int `yaml:"disk_size_mb"` // 磁盘压测文件大小(MB),0=默认1024 + DiskDir string `yaml:"disk_dir"` // 磁盘压测目录,空=自动临时目录 + TempInterval time.Duration `yaml:"temp_interval"` // 温度采样间隔,0=默认10s TempLimit float64 `yaml:"temp_limit"` // 温度上限(°C),0=不判定 AutoInstall bool `yaml:"auto_install"` // 缺工具时尝试在线安装(apt/dnf/yum 等) UseMirror bool `yaml:"use_mirror"` // 在线安装时切换国内镜像源(清华 TUNA),国内网络卡顿/超时再开启 @@ -87,12 +91,14 @@ func Default() *Config { Port: 22, }, Stress: StressConfig{ - Types: "cpu,memory", - Duration: 30 * time.Second, - Threads: 4, - TempLimit: 90, - AutoInstall: true, - UseMirror: false, + Types: "cpu,memory", + Duration: 30 * time.Second, + Threads: 4, + DiskSizeMB: 1024, + TempInterval: 10 * time.Second, + TempLimit: 90, + AutoInstall: true, + UseMirror: false, }, Workflow: WorkflowConfig{ Interval: 10 * time.Second, diff --git a/auto-check/pkg/sshclient/sshclient.go b/auto-check/pkg/sshclient/sshclient.go index 71fd6eb..e94dae6 100644 --- a/auto-check/pkg/sshclient/sshclient.go +++ b/auto-check/pkg/sshclient/sshclient.go @@ -81,7 +81,7 @@ func isNoiseLine(line string) bool { return true } } - // 某些横幅是 "Could: command not found" 这类由前面噪声行残生, + // 某些横幅是 "Could: command not found" 这类由前面噪声行产生, // 形如 "xxx: command not found" 且前半段是噪声关键词的也过滤 if strings.Contains(s, ": command not found") { return true diff --git a/auto-check/pkg/stress/metrics.go b/auto-check/pkg/stress/metrics.go index 2294d04..5d05801 100644 --- a/auto-check/pkg/stress/metrics.go +++ b/auto-check/pkg/stress/metrics.go @@ -79,11 +79,12 @@ func BuildMetrics(types []TestType, tools ToolSet) []Metric { type Config struct { Duration time.Duration Threads int - MemSizeMB int // 0=自动(可用60%) - DiskSizeMB int // 0=默认1024 - DiskDir string // 空=自动临时目录 - TempLogInt time.Duration // 0=10s - TempLimit float64 // 温度上限(°C),0=不判定 + MemSizeMB int // 0=自动(可用60%) + DiskSizeMB int // 0=默认1024 + DiskDir string // 空=自动临时目录 + TempLogInt time.Duration + TempLimit float64 // 温度上限(°C),0=不判定 + UseMirror bool // 在线安装时切换国内镜像源(清华TUNA) } // DefaultConfig 默认配置 diff --git a/auto-check/pkg/stress/runner.go b/auto-check/pkg/stress/runner.go index f6f5cbd..80706f4 100644 --- a/auto-check/pkg/stress/runner.go +++ b/auto-check/pkg/stress/runner.go @@ -36,7 +36,7 @@ type Runner struct { // NewRunner 创建执行器(检查/在线安装 → 构建指标 → 生成脚本 → 执行) func NewRunner(cfg Config, types []TestType, client *ssh.Client, autoInstall bool, sudoPwd string) *Runner { // 1. 检测工具,缺失时按发行版在线安装(可配置国内镜像源加速) - tools, failed := EnsureTools(client, requiredTools, autoInstall, sudoPwd) + tools, failed := EnsureTools(client, requiredTools, autoInstall, sudoPwd, cfg.UseMirror) metrics := BuildMetrics(types, tools) return &Runner{cfg: cfg, types: types, client: client, tools: tools, metrics: metrics, installFailed: failed} } @@ -285,14 +285,14 @@ func (r *Runner) assembleScript() string { sb.WriteString("set -e\n\n") // 导出参数变量 - sb.WriteString(fmt.Sprintf("export AUTOCHECK_DURATION=%d\n", int(r.cfg.Duration.Seconds()))) - sb.WriteString(fmt.Sprintf("export AUTOCHECK_THREADS=%d\n", r.cfg.Threads)) - sb.WriteString(fmt.Sprintf("export AUTOCHECK_DISK_SIZE_MB=%d\n", r.cfg.DiskSizeMB)) - sb.WriteString(fmt.Sprintf("export AUTOCHECK_MEM_SIZE_MB=%d\n", r.cfg.MemSizeMB)) - sb.WriteString(fmt.Sprintf("export AUTOCHECK_TEMP_INTERVAL=%d\n", int(r.cfg.TempLogInt.Seconds()))) + fmt.Fprintf(&sb, "export AUTOCHECK_DURATION=%d\n", int(r.cfg.Duration.Seconds())) + fmt.Fprintf(&sb, "export AUTOCHECK_THREADS=%d\n", r.cfg.Threads) + fmt.Fprintf(&sb, "export AUTOCHECK_DISK_SIZE_MB=%d\n", r.cfg.DiskSizeMB) + fmt.Fprintf(&sb, "export AUTOCHECK_MEM_SIZE_MB=%d\n", r.cfg.MemSizeMB) + fmt.Fprintf(&sb, "export AUTOCHECK_TEMP_INTERVAL=%d\n", int(r.cfg.TempLogInt.Seconds())) sb.WriteString("export AUTOCHECK_SAMPLE_INTERVAL=2\n") if r.cfg.DiskDir != "" { - sb.WriteString(fmt.Sprintf("export AUTOCHECK_DISK_DIR=%s\n", r.cfg.DiskDir)) + fmt.Fprintf(&sb, "export AUTOCHECK_DISK_DIR=%s\n", r.cfg.DiskDir) } sb.WriteString("\n") @@ -327,17 +327,17 @@ func (r *Runner) assembleScript() string { } if !m.Enabled { // 缺少依赖时仍输出一个 skip 结果,让报告完整展示原因 - sb.WriteString(fmt.Sprintf("echo '===TEST:%s==='\n", m.Name)) + fmt.Fprintf(&sb, "echo '===TEST:%s==='\n", m.Name) sb.WriteString("echo 'status:skip'\n") - sb.WriteString(fmt.Sprintf("echo 'output:%s'\n", m.DisableReason)) + fmt.Fprintf(&sb, "echo 'output:%s'\n", m.DisableReason) sb.WriteString("echo ''\n") continue } data := r.readScript(m.Name) if data == nil { - sb.WriteString(fmt.Sprintf("echo '===TEST:%s==='\n", m.Name)) + fmt.Fprintf(&sb, "echo '===TEST:%s==='\n", m.Name) sb.WriteString("echo 'status:skip'\n") - sb.WriteString(fmt.Sprintf("echo 'output:脚本文件 scripts/%s.sh 不存在'\n", m.Name)) + fmt.Fprintf(&sb, "echo 'output:脚本文件 scripts/%s.sh 不存在'\n", m.Name) sb.WriteString("echo ''\n") continue } @@ -406,9 +406,6 @@ func TestDevice(ip string, cfg config.Config) *Report { // "Could not chdir to home directory" 横幅污染命令输出,先建好 HOME sshclient.EnsureHome(conn) - // 根据配置决定是否在线安装时使用国内镜像源(默认 false,先试系统自带源) - SetMirror(cfg.Stress.UseMirror) - // sudo 密码:优先用专属 sudo_password;为空时退回 SSH 登录密码(飞牛 admin 同密码) sudoPwd := cfg.SSH.SudoPwd if sudoPwd == "" { @@ -424,13 +421,17 @@ func TestDevice(ip string, cfg config.Config) *Report { fmt.Printf(" [MAC] %s -> %s\n", ip, mac) } - stressCfg := Config{ - Duration: cfg.Stress.Duration, - Threads: cfg.Stress.Threads, - DiskSizeMB: 1024, - TempLogInt: 10 * time.Second, - TempLimit: cfg.Stress.TempLimit, - } + // 由默认配置 + yaml 映射构造(避免硬编码,便于后续扩展字段) + stressCfg := DefaultConfig() + stressCfg.Duration = cfg.Stress.Duration + stressCfg.Threads = cfg.Stress.Threads + stressCfg.MemSizeMB = cfg.Stress.MemSizeMB + stressCfg.DiskSizeMB = cfg.Stress.DiskSizeMB + stressCfg.DiskDir = cfg.Stress.DiskDir + stressCfg.TempLogInt = cfg.Stress.TempInterval + stressCfg.TempLimit = cfg.Stress.TempLimit + stressCfg.UseMirror = cfg.Stress.UseMirror + return NewRunner(stressCfg, ParseTypes(cfg.Stress.Types), conn, cfg.Stress.AutoInstall, sudoPwd).Run(ip) } diff --git a/auto-check/pkg/stress/tools.go b/auto-check/pkg/stress/tools.go index f6d56d5..f6cf578 100644 --- a/auto-check/pkg/stress/tools.go +++ b/auto-check/pkg/stress/tools.go @@ -13,24 +13,13 @@ import ( // 国内镜像源 // ============================ -// useMirror 控制是否把远端包管理器切到国内镜像。默认关闭——先用系统自带源 -// 试装(飞牛/群晖等定制系统常常已预置可用源),失败或超时再开启清华镜像。 -var useMirror = false - -// SetMirror 设置是否使用国内镜像源(由配置注入) -func SetMirror(on bool) { - useMirror = on -} - -// mirrorName 根据发行版返回镜像别名(用于日志) -const mirrorLabel = "清华 TUNA 镜像" - -// setupMirror 在安装前把对应包管理器的源切换为国内镜像(仅 apt 系需要改文件, -// 其它包管理器通过参数/变量临时指向镜像)。失败不致命,仅打印警告并继续用原源。 -func setupMirror(client *ssh.Client, pm string, sudoPwd string) { +// setupMirror 在安装前把对应包管理器的源切换为国内镜像(清华 TUNA)。 +// useMirror=false 时直接跳过(先用系统自带源试装)。失败不致命,仅提示并继续用原源。 +func setupMirror(client *ssh.Client, pm string, sudoPwd string, useMirror bool) { if !useMirror { return } + const label = "清华 TUNA 镜像" switch pm { case "apt-get": // 备份并替换为清华镜像(Debian/Ubuntu 通用,按 lsb_release 选版本) @@ -63,17 +52,14 @@ echo OK` if err != nil || !strings.Contains(out, "OK") { fmt.Printf(" [镜像] apt 切换国内源失败,将使用官方源: %v\n", err) } else { - fmt.Printf(" [镜像] apt 已切换至%s\n", mirrorLabel) + fmt.Printf(" [镜像] apt 已切换至%s\n", label) } - case "dnf", "yum": - // 清华镜像站对 dnf/yum 提供 repo 文件;这里用变量临时指向(持久化需改 repo) - cmd := `echo "腾讯/清华镜像需手动配置 repo;尝试临时使用 mirrors.tuna.tsinghua.edu.cn 变量"` - runPrivileged(client, cmd, sudoPwd) - // 通过 baseurl 变量临时覆盖(仅对部分仓库有效,作为加速兜底) - fmt.Printf(" [镜像] %s 使用系统默认源(建议手动配置%s repo)\n", pm, mirrorLabel) case "apk": runPrivileged(client, "sed -i 's#https\\?://[^/]*alpinelinux.org#https://mirrors.tuna.tsinghua.edu.cn/alpine#g' /etc/apk/repositories", sudoPwd) - fmt.Printf(" [镜像] apk 已切换至%s\n", mirrorLabel) + fmt.Printf(" [镜像] apk 已切换至%s\n", label) + default: + // dnf/yum 等无通用一键切源命令,需手动配置 repo 文件,这里仅提示 + fmt.Printf(" [镜像] %s 无内置切源逻辑,建议使用系统默认源或手动配置%s repo\n", pm, label) } } @@ -81,8 +67,9 @@ echo OK` // 远程工具检测 // ============================ -// 压测核心依赖工具(缺则按需在线安装)。lm-sensors 依赖较多,仅单文件 -// 二进制 stress-ng 与 fio 为必需;sensors 缺失仅影响温度曲线,不阻断压测。 +// requiredTools 压测核心依赖工具(缺则按需在线安装)。lm-sensors 依赖较多, +// 仅单文件二进制 stress-ng 与 fio 为必需;sensors 缺失仅影响温度曲线,不阻断压测。 +// 这是工具检测的唯一来源,DetectTools/EnsureTools 都从这里取列表,避免两处不一致。 var requiredTools = []string{"stress-ng", "fio"} // ToolInfo 远程工具信息 @@ -112,7 +99,7 @@ func (ts ToolSet) Get(name string) (ToolInfo, bool) { // DetectTools 检测远程所有相关工具是否可用 func DetectTools(client *ssh.Client) ToolSet { ts := ToolSet{Tools: make(map[string]ToolInfo)} - for _, name := range []string{"stress-ng", "stressapptest", "iperf3", "fio", "lm-sensors"} { + for _, name := range requiredTools { if info, ok := detectOne(client, name); ok { ts.Tools[name] = info } @@ -121,9 +108,10 @@ func DetectTools(client *ssh.Client) ToolSet { } // EnsureTools 检测工具;缺失且 autoInstall=true 时按发行版自动安装。 -// sudoPwd 为非 root 用户执行安装时提供(为空则尝试免密 sudo)。 -// 返回安装后的工具集合,以及最终仍缺失的工具名列表。 -func EnsureTools(client *ssh.Client, names []string, autoInstall bool, sudoPwd string) (ToolSet, []string) { +// sudoPwd 为非 root 用户执行安装时提供(为空则尝试免密 sudo)。useMirror=true +// 时安装前把包管理器源切换为国内镜像(清华 TUNA)。返回安装后的工具集合, +// 以及最终仍缺失的工具名列表。 +func EnsureTools(client *ssh.Client, names []string, autoInstall bool, sudoPwd string, useMirror bool) (ToolSet, []string) { ts := DetectTools(client) var missing []string for _, n := range names { @@ -142,7 +130,7 @@ func EnsureTools(client *ssh.Client, names []string, autoInstall bool, sudoPwd s return ts, missing // 无法识别包管理器,跳过安装 } // 安装前先把源切到国内镜像(使用官方源在网络差的环境会超时) - setupMirror(client, pm, sudoPwd) + setupMirror(client, pm, sudoPwd, useMirror) // 仅 apt 系需要先刷新元数据 if pm == "apt-get" { if out, err := runPrivileged(client, "timeout 180 apt-get update 2>&1", sudoPwd); err != nil || strings.Contains(out, "Err") || strings.Contains(out, "Failed") { @@ -282,24 +270,13 @@ func detectOne(client *ssh.Client, name string) (ToolInfo, bool) { return ToolInfo{}, false } - var version string - switch name { - case "stress-ng": - v, _ := sshclient.RunCommand(client, path+" --version 2>&1 | head -1") - version = strings.TrimSpace(v) - case "stressapptest": - v, _ := sshclient.RunCommand(client, path+" --help 2>&1 | head -1") - version = strings.TrimSpace(v) - case "iperf3": - v, _ := sshclient.RunCommand(client, path+" --version 2>&1 | head -1") - version = strings.TrimSpace(v) - case "fio": - v, _ := sshclient.RunCommand(client, path+" --version 2>&1 | head -1") - version = strings.TrimSpace(v) - case "lm-sensors": - v, _ := sshclient.RunCommand(client, path+" -v 2>&1 | head -1") - version = strings.TrimSpace(v) + // 取版本:lm-sensors 仅支持 -v,其余工具均支持 --version + verFlag := "--version" + if name == "lm-sensors" { + verFlag = "-v" } + v, _ := sshclient.RunCommand(client, path+" "+verFlag+" 2>&1 | head -1") + version := strings.TrimSpace(v) return ToolInfo{Name: name, Path: path, Version: version}, true } diff --git a/auto-check/run.log b/auto-check/run.log index fc52167..024baf9 100644 --- a/auto-check/run.log +++ b/auto-check/run.log @@ -1,142 +1,148 @@ [配置] 加载完成: 网段=10.0.3.0/24 间隔=3m0s 压测=cpu,memory,disk,full ══ 工作流启动(间隔 3m0s,设备以 IP 为 key)══ -════ 轮次开始 [13:42:10] ════ +════ 轮次开始 [01:18:28] ════ [扫描] 网段 10.0.3.0/24,共 254 个IP,10 并发 ping 探测... -[扫描] 完成,发现 11 台存活设备 - [扫描] 设备 11 台 +[扫描] 完成,发现 13 台存活设备 + [扫描] 设备 13 台 + [测试] 10.0.3.171 () 开始压测... + [测试] 10.0.3.171 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.171:22 失败: dial tcp 10.0.3.171:22: connectex: No connection could be made because the target machine actively refused it. + [测试] 10.0.3.175 () 开始压测... + [测试] 10.0.3.175 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.175:22 失败: dial tcp 10.0.3.175:22: connectex: No connection could be made because the target machine actively refused it. + [测试] 10.0.3.236 () 开始压测... + [测试] 10.0.3.236 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.236:22 失败: dial tcp 10.0.3.236:22: connectex: No connection could be made because the target machine actively refused it. + [测试] 10.0.3.4 () 开始压测... + [测试] 10.0.3.4 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.4:22 失败: dial tcp 10.0.3.4:22: connectex: No connection could be made because the target machine actively refused it. [测试] 10.0.3.1 () 开始压测... [测试] 10.0.3.1 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.1:22 失败: dial tcp 10.0.3.1:22: connectex: No connection could be made because the target machine actively refused it. [测试] 10.0.3.104 () 开始压测... [测试] 10.0.3.104 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.104:22 失败: dial tcp 10.0.3.104:22: connectex: No connection could be made because the target machine actively refused it. [测试] 10.0.3.123 () 开始压测... [测试] 10.0.3.123 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.123:22 失败: dial tcp 10.0.3.123:22: connectex: No connection could be made because the target machine actively refused it. - [测试] 10.0.3.152 () 开始压测... - [测试] 10.0.3.152 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.152:22 失败: dial tcp 10.0.3.152:22: connectex: No connection could be made because the target machine actively refused it. + [测试] 10.0.3.119 () 开始压测... + [测试] 10.0.3.119 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.119:22 失败: dial tcp 10.0.3.119:22: connectex: No connection could be made because the target machine actively refused it. [测试] 10.0.3.147 () 开始压测... [测试] 10.0.3.147 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.147:22 失败: dial tcp 10.0.3.147:22: connectex: No connection could be made because the target machine actively refused it. [测试] 10.0.3.148 () 开始压测... [MAC] 10.0.3.148 -> fe:49:6a:ab:e1:79 ════════ [10.0.3.148] 压力测试开始 ════════ - 工具: stress-ng(stress-ng, version 0.15.06 (gcc 12.2.0, x86_64 Linux 6.18.18.c877-trim)) iperf3(iperf 3.12 (cJSON 1.7.15)) fio(fio-3.33) + 工具: stress-ng(stress-ng, version 0.15.06 (gcc 12.2.0, x86_64 Linux 6.18.18.c877-trim)) fio(fio-3.33) 指标: cpu memory disk full dmesg [脚本] 拼装完成,10334 字节 [报告] reports/report-10.0.3.148.html ════════ [10.0.3.148] 压力测试完成 ════════ ══ [10.0.3.148] 压力测试报告 ══ - 耗时: 2m18.501s + 耗时: 2m23.341s ✓ cpu pass - 跑分: 1285.6 ops/s - 最高温度: 57.0°C - 平均CPU利用率: 99.1% - stress-ng: info: [3652909] Working directory / is not read/writeable, some I/O tests may fail - stress-ng: info: [3652909] setting to a 30 second run per stressor - stress-ng: info: [3652909] dispatching hogs: 4 cpu - stress-ng: metrc: [3652909] stressor bogo ops real time usr time sys time bogo ops/s bogo ops/s - stress-ng: metrc: [3652909] (secs) (secs) (secs) (real time) (usr+sys time) - stress-ng: metrc: [3652909] cpu 38577 30.01 90.66 0.43 1285.60 423.51 - stress-ng: info: [3652909] successful run completed in 30.02s + 跑分: 1622.1 ops/s + 最高温度: 53.0°C + 平均CPU利用率: 98.4% + stress-ng: info: [3783625] Working directory / is not read/writeable, some I/O tests may fail + stress-ng: info: [3783625] setting to a 30 second run per stressor + stress-ng: info: [3783625] dispatching hogs: 4 cpu + stress-ng: metrc: [3783625] stressor bogo ops real time usr time sys time bogo ops/s bogo ops/s + stress-ng: metrc: [3783625] (secs) (secs) (secs) (real time) (usr+sys time) + stress-ng: metrc: [3783625] cpu 48668 30.00 113.93 0.32 1622.06 426.00 + stress-ng: info: [3783625] successful run completed in 30.02s ✓ memory pass - 跑分: 33472.4 ops/s - 最高温度: 58.0°C - 峰值内存使用率: 57.1% - stress-ng: info: [3653312] Working directory / is not read/writeable, some I/O tests may fail - stress-ng: info: [3653312] setting to a 30 second run per stressor - stress-ng: info: [3653312] dispatching hogs: 4 vm - stress-ng: metrc: [3653312] stressor bogo ops real time usr time sys time bogo ops/s bogo ops/s - stress-ng: metrc: [3653312] (secs) (secs) (secs) (real time) (usr+sys time) - stress-ng: metrc: [3653312] vm 1006646 30.07 47.26 5.75 33472.37 18990.03 - stress-ng: info: [3653312] successful run completed in 30.28s + 跑分: 44033.6 ops/s + 最高温度: 53.0°C + 峰值内存使用率: 52.5% + stress-ng: info: [3783877] Working directory / is not read/writeable, some I/O tests may fail + stress-ng: info: [3783877] setting to a 30 second run per stressor + stress-ng: info: [3783877] dispatching hogs: 4 vm + stress-ng: metrc: [3783877] stressor bogo ops real time usr time sys time bogo ops/s bogo ops/s + stress-ng: metrc: [3783877] (secs) (secs) (secs) (real time) (usr+sys time) + stress-ng: metrc: [3783877] vm 1321192 30.00 96.84 5.67 44033.61 12888.25 + stress-ng: info: [3783877] successful run completed in 30.01s ✓ disk pass - 跑分: 445.0 MB/s - 读IOPS: 77.0 - 写IOPS: 34.0 - 总IOPS: 111.0 - 读吞吐: 309.0MB/s - 写吞吐: 136.0MB/s - 总吞吐: 445.0MB/s + 跑分: 391.0 MB/s + 读IOPS: 67.0 + 写IOPS: 29.0 + 总IOPS: 96.0 + 读吞吐: 271.0MB/s + 写吞吐: 120.0MB/s + 总吞吐: 391.0MB/s autocheck: (g=0): rw=randrw, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=psync, iodepth=32 fio-3.33 Starting 1 process autocheck: Laying out IO file (1 file / 1024MiB) note: both iodepth >= 1 and synchronous I/O engine are selected, queue depth will be capped at 1 - autocheck: (groupid=0, jobs=1): err= 0: pid=3653771: Thu Aug 13 13:44:37 2026 - read: IOPS=77, BW=309KiB/s (317kB/s)(9276KiB/30005msec) - clat (usec): min=253, max=830522, avg=11740.11, stdev=28335.80 - lat (usec): min=255, max=830525, avg=11742.04, stdev=28335.81 + autocheck: (groupid=0, jobs=1): err= 0: pid=3784176: Fri Aug 14 01:21:03 2026 + read: IOPS=67, BW=271KiB/s (277kB/s)(8328KiB/30763msec) + clat (usec): min=256, max=919497, avg=14116.10, stdev=41899.33 + lat (usec): min=257, max=919500, avg=14118.33, stdev=41899.33 clat percentiles (msec): | 1.00th=[ 4], 5.00th=[ 5], 10.00th=[ 6], 20.00th=[ 7], - | 30.00th=[ 8], 40.00th=[ 9], 50.00th=[ 11], 60.00th=[ 12], - | 70.00th=[ 13], 80.00th=[ 14], 90.00th=[ 15], 95.00th=[ 16], - | 99.00th=[ 59], 99.50th=[ 65], 99.90th=[ 676], 99.95th=[ 802], - | 99.99th=[ 835] - bw ( KiB/s): min= 28, max= 420, per=98.98%, avg=306.62, stdev=113.30, samples=29 - iops : min= 7, max= 105, avg=76.55, stdev=28.40, samples=29 - write: IOPS=34, BW=136KiB/s (140kB/s)(4088KiB/30005msec); 0 zone resets - clat (usec): min=131, max=841470, avg=2638.71, stdev=36403.27 - lat (usec): min=131, max=841473, avg=2641.68, stdev=36403.26 + | 30.00th=[ 8], 40.00th=[ 10], 50.00th=[ 11], 60.00th=[ 12], + | 70.00th=[ 13], 80.00th=[ 14], 90.00th=[ 15], 95.00th=[ 18], + | 99.00th=[ 65], 99.50th=[ 74], 99.90th=[ 869], 99.95th=[ 894], + | 99.99th=[ 919] + bw ( KiB/s): min= 84, max= 396, per=100.00%, avg=277.27, stdev=87.49, samples=30 + iops : min= 21, max= 99, avg=69.30, stdev=21.85, samples=30 + write: IOPS=29, BW=120KiB/s (123kB/s)(3684KiB/30763msec); 0 zone resets + clat (usec): min=135, max=285109, avg=1405.37, stdev=9787.22 + lat (usec): min=136, max=285113, avg=1408.31, stdev=9787.24 clat percentiles (usec): - | 1.00th=[ 188], 5.00th=[ 269], 10.00th=[ 318], 20.00th=[ 383], - | 30.00th=[ 449], 40.00th=[ 506], 50.00th=[ 586], 60.00th=[ 685], - | 70.00th=[ 824], 80.00th=[ 979], 90.00th=[ 1254], 95.00th=[ 1483], - | 99.00th=[ 9372], 99.50th=[ 15270], 99.90th=[767558], 99.95th=[843056], - | 99.99th=[843056] - bw ( KiB/s): min= 8, max= 211, per=99.09%, avg=135.72, stdev=55.82, samples=29 - iops : min= 2, max= 52, avg=33.83, stdev=14.03, samples=29 - lat (usec) : 250=1.11%, 500=10.72%, 750=8.20%, 1000=5.00% - lat (msec) : 2=4.88%, 4=1.65%, 10=33.49%, 20=33.10%, 50=0.57% - lat (msec) : 100=1.11%, 250=0.03%, 750=0.03%, 1000=0.12% - cpu : usr=0.46%, sys=2.25%, ctx=3357, majf=0, minf=13 + | 1.00th=[ 212], 5.00th=[ 289], 10.00th=[ 338], 20.00th=[ 400], + | 30.00th=[ 469], 40.00th=[ 537], 50.00th=[ 627], 60.00th=[ 758], + | 70.00th=[ 881], 80.00th=[ 1037], 90.00th=[ 1270], 95.00th=[ 1549], + | 99.00th=[ 17433], 99.50th=[ 22414], 99.90th=[283116], 99.95th=[283116], + | 99.99th=[283116] + bw ( KiB/s): min= 32, max= 192, per=100.00%, avg=122.73, stdev=43.53, samples=30 + iops : min= 8, max= 48, avg=30.63, stdev=10.85, samples=30 + lat (usec) : 250=0.87%, 500=9.59%, 750=7.86%, 1000=5.76% + lat (msec) : 2=5.56%, 4=1.00%, 10=32.17%, 20=33.70%, 50=0.87% + lat (msec) : 100=2.33%, 250=0.07%, 500=0.07%, 750=0.07%, 1000=0.10% + cpu : usr=0.56%, sys=1.94%, ctx=3031, majf=0, minf=12 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% - issued rwts: total=2319,1022,0,0 short=0,0,0,0 dropped=0,0,0,0 + issued rwts: total=2082,921,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=32 Run status group 0 (all jobs): - READ: bw=309KiB/s (317kB/s), 309KiB/s-309KiB/s (317kB/s-317kB/s), io=9276KiB (9499kB), run=30005-30005msec - WRITE: bw=136KiB/s (140kB/s), 136KiB/s-136KiB/s (140kB/s-140kB/s), io=4088KiB (4186kB), run=30005-30005msec + READ: bw=271KiB/s (277kB/s), 271KiB/s-271KiB/s (277kB/s-277kB/s), io=8328KiB (8528kB), run=30763-30763msec + WRITE: bw=120KiB/s (123kB/s), 120KiB/s-120KiB/s (123kB/s-123kB/s), io=3684KiB (3772kB), run=30763-30763msec Disk stats (read/write): - sda: ios=2319/1057, merge=0/81, ticks=26764/7589, in_queue=38611, util=97.50% + sda: ios=2085/984, merge=0/88, ticks=28333/21834, in_queue=54712, util=93.86% ✓ full pass - 跑分: 40708.6 ops/s - 最高温度: 58.0°C - 平均CPU利用率: 95.8% - 峰值内存使用率: 51.2% - stress-ng: info: [3653901] Working directory / is not read/writeable, some I/O tests may fail - stress-ng: info: [3653901] setting to a 30 second run per stressor - stress-ng: info: [3653901] dispatching hogs: 4 cpu, 4 vm, 2 iomix - stress-ng: metrc: [3653901] stressor bogo ops real time usr time sys time bogo ops/s bogo ops/s - stress-ng: metrc: [3653901] (secs) (secs) (secs) (real time) (usr+sys time) - stress-ng: metrc: [3653901] cpu 22552 30.02 54.07 0.35 751.21 414.42 - stress-ng: metrc: [3653901] vm 1193352 30.01 45.94 3.66 39767.94 24057.59 - stress-ng: metrc: [3653901] iomix 5692 30.04 2.13 4.02 189.48 924.72 - stress-ng: info: [3653901] successful run completed in 30.08s + 跑分: 33777.8 ops/s + 最高温度: 54.0°C + 平均CPU利用率: 92.1% + 峰值内存使用率: 51.9% + stress-ng: info: [3784311] Working directory / is not read/writeable, some I/O tests may fail + stress-ng: info: [3784311] setting to a 30 second run per stressor + stress-ng: info: [3784311] dispatching hogs: 4 cpu, 4 vm, 2 iomix + stress-ng: metrc: [3784311] stressor bogo ops real time usr time sys time bogo ops/s bogo ops/s + stress-ng: metrc: [3784311] (secs) (secs) (secs) (real time) (usr+sys time) + stress-ng: metrc: [3784311] cpu 24082 30.01 57.65 0.34 802.40 415.28 + stress-ng: metrc: [3784311] vm 1005657 30.64 44.02 4.26 32825.38 20831.04 + stress-ng: metrc: [3784311] iomix 4543 30.28 2.18 3.87 150.03 750.28 + stress-ng: info: [3784311] successful run completed in 32.51s ✓ dmesg pass 无硬件相关内核报错 共 5 项: 5 通过, 0 失败, 0 跳过, 0 错误 - [测试] 10.0.3.162 () 开始压测... - [测试] 10.0.3.162 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.162:22 失败: dial tcp 10.0.3.162:22: connectex: No connection could be made because the target machine actively refused it. - [测试] 10.0.3.119 () 开始压测... - [测试] 10.0.3.119 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.119:22 失败: dial tcp 10.0.3.119:22: connectex: No connection could be made because the target machine actively refused it. [测试] 10.0.3.160 () 开始压测... [测试] 10.0.3.160 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.160:22 失败: dial tcp 10.0.3.160:22: connectex: No connection could be made because the target machine actively refused it. - [测试] 10.0.3.171 () 开始压测... - [测试] 10.0.3.171 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.171:22 失败: dial tcp 10.0.3.171:22: connectex: No connection could be made because the target machine actively refused it. - [测试] 10.0.3.236 () 开始压测... - [测试] 10.0.3.236 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.236:22 失败: dial tcp 10.0.3.236:22: connectex: No connection could be made because the target machine actively refused it. - [状态] 10.0.3.160 ✗ → fail - [状态] 10.0.3.236 ✗ → fail - [状态] 10.0.3.1 ✗ → fail + [测试] 10.0.3.152 () 开始压测... + [测试] 10.0.3.152 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.152:22 失败: dial tcp 10.0.3.152:22: connectex: No connection could be made because the target machine actively refused it. + [测试] 10.0.3.162 () 开始压测... + [测试] 10.0.3.162 SSH 连接失败,跳过报告输出: SSH 连接 10.0.3.162:22 失败: dial tcp 10.0.3.162:22: connectex: No connection could be made because the target machine actively refused it. + [状态] 10.0.3.4 ✗ → fail [状态] 10.0.3.104 ✗ → fail [状态] 10.0.3.147 ✗ → fail - [状态] 10.0.3.119 ✗ → fail - [状态] 10.0.3.171 ✗ → fail - [状态] 10.0.3.123 ✗ → fail [状态] 10.0.3.152 ✗ → fail + [状态] 10.0.3.236 ✗ → fail + [状态] 10.0.3.1 ✗ → fail + [状态] 10.0.3.123 ✗ → fail + [状态] 10.0.3.119 ✗ → fail [状态] 10.0.3.148 (fe:49:6a:ab:e1:79) ✓ → pass + [状态] 10.0.3.160 ✗ → fail [状态] 10.0.3.162 ✗ → fail + [状态] 10.0.3.171 ✗ → fail + [状态] 10.0.3.175 ✗ → fail