Linux 服务器零成本告警方案:CPU / 内存超阈值自动发邮件(附完整脚本 + 避坑指南) Linux 服务器零成本告警方案CPU / 内存超阈值自动发邮件附完整脚本 避坑指南 前言小服务器也需要「会喊救命」不是每个团队一上来就有 Zabbix、Prometheus。很多中小项目、个人服务器、测试机就是几台孤零零的 Linux。它们出问题时往往是用户先发现、你最后才知道——CPU 被打满、内存被吃光、服务卡死而你还蒙在鼓里。其实不用上重型监控一套mailx Shell Crontab的组合十几行脚本就能让服务器在扛不住时主动给你发邮件求救零成本、零依赖、五分钟落地。但网上那些「复制粘贴」教程有个通病照抄却跑不通——openssl命令写错、证书配置混乱、更要命的是 CPU 一旦持续超标脚本会每分钟给你发一封邮件一夜之间几百封把邮箱塞爆。本文把这些坑逐个填平给你一套真正能上生产的方案。本文适合谁想给中小型 Linux 服务器加个轻量告警、又不想上重型监控系统的开发者 / 运维。全程 CentOS/RHEL 系为例脚本可直接用。阅读约 12 分钟。目录整体方案一张图看懂告警链路为什么装了 mailx 还要配 SMTP第一步安装邮件工具第二步配置 QQ 邮箱 SMTP含授权码获取第三步配置 SSL 证书重点填坑第四步发送测试邮件第五步监控告警脚本生产级带防骚扰第六步加入 Crontab 定时执行常见故障排查FAQ读者最常问的问题总结与延伸① 整体方案一张图看懂告警链路Crontab每分钟触发 │ ▼ monitor.sh ──采集──► CPU 使用率 / 内存使用率 │ │ 超过阈值 ┌─ 否 → 静默退出 ├────────────────────►┤ │ └─ 是 → 冷却期内──是→ 跳过防邮件轰炸 │ │ │ 否 ▼ ▼ 组织告警内容 ──mailx──► SMTP(smtp.qq.com:465, SSL) ──► 你的邮箱 整套方案只有三个角色Crontab 负责定时、Shell 负责判断、mailx 负责送信。理解这条链路后面每一步都是在实现它。② 为什么装了 mailx 还要配 SMTP先破除一个常见误解。很多教程让你同时装sendmail其实mailx 本身就能直连 SMTP 发信通过/etc/mail.rc里的set smtp...并不依赖本机跑一个 sendmail/postfix 邮件服务器装sendmail只是提供一个本地 MTA 兜底非必需。若你只是想「借 QQ 邮箱把告警发出去」光配好 mailx 的 SMTP 就够了。省心结论本文核心是让 mailx 走 QQ 邮箱的 SMTP 中转。sendmail 装不装都行别在它身上纠结。③ 第一步安装邮件工具# mailx邮件客户端负责组织并发送邮件核心yum-yinstallmailx# sendmail本地 MTA可选不装也能用 SMTP 直发yum-yinstallsendmail⚠️注意部分系统的包名是s-nailmailx 的后继。如果yum install mailx找不到包试试yum install s-nail配置方式一致。④ 第二步配置 QQ 邮箱 SMTP含授权码获取4.1 先拿到「授权码」不是登录密码QQ 邮箱不允许用登录密码做 SMTP 认证必须用授权码登录 QQ 邮箱网页版 →「设置」→「账号」找到「POP3/IMAP/SMTP…服务」开启「IMAP/SMTP 服务」按提示短信验证后会生成一串 16 位授权码复制保存。4.2 编辑/etc/mail.rc在文件末尾追加以下配置把占位符换成你自己的# 发件人对方看到的发件邮箱setfromyour_mailqq.com# QQ 邮箱 SMTP 服务器SSL 加密端口 465setsmtpsmtps://smtp.qq.com:465# SMTP 登录用户名即你的 QQ 邮箱setsmtp-auth-useryour_mailqq.com# ⚠️ 这里填【授权码】不是 QQ 登录密码setsmtp-auth-passwordxxxxxxxxxxxxxxxx# SMTP 认证方式setsmtp-authlogin# 忽略 SSL 证书严格校验配合下一步的证书使用setssl-verifyignore# NSS 证书库目录setnss-config-dir/root/.certs安全红线/etc/mail.rc里存了授权码明文。务必chmod 600 /etc/mail.rc收紧权限且绝不要把它提交到 Git 或截图公开。授权码泄露 你的邮箱被人拿去发信。⑤ 第三步配置 SSL 证书重点填坑QQ 的 465 端口走 SSLmailx 需要信任其证书。这一步是全网教程翻车重灾区注意命令细节# 1. 创建证书目录mkdir-p/root/.certs/cd/root/.certs/# 2. 下载 QQ SMTP 的 SSL 证书# ⚠️ 是 s_client 不是 ssl_client全网抄错最多的一行echo-n|openssl s_client-connectsmtp.qq.com:465\|sed-ne/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p/root/.certs/qq.crt# 3. 导入证书到 NSS 信任库目录统一用 /root/.certs信任位统一certutil-A-nQQ SMTP-tC,,-d/root/.certs-i/root/.certs/qq.crt# 4. 验证证书已导入certutil-L-d/root/.certs填坑说明原始教程里openssl ssl_client是错的该命令根本不存在正确的是openssl s_client别一会儿-d ~/.certs一会儿-d ./混着来全程统一用绝对路径/root/.certs否则证书导到别处、mailx 又找不到证书别名-n后面的随便起个能认的即可不必照抄 “GeoTrust” 那一堆。⑥ 第四步发送测试邮件配置完先验证连通性echo这是一封测试邮件|mail-s服务器邮件配置测试your_receiverqq.com收到邮件→ 恭喜SMTP 证书全部搞定可以进下一步没收到→ 先别急着改脚本直接跳到第 ⑨ 节「故障排查」按步定位。 测试时收件人可以先填自己确认链路通了再改成实际告警接收人。⑦ 第五步监控告警脚本生产级带防骚扰下面这版脚本相比网上流传的版本做了四处关键加固注释已标出直接可用#!/bin/bash# # Linux CPU / 内存 告警脚本生产加固版# # ---------- 可配置项 ----------TOyour_receiverqq.com# 收件人CPU_THRESHOLD80# CPU 告警阈值(%)MEM_THRESHOLD90# 内存告警阈值(%)COOLDOWN1800# 告警冷却时间(秒)30分钟内不重复发防轰炸STATE_FILE/var/tmp/monitor_alert.ts# 记录上次告警时间# ------------------------------# 【加固1】自动探测主网卡 IP不再硬编码 eth0云主机常是 ens33/enp0s3ip$(ip-4-oaddr show scope global|awk{gsub(/\/.*/,,$4); print $4; exit})# CPU 使用率 100 - 空闲率cpu$(top-b-n1|grepCpu(s)|tail-1\|awk-Fid,{split($1,vs,,); vvs[length(vs)]; gsub(/[^0-9.]/,,v); printf %d, 100-v})# 内存使用率 总内存 - 可用内存/ 总内存# 注依赖 free 的 available 列CentOS7/procps-ng 3.3.10mem$(free-m|awk/^Mem/{printf %d, ($2-$7)/$2*100})# 【加固2】判断是否触发告警CPU 或 内存 任一超阈值if[$cpu-gt$CPU_THRESHOLD]||[$mem-gt$MEM_THRESHOLD];then# 【加固3】冷却机制冷却期内直接退出避免每分钟狂发邮件now$(date%s)if[-f$STATE_FILE];thenlast$(cat$STATE_FILE)if[$((now-last))-lt$COOLDOWN];thenexit0# 还在冷却期静默跳过fifiSUBJECT【服务器告警】$ipCPU:${cpu}% 内存:${mem}% -$(date%F %T)# 【加固4】用 mktemp 生成临时文件杜绝追加残留与多进程竞争MSG$(mktemp /tmp/monitor.XXXXXX){echo服务器 IP :$ipecho告警时间 :$(date%F %T)echo-----------------------------------echoCPU 使用率 :${cpu}% (阈值${CPU_THRESHOLD}%)echo内存使用率 :${mem}% (阈值${MEM_THRESHOLD}%)echo-----------------------------------echoCPU 占用 TOP10 进程ps-eopcpu,pid,user,args|sort-k1-nr|head-10echo-----------------------------------echo内存占用 TOP10 进程ps-eopmem,pid,user,args|sort-k1-nr|head-10}$MSGmail-s$SUBJECT$TO$MSGecho$now$STATE_FILE# 记录本次告警时间开始冷却rm-f$MSG# 清理临时文件fi四处加固是精华所在自动探测网卡—— 换台云主机就不用改脚本CPU 内存双指标—— 原版只判断 CPU内存爆了不告警等于漏报冷却机制—— 这是原版最致命的缺失CPU 持续高负载时没有冷却就会每分钟一封邮件把你邮箱撑爆mktemp—— 避免固定文件名的内容残留和并发竞争。⑧ 第六步加入 Crontab 定时执行# 1. 保存脚本并授权mvmonitor.sh /usr/local/bin/monitor.shchmodx /usr/local/bin/monitor.sh# 2. 编辑定时任务crontab-e# 3. 加入下面一行每分钟执行一次* * * * * /usr/local/bin/monitor.sh⚠️Crontab 三大隐形坑环境变量极简cron 里PATH很短ip/top/mail等命令建议用绝对路径或在脚本开头export PATH/usr/bin:/bin:$PATH验证是否在跑tail -f /var/log/cron看有没有触发记录别忘了给脚本执行权限否则 cron 静默失败、什么都不发。⑨ 常见故障排查邮件发不出去时按这个顺序逐步定位从底层往上排查项命令说明网络/端口通不通telnet smtp.qq.com 465或curl -v telnet://smtp.qq.com:465不通多半是安全组/防火墙没放行 465证书是否导入certutil -L -d /root/.certs列表里得能看到你导入的证书邮件系统日志tail -f /var/log/maillogmailx 的报错这里最全加详细日志发信echo test | mail -v -s test youqq.com-v打印完整 SMTP 交互一眼看出卡在哪授权码是否正确重新在 QQ 邮箱生成授权码认证失败 90% 是把登录密码当授权码了最有用的一招加-v参数发信mail -v ...它会把和 SMTP 服务器的整个握手过程打印出来认证失败、证书拒绝、连接超时都一目了然。⑩ FAQ读者最常问的问题Q1一定要用 QQ 邮箱吗不是。163、Gmail、企业邮箱都行改set smtp、smtp-auth-user、授权码即可。端口和加密方式按各家文档来多为 465/SSL 或 587/STARTTLS。Q2内存使用率算出来是 0 或报错你的free版本没有available列较老系统。改用free | awk /Mem/{printf %d,$3/$2*100}按 used/total 估算即可。Q3为什么加了冷却还是收到重复告警检查/var/tmp/monitor_alert.ts是否可写、COOLDOWN是否设得太小。也可能是多台机器都在发——把 IP 放进主题就能区分。Q4能不能告警后自动处理比如重启服务能但要极其谨慎。在发邮件后加处理逻辑前务必先加二次确认/最大执行次数限制否则可能误杀正常进程。建议先只告警、人工介入。Q5告警太多想分级警告/严重怎么办设两档阈值比如 CPU80% 发「警告」、95% 发「严重」并缩短冷却时间主题里标注级别。Q6不想收邮件想发到钉钉/企业微信/飞书把mail -s ... $MSG换成对应机器人的 Webhookcurl调用即可采集和判断逻辑完全复用。⑪ 总结与延伸本文用mailx Shell Crontab搭了一套零成本的 Linux 告警方案核心要点环节关键点SMTP 配置用授权码而非密码/etc/mail.rc记得chmod 600证书命令是openssl s_client目录全程统一用绝对路径脚本CPU 内存双指标、自动探测网卡、mktemp临时文件防骚扰冷却机制是生产必备否则邮箱必被轰炸定时Crontab 注意 PATH 精简、脚本要有执行权限这套方案简单有效适合中小型服务器和个人项目。当机器数量上到几十台、需要历史趋势图和统一看板时再平滑升级到Zabbix / Prometheus Grafana也不迟——但那之前这十几行脚本足够帮你守住服务器的第一道防线。 如果本文帮到你欢迎点赞 / 收藏 / 关注。评论区聊聊你是怎么给服务器做告警的