一个人维护几台服务器,最怕的不是技术难题,而是「没人提醒」。磁盘满了没人说,证书快到期没人说,某个服务凌晨三点挂了没人说,等你早上醒来发现客户投诉、搜索引擎降权,才知道出了事。十几年下来我逐渐形成了一个习惯:能自动发现的,绝不用眼睛盯;能用一行命令查的,绝不点开面板翻三层菜单。
这篇不讲具体命令大全,讲几件我认为最值得花时间建立的东西,以及哪些「看起来很专业」的做法其实不值得做。
一、把「我今天要看什么」压缩到一屏
很多人的监控是「装了一大堆面板」,Prometheus、Grafana、Zabbix 全上,十几个仪表盘,五颜六色的曲线。结果是没人看——因为看一次要花二十分钟,而且看到异常也不知道该不该管。
我现在的做法正相反:一台服务器写一个 check.sh,把最关键的七八个数字打成几行文本,每天早上定时发到我的手机或邮箱。内容大概是:磁盘根分区使用率、内存可用值、负载一分钟、Nginx 是否在跑、MySQL 是否在跑、最近一小时 5xx 数量、证书剩余天数、最近一次备份的文件时间。
这个东西的价值不在于「好看」,而在于一旦某天数字不对劲,我立刻能感觉到。人眼对「昨天 62%,今天 91%」这种变化非常敏感,比看曲线图快得多。
#!/bin/sh
echo "host: $(hostname) $(date '+%F %H:%M')"
echo "disk: $(df -h / | awk 'NR==2{print $5" used, "$4" free"}')"
echo "mem: $(free -m | awk 'NR==2{print $3"/"$2" MB"}')"
echo "load: $(cut -d' ' -f1-3 /proc/loadavg)"
echo "nginx:$(pgrep -c nginx) mysql:$(pgrep -c mysqld)"
echo "5xx: $(grep -c ' 50[0-9] ' /var/log/nginx/access.log)"这个脚本不到十行,但覆盖了 80% 的常见事故。后面再慢慢加,别一开始就追求完整。
二、日志只留「能用来查案」的部分
新手常犯的错是把日志留得越多越安心,结果磁盘被 access.log 吃掉一半。更麻烦的是,日志太大之后你根本不会去查它——查一次要扫几个 G。
我的做法是三件事。第一,logrotate 按天切割、保留 14 天、压缩,配置用 dateext 便于按日期找。第二,access log 的格式精简,去掉那些从来不用的字段,只留时间、IP、方法、URI、状态码、响应时间、UA,UA 也截断到 100 字符。第三,把「慢请求」单独过滤到另一个文件,方便盯着看:
map $request_time $slow_log {
default 0;
"~^([2-9]|[1-9][0-9])\." 1;
}
access_log /var/log/nginx/slow.log combined if=$slow_log;这样正常流量的日志照常滚,慢请求单独存一份,几十 MB,随时能翻。查性能问题的效率提升非常明显——你不用在几百万行里 grep 了。
三、备份的价值全在「恢复」那一刻
关于备份,我见过最多的错觉是「我有备份」。真相是:没验证过恢复的备份,只是心理安慰。硬盘上的 tar.gz 可能因为备份中途磁盘满而截断,可能因为数据库在备份过程中写入而不一致,可能因为权限不对恢复之后站点起不来。
所以我给自己的规矩很简单:每月至少恢复一次,而且是恢复到「另一台机器或另一个目录」,不是覆盖生产。恢复完要真的打开首页、登录后台、发一篇测试文章、走一遍搜索,能跑通才算数。
具体备份策略上,我用的是「数据库每日 dump + 站点文件每周 rsync 增量 + 配置单独 git 管理」三件套。数据库 dump 用 --single-transaction 保证 InnoDB 表一致性,不要用 --all-databases 一把梭,因为系统库恢复时经常出权限问题。站点文件主要是图片和上传附件,用 rsync --link-dest 做硬链接快照,占用空间小、每次看起来都是完整一份。
配置文件单独用 git 管,是我近几年最满意的一个改动。任何一次「改坏了要回滚」,都只需要 git diff 看一眼、git checkout 一下,比翻备份快十倍。而且 diff 本身就是文档,能看出上个月改了哪一行。
四、别让「顺手改一下」变成事故
根权限下的一次误操作,能抹掉几年的工作。我不是靠自律避免的,而是靠几个机械化的习惯:
一、动 rm 之前先把要删的路径 ls 一遍,尤其是有变量拼接的时候。rm -rf $DIR/ 里 $DIR 为空会变成 rm -rf /,这是经典事故,我的写法一律是 rm -rf "${DIR:?}/",变量为空直接退出。
二、改 Nginx、PHP、MySQL 配置之前先备份一份带日期的副本,改完先 nginx -t 再 reload。nginx -t 会真的去读配置、解析证书,能拦下 90% 的低级错误。
三、批量操作前先 --dry-run。rsync、rsync 删除、文件批量重命名、数据库批量更新,能 dry-run 的一律先跑一遍看清单。这个习惯帮我避免过至少三次「删错了目录」。
四、不在深夜改生产环境。这条听起来像鸡汤,其实是成本核算:深夜的判断力下降、别人都在睡觉没法帮你确认、出事后搜索引擎和用户都在抓取和访问。留到白天,还有人在旁边能说一句「你确定吗」。
五、写下来,比记在脑子里可靠
一个人做站长,最大的资产其实是「这台服务器上到底装了什么、为什么这么配」。半年后回来看,你会完全不记得为什么某个目录的权限是 750,为什么 Nginx 里有一段被注释掉的 location。
我现在的做法是每个站点根目录下放一个 OPS.md,写清楚:域名和 DNS 在哪里管、证书怎么续、数据库叫什么名字密码在哪、备份在哪恢复怎么恢复、上个月改过什么、有哪些已知但还没修的问题。内容不需要漂亮,但要具体到能照着操作。
这件事的收益不是「显得专业」,而是降低回来处理问题的启动成本。有这份文档,一年后半夜出故障,你打开就知道从哪查;没有这份文档,你得先花一小时回忆架构,事故时间就翻倍了。
六、这些事我试过,后来放弃了
说几个反向经验,可能比正向建议更省时间。
第一,全站装一堆监控告警。我试过给每个指标都设阈值告警,结果一天几十条通知,全部被无视,真正重要的那条也淹在里面。现在只保留三条告警:站点不可访问、磁盘超 90%、证书剩 15 天。少而准,才有人看。
第二,追求「零停机」的复杂架构。个人站点日流量几千,搞双机热备、主从切换、蓝绿部署,运维复杂度上升十倍,收益几乎为零。单机加一个每日备份加一个能快速重建的脚本,比什么都实在。
第三,为了「安全」把 SSH 端口改成奇怪数字。这挡不住真正的扫描,只增加自己记忆负担。真正有用的是禁 root 密码登录、只留密钥、装个简单的失败次数封禁。这两三件事做对,比换端口强得多。
第四,一开始就上容器。Docker 很好,但如果你只有一台机器、一个站点,容器化带来的编排、网络、存储排查成本,往往超过它省下的时间。等到「两台以上机器」或「两个以上环境」时再上,是更合适的时机。
七、最后一条:接受「不完美」
一个人的精力是有限的。我的服务器上有几处配置我自己知道不够好,比如某个老站还在用 PHP 7 的老版本、某段 Nginx 规则写得啰嗦。这些不是问题,因为我知道它们的风险和边界。
真正危险的是「不知道自己在冒什么风险」。所以与其追求把每件事做到最优,不如把每件事的边界搞清楚:这个版本什么时候停止支持、这个配置在什么情况下会失效、这个备份恢复需要多久。心里有数,就不慌。
把上面这些落成习惯之后,我的日常运维时间从每天两小时降到每天十分钟,剩下的时间才能真的用来做内容——那才是一个个人站长该花时间的地方。