Skip to content

Instantly share code, notes, and snippets.

@githubhjs
Created September 17, 2025 09:12
Show Gist options
  • Select an option

  • Save githubhjs/7c6d1f72ffac5e65954dfbfb3b0160b2 to your computer and use it in GitHub Desktop.

Select an option

Save githubhjs/7c6d1f72ffac5e65954dfbfb3b0160b2 to your computer and use it in GitHub Desktop.
60 秒系統快照腳本(拎了就跑), 把下列存成 sys-snapshot.sh 並給執行權限:
#!/usr/bin/env bash
set -euo pipefail
OUT="/tmp/sys_snapshot_$(hostname)_$(date +%F_%H%M%S).log"
{
echo "===== META ====="; date; hostnamectl || true; echo; uptime
echo; echo "===== CPU & MEM ====="; lscpu | egrep 'CPU|Thread|Model|NUMA' || lscpu; echo; free -m
echo; echo "===== LOAD / RUNQ (vmstat 1x10) ====="; vmstat 1 10
echo; echo "===== DISK I/O (iostat -xz 1x10) ====="; iostat -xz 1 10
echo; echo "===== TOP PROCS (CPU) ====="; ps -eo pid,ppid,comm,%cpu,%mem,stat --sort=-%cpu | head -n 30
echo; echo "===== PID I/O/CTX (pidstat -urd 1x5) ====="; pidstat -urd 1 5 || true
echo; echo "===== D-STATE TASKS ====="; ps -eo state,pid,ppid,comm,wchan:20 | awk '$1=="D"'
echo; echo "===== FILESYSTEM ====="; lsblk -o NAME,TYPE,FSTYPE,SIZE,MOUNTPOINT; echo; df -hT; echo; df -hi
echo; echo "===== KERNEL MSG (errors/warning) ====="; dmesg -T | egrep -i "error|warn|reset|I/O|nvme|xfs|ext4" | tail -n 200 || true
} | tee "$OUT"
echo "Saved to $OUT"
@githubhjs
Copy link
Copy Markdown
Author

ChatGPT said:

收到!馬上交付你要的三件事:① 異常自動留證(快照 + 定時器/cron)、③ htop 調校、④ LSF 佇列與資源限制範本。我用「貼上即可用」的檔案與指令寫好;參數都附上安全預設與註解。

① 異常自動留證:watchdog + 快照 + 定時器/cron

  1. 系統快照腳本(放 /usr/local/sbin/sys-snapshot.sh)

#!/usr/bin/env bash
set -euo pipefail
OUTDIR="/var/log/sys_snapshots"
mkdir -p "$OUTDIR"
OUT="$OUTDIR/sys_snapshot_$(hostname)$(date +%F%H%M%S).log"

{
echo "===== META ====="; date; hostnamectl 2>/dev/null || true; echo; uptime
echo; echo "===== CPU/MEM ====="; lscpu | egrep 'CPU|Thread|Model|NUMA' || lscpu; echo; free -m
echo; echo "===== vmstat (1s x10) ====="; vmstat 1 10
echo; echo "===== iostat -xz (1s x10) ====="; iostat -xz 1 10
echo; echo "===== Top 進程(CPU) ====="; ps -eo pid,ppid,comm,%cpu,%mem,stat --sort=-%cpu | head -n 30
echo; echo "===== pidstat -urd (1s x5) ====="; pidstat -urd 1 5 || true
echo; echo "===== D 狀態進程 ====="; ps -eo state,pid,ppid,comm,wchan:20 | awk '$1=="D"'
echo; echo "===== 檔案系統 ====="; lsblk -o NAME,TYPE,FSTYPE,SIZE,MOUNTPOINT; echo; df -hT; echo; df -hi
echo; echo "===== dmesg (I/O/磁碟/錯誤) ====="; dmesg -T | egrep -i "error|warn|reset|I/O|nvme|xfs|ext4" | tail -n 200 || true
} | tee "$OUT"

echo "Saved to $OUT"

sudo install -m 0755 sys-snapshot.sh /usr/local/sbin/

  1. watchdog 觸發器(放 /usr/local/sbin/snap-watchdog.sh)

每分鐘檢查一次;當任一條件命中就跑快照。閾值是保守、好理解的實務值。

#!/usr/bin/env bash
set -euo pipefail

