网站挂了?6个高频技术故障排查实录

王尘宇 问题解答 4

网站挂了?我踩过的6个坑和排查过程

上周四下午三点,客户打电话说官网打不开。我打开浏览器一看,大红叉——SSL证书过期了。这种事一年总会遇到两三次,但每次都是急事。下面这6个故障我过去两年里每个都至少处理过3次,把排查过程和坑点写出来,你看完起码知道从哪下手。

1. SSL证书过期:浏览器直接拦人

场景就是上面说的,用户访问时浏览器弹出"您的连接不是私密连接",根本进不去页面。Let's Encrypt的免费证书有效期一直是90天,很多人的certbot自动续期脚本跑着跑着就挂了没人知道。我遇到过一个站,证书过期了3天才被发现——因为运维离职了交接文档里没写。

排查很简单:点浏览器地址栏的小锁图标看到期日,或者F12进Security标签页。确认过期后SSH进服务器跑 certbot renew --dry-run 看看能不能自动续。80%的情况是certbot定时任务没配,或者防火墙把80端口封了导致HTTP验证失败。

解决办法:如果是nginx,先临时开80端口完成验证,certbot renew 然后 reload nginx。如果前面套了CDN(比如Cloudflare),证书是CDN那边管的,直接去CDN控制台更新就行,跟服务器没关系。建议设两个日历提醒:证书到期前30天和7天各弹一次,比任何监控脚本都靠谱。

2. CDN缓存清了页面还是不更新

这个问题在用了阿里云CDN或Cloudflare的站点上出现频率极高。你改了CSS,CDN后台点了刷新,自己电脑上好了,客户那边还是旧版。其实就是CDN的层级缓存问题——热节点刷了,边缘节点还没同步。

排查用 curl -I https://你的域名/path 看响应头的 X-Cache 和 Age。X-Cache 显示 HIT 且 Age 很大,说明节点还在用旧缓存。另一个坑:CDN控制台的刷新通常只刷了热节点,边缘节点要过5到15分钟。如果刷新的是带参数URL(比如 style.css?v=1.0),参数没变的话CDN可能认为不是新文件。

最暴力的解决办法:改文件名,style.css 改成 style.v2.css,100%有效。Cloudflare用户可以进缓存规则把那个路径临时设成"绕过缓存"。长期方案是nginx里对静态资源配置合理的 Cache-Control:图片设一年,CSS/JS设一周,HTML设不缓存。

3. 数据库连接数爆了,网站502

凌晨一点收到报警:网站全站502。SSH进去,MySQL日志里全是 "Too many connections"。这种情况通常不是并发高,而是有慢查询把连接池占满了,后面的请求全堵着。

排查命令:mysql -e "SHOW PROCESSLIST;" 看当前连接状态。如果一堆 "Sending data" 或 "Locked" 且跑了很久,就是有查询卡住了。再跑 SELECT * FROM information_schema.innodb_trx 查长时间未提交的事务。

我遇到过一个经典案例:定时任务没加索引,全表扫描300万行的表,每次跑7分钟,高峰期直接拖垮整个库。紧急处理:mysql -e "SET GLOBAL max_connections=500;" 临时提上限,然后找到慢查询 kill 掉。长期方案:加索引、max_connections 调到合理值(不是越大越好,内存撑不住)、配上连接超时时间。

4. 网站打开超过3秒,用户跑了一半

Google的数据说页面加载超过3秒,53%的移动用户会走。我实测过自己项目,加载从2.1秒优化到1.4秒,跳出率直接降了18个百分点。排查不能靠猜,得用数据说话。

工具就两个:浏览器DevTools的Network面板看每个资源耗时,加Lighthouse跑一遍看具体建议。我遇到的慢加载原因排名:第一是图片没压缩(首页banner图2MB,CDN上开个图片处理5毛钱的事),第二是没开Gzip/Brotli,第三是阻塞渲染的JS放到了head里。

操作方案:图片统一WebP格式、质量80%,肉眼看不出区别但体积小70%。nginx开 gzip_static 和 brotli。JS全部加 async 或 defer,或者挪到body底部。数据库查询加Redis缓存。这套组合下来,90%的站点能从3秒+降到1.5秒以内。

5. DNS改完部分地区还是旧IP

换服务器IP或切CDN后,总有人反馈打不开。你电脑上ping出来是新IP,客户那边是旧的。说白了就是各地运营商DNS缓存了旧记录,传播需要时间。

排查工具:whatsmydns.net 查全球解析情况,或者 dig @8.8.8.8 你的域名 和 dig @114.114.114.114 你的域名 分别查Google和114DNS。结果不一致就是还没同步完。

核心教训:切换IP之前先把TTL从默认的600秒改成60秒,等原TTL时间过了再做切换,这样切换后最多60秒就全局生效。如果已经切完了才发现问题只能等,一般24到48小时。救急方案:旧服务器上做个反向代理到新服务器过渡,我自己用过,管用。

6. 磁盘满了,网站直接500

这个故障出场方式特别突然:网站所有页面500,SSH进去敲任何命令都报 "No space left on device"。df -h 一看,根分区100%。

查谁吃了磁盘:du -sh /var/* | sort -rh | head -10,因为日志和数据库通常在这。罪魁祸首前三名:nginx日志没做logrotate(一个access.log攒了40GB)、MySQL binlog没设过期时间、Docker overlay2目录堆了半年没清理的无用镜像。

处理顺序:先清日志腾空间让服务恢复,nginx日志直接 echo '' > access.log 清空。然后设logrotate策略,日志保留7天自动压缩。MySQL设 expire_logs_days=7。Docker跑 docker system prune -a。最后加个磁盘监控,超过85%就报警,别等到100%。

上面这6个问题都是真实踩过的坑。网站运维大部分故障不复杂,关键是出问题时你知道从哪开始查。我的习惯是把每次故障处理过程记到Markdown文件里,搜起来比翻聊天记录快得多。如果你手头正好有哪个问题在折腾,希望能帮你省点时间。

标签: 技术问答 故障排查 网站运维 SSL CDN 数据库

发布评论 0条评论)

  • Refresh code

还木有评论哦,快来抢沙发吧~