雖然標題提到 Java 集合框架,但實際內容是兩個生產級 Shell 監控腳本,涵蓋系統資源監控與網站健康檢查,具備郵件告警、頻率控制、日誌記錄等完整功能。
#!/bin/bash
# 配置區
ROOT=$(cd "$(dirname "$0")"; pwd)
HOST=$(hostname)
NOTICE_EMAIL='admin@admin.com'
REMARK_EXPIRE=3600 # 告警間隔 1 小時
# 獲取 CPU 使用率 (vmstat 取樣 5 次平均)
GetCpu() {
cpufree=$(vmstat 1 5 | sed -n '3,$p' | awk '{x+=$15} END {print x/5}' | awk -F. '{print $1}')
cpuused=$((100 - cpufree))
check_and_alert "CPU" "$cpuused" 90 "$CPU_REMARK"
}
# 獲取記憶體狀態
GetMem() {
mem=$(free -m | sed -n '3,3p')
used=$(echo $mem | awk '{print $3}')
free=$(echo $mem | awk '{print $4}')
total=$((used + free))
limit=$((total / 10)) # 10% 閾值
check_and_alert "Memory" "$free" "$limit" "$MEM_REMARK" "lt" # 可用小於閾值
}
# 獲取 Load Average
GetLoad() {
load=$(uptime | awk -F 'load average: ' '{print $2}')
m1=$(echo $load | awk -F ', ' '{print $1}' | awk -F. '{print $1}')
check_and_alert "Load" "$m1" 2 "$LOAD_REMARK"
}
# 通用告警檢查 (支援大於/小於)
check_and_alert() {
local metric=$1 current=$2 threshold=$3 remark_file=$4 op=${5:-gt}
local remark=$(get_remark "$remark_file")
if [ -z "$remark" ]; then
if [ "$op" = "gt" ] && [ "$current" -gt "$threshold" ] || \
[ "$op" = "lt" ] && [ "$current" -lt "$threshold" ]; then
echo "Subject: ${HOST} ${metric} alert $(date)" | sendmail ${NOTICE_EMAIL}
echo "$(date +%s)" > "$remark_file"
fi
fi
}
# 讀取上次告警時間,過期則清除
get_remark() { ... }
# 主流程
cpuinfo=$(GetCpu)
meminfo=$(GetMem)
loadinfo=$(GetLoad)
echo "cpu: ${cpuinfo}" >> "${CPU_LOG}"
echo "mem: ${meminfo}" >> "${MEM_LOG}"
echo "load: ${loadinfo}" >> "${LOAD_LOG}"
SITES=("https://web01.example.com" "https://web02.example.com")
MAXLOADTIME=10
REMARKFILE='/tmp/monitor_load.remark'
for site in ${SITES[*]}; do
# 獲取連線時間、傳輸時間、總時間
site_load_time=$(curl -o /dev/null -s -w \
"time_connect: %{time_connect}\ntime_starttransfer: %{time_starttransfer}\ntime_total: %{time_total}" \
"${site}")
site_access=$(curl -o /dev/null -s -w "%{http_code}" "${site}")
time_total=${site_load_time##*:} # 提取總時間
# 告警邏輯 (同樣 1 小時頻率控制)
if [ -z "$REMARK" ]; then
if [ "$time_total" = "0.000" ] || [ "$site_access" != "200" ]; then
send_alert "${site} can not access"
elif [ "${time_total%%.*}" -ge ${MAXLOADTIME} ]; then
send_alert "${site} load time ${time_total}s"
fi
fi
done
| 項目 | 建議 |
|---|---|
| 排程 | crontab -e 添加 */1 * * * * /path/ServerMonitor.sh (每分鐘) 或 */30 * * * * * (每30秒需 systemd timer) |
| 郵件服務 | 確保 sendmail 或 postfix 已配置可發送外部郵件 |
| 日誌輪轉 | 配置 logrotate 避免日誌佔滿磁碟 |
| 權限 | 腳本需 chmod +x,以監控用戶身分執行 |
| 擴展 | 可加入磁碟空間、TCP 連線數、業務指標等監控項 |