CORES=$(nproc)
LOAD1=$(awk '{print $1}' /proc/loadavg) # 1 分鐘 load
LOAD_PER_CPU=$(awk -v l="$LOAD1" -v c="$CORES" 'BEGIN{printf "%.2f", l/c}')
IOWAIT=$(vmstat 1 2 | tail -1 | awk '{print $(NF-1)+0}') # wa%
DISK_UTIL=$(iostat -dx 1 2 | awk '/^(sd|nvme)/{u=$NF; if(u>max)max=u} END{print (max=="")?0:max+0}')
DSTATE=$(ps -eo s | awk '$1=="D"{c++} END{print c+0}')

可調閾值(命中任一條件即留證)

: "${THRESH_LOAD_PER_CPU:=0.90}" # load/CPU >= 0.90
: "${THRESH_IOWAIT:=10}" # iowait% >= 10
: "${THRESH_DISK_UTIL:=70}" # 磁碟%util >= 70
: "${THRESH_DSTATE:=5}" # D 狀態進程數 >= 5

TRIGGER=0
[ $(echo "$LOAD_PER_CPU >= $THRESH_LOAD_PER_CPU" | bc -l) -eq 1 ] && TRIGGER=1
[ $(echo "$IOWAIT >= $THRESH_IOWAIT" | bc -l) -eq 1 ] && TRIGGER=1
[ $(echo "$DISK_UTIL >= $THRESH_DISK_UTIL" | bc -l) -eq 1 ] && TRIGGER=1
[ "$DSTATE" -ge "$THRESH_DSTATE" ] && TRIGGER=1
[ "${SNAP_FORCE:-0}" != "0" ] && TRIGGER=1

if [ "$TRIGGER" -eq 1 ]; then
/usr/local/sbin/sys-snapshot.sh
fi

sudo apt-get -y install sysstat bc || sudo yum -y install sysstat bc
sudo install -m 0755 snap-watchdog.sh /usr/local/sbin/

3A) 用 systemd timer(推薦)

/etc/systemd/system/snap-watchdog.service

[Unit]
Description=Snapshot Watchdog (run snapshot on anomaly)

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/snap-watchdog.sh

/etc/systemd/system/snap-watchdog.timer

[Unit]
Description=Run Snapshot Watchdog every minute

[Timer]
OnBootSec=1min
OnUnitActiveSec=60s
AccuracySec=10s
Unit=snap-watchdog.service

[Install]
WantedBy=timers.target

啟用:

sudo systemctl daemon-reload
sudo systemctl enable --now snap-watchdog.timer
systemctl list-timers | grep snap-watchdog

3B) 或用 cron

root 的 crontab

          • /usr/local/sbin/snap-watchdog.sh >/dev/null 2>&1
  1. logrotate(保留 8 週,自動壓縮) /etc/logrotate.d/sys_snapshots

/var/log/sys_snapshots/*.log {
weekly
rotate 8
compress
missingok
notifempty
}

測試:
SNAP_FORCE=1 /usr/local/sbin/snap-watchdog.sh
看 /var/log/sys_snapshots/ 是否產生報告。

③ htop 調校(I/O、切換、執行緒一眼看穿)

快速做法(無需記數字欄位碼):

進入 htop → 按 F2(Setup)。

Meters:

Left:CPU (1/All)、Memory、Swap。

Right:加上 Load average、Uptime、Tasks、Disk I/O、Network I/O(若版本支援)。

Columns(Process fields):新增並靠前擺放

PERCENT_CPU, PERCENT_MEM, STATE, PRIORITY, NICE,

IO_RATE, IO_READ_RATE, IO_WRITE_RATE, IO_PRIORITY,

SWAPIN, THREADS, TIME+。
排序:F6 切到 IO_RATE(I/O 熱點時),平常用 PERCENT_CPU。

Display options:勾選

Highlight program basename、Show thread names、Tree view、Update process names。

顯示 CPU iowait 顏色(大多數發行版預設已顯示)。

讓設定常駐(建議)

mkdir -p ~/.config/htop
htop --write-config # 生成 htoprc 之後再進 F2 調整一次就會持久化

可選:預置一個偏好檔(部分版本支援這些鍵) ~/.config/htop/htoprc

若你的發行版支援,下列 meter 名稱會被解析;否則以 F2 介面調。

tree_view=1
highlight_base_name=1
show_thread_names=1

meters

left_meters=LeftCPUs2 Memory Swap
right_meters=RightCPUs2 Tasks LoadAverage Uptime DiskIO NetworkIO

提示:H 切換顯示執行緒;F5 樹狀;/ 搜索;K 清單上選 PID 後結束;i 依 IO 排序(部分版本的快捷鍵)。

④ LSF 佇列與資源限制:安全範本

目標:CPU 密集與I/O 密集分流;I/O 任務降低優先權、限制每台主機並發;預設每個 job 都要宣告記憶體。以下為常用、保守且容易回滾的設定。

檔案位置依發行不同,通常在 /opt/lsf/conf/ 或 /etc/lsf/。修改後執行 badmin reconfig 使其生效。

  1. Job starter:對 I/O 佇列自動降 nice/ionice
    /opt/lsf/job_starters/io_nice.sh

#!/usr/bin/env bash

降低 CPU 與 I/O 優先權,避免把機器 I/O 打爆

exec /usr/bin/ionice -c2 -n7 /usr/bin/nice -n 10 "$@"

sudo install -m 0755 io_nice.sh /opt/lsf/job_starters/

  1. 佇列定義(lsb.queues) — 新增兩條典型佇列

CPU 密集型(預設使用)

Begin Queue
QUEUE_NAME = compute.q
PRIORITY = 40
NICE = 0
RUNLIMIT = 04:00
SLOT_LIMIT = 256 # 此佇列最多用 256 個 slot(全叢集)
RES_REQ = select[type==linux] rusage[mem=4096] span[host=1] # 每 job 至少 4GB

允許超額提早啟動(視版本):先不開,若有 backfill 可再開

#JOB_STARTER =
End Queue

I/O 密集型:降優先、限並發、強制低 I/O 優先權

Begin Queue
QUEUE_NAME = io.q
PRIORITY = 20
NICE = 15
RUNLIMIT = 12:00
SLOT_LIMIT = 64 # 限制整個佇列 slot,避免全集群 I/O 滿載
RES_REQ = select[type==linux] rusage[mem=4096] span[ptile=4]
JOB_STARTER = /opt/lsf/job_starters/io_nice.sh

也可加:USER_JOB_LIMIT=20(每使用者同時最多 20 個 job)

End Queue

  1. 主機並發上限(lsb.hosts) — 控制每台主機可跑的 job 數

例如 128 vCPU 主機,允許最多 96 job slot,留 25% 緩衝給系統與互相干擾。

Begin Host
HOST_NAME = dcserver11
MXJ = 96 # Max eXecutable Jobs on this host
End Host

多台機器可用 host group(HOSTS=@compute),在 lsf.cluster. 定義群組後統一管理。

  1. 常用檢查

bqueues -l compute.q
bqueues -l io.q
bhosts -l dcserver11
badmin reconfig

  1. 使用示例

CPU 密集工作(預設)

bsub -q compute.q -R "rusage[mem=8192]" -n 8 ./run_cpu_task.sh

I/O 密集工作(分流 + 低優先權 + 限佇列並發)

bsub -q io.q -R "rusage[mem=8192]" ./run_io_task.sh

進階(之後可加):以 JOB_STARTER 包裝 cgroup(限制 IOPS/吞吐),或建立 fastio/slowio 主機群,讓 io.q 只落在特定磁碟型號。這需要在 lsf.cluster.* 或 lsb.resources 額外標註主機屬性,隨時可幫你補。

收束

watchdog 每分鐘巡檢、命中就「留證」,不會平時狂刷磁碟。

htop 專注 I/O 相關欄位,日常巡檢順眼又到位。

LSF 以「分流 + 降優先 + 佇列並發限制 + 主機 MXJ」形成四道保護,避免 I/O 把整台機器拖慢。

信心分數:94/100

可選下一步(編號回覆即可):

幫你把 JOB_STARTER 升級成 cgroup 版(限制 IOPS/MBps),附 systemd slice 與回滾腳本。

針對 io.q 製作 Prometheus 告警(聯合條件:iowait、%util、D 狀態)。

依你的機器清單生成 lsb.hosts/host groups 範本(含 MXJ 建議值)。

加上 fio 的安全只讀探針腳本與報表,幫你辨識哪顆盤是瓶頸。

做一個 htop 與 iostat 的 Tmux 面板檔,登入即一鍵監控。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment