网站打不开是什么原因?从DNS到程序的分层定位法

来源:互联网 时间:2026-09-19

凌晨两点手机响了,客户说网站打不开。这种时候最忌讳的动作是马上登服务器重启一遍,它确实能解决一部分问题,但会把现场一起冲掉。网站打不开是句很笼统的话:从用户敲下域名到看见页面,中间要经过解析、连接、Web 服务、程序、数据库好几层,任何一层断了,用户看到的都是同一句打不开。分层定位的价值就在这里,顺着请求真实走过的链路一层层往下走,每层用一条命令确认,几分钟就能把范围缩到某一层,而不是在盲猜里耗一晚上。

一、先读浏览器给出的那句话

同样是打不开,浏览器的说法不一样,而这个说法本身就是第一条线索。提示找不到服务器地址、DNS 查询失败,问题在解析层;提示连接超时、无法建立连接,问题在连接或防火墙;能看到报错页并且带具体状态码,比如 500、502、504,说明 Web 服务还活着,毛病在后端;页面能打开但一片空白、或者一直转圈,多半是程序或数据库。

二、第一层是解析层,用 dig 和 nslookup 对答案

解析出问题无非两种表现:查不到记录,或者查到的地址不对。前者常见于域名过期、DNS 服务商抽风、记录被误删;后者更常见,是换了服务器没同步改解析,或者解析还停在一个已经下线的老地址上。判断办法是分别问本地 DNS 和公共 DNS,看两边答案一致不一致。

第一步就用下面这条命令查解析。系统默认 DNS 和公共 DNS 各查一次,对照看两边答案一不一致。

# 用系统默认 DNS 查一次
dig +short www.example.com

# 直接问公共 DNS,绕开本地缓存
dig +short www.example.com @223.5.5.5
dig +short www.example.com @8.8.8.8

# Windows 上用 nslookup 对照
nslookup www.example.com
nslookup www.example.com 223.5.5.5

两边答案不一致,说明本地或线路上的缓存还是旧的,等 TTL 过期或者手动刷新即可;两边都查不到,是记录本身的问题,去域名后台确认 A 记录还在不在、有没有被误删。这里有个容易吓到自己的情况:套了 CDN 的站,解析出来的本来就是 CDN 地址,不是你自己服务器的 IP。看到对不上先别慌,用 dig 追一下 CNAME 链,确认是正常接了 CDN 还是真解析错了。

三、第二层是连接层,判断端口通不通

解析对了还是打不开,下一步看能不能连上服务器。用 ping 判断主机可达性,用 nc 或 curl 判断端口是否放行。要分清一件事:ping 通不代表端口通,ping 不通也不代表服务挂了——很多服务器直接禁了 ICMP,只测 ping 很容易误判。判断以端口为准。

解析没问题,接着看能不能连上服务器。下面几条命令分别测主机可达性和端口通不通,判断以端口为准。

# 主机可达性(仅供参考,不能作为结论)
ping -c 4 www.example.com

# 关键:80 和 443 是否放行
nc -vz www.example.com 80
nc -vz www.example.com 443

# 没有 nc 就用 curl 只做握手,不取正文
curl -sS -o /dev/null -v --connect-timeout 5 https://www.example.com/ 2>&1 | head -20

端口不通,方向立刻明确:云平台的安全组、服务器本机的防火墙(iptables、firewalld)、CDN 的回源配置,三处里必有一处把请求挡了。排查顺序按改动频率来排,先看安全组,因为换服务器、改 IP 之后最容易忘的就是它,再看本机防火墙规则,最后看 CDN 回源有没有指对。反过来,端口通、握手正常,就说明网络这一段没问题,直接进下一层。

四、第三层是 Web 服务层,看服务在不在听

能连上端口却返回 502,或者干脆一片空白,说明请求到了服务器,但接请求的服务出了问题。在服务器上做三件事:看端口有没有进程在监听、看服务状态、从本机直接请求一次。

请求到了服务器却返回 502,说明接请求的服务出了问题。下面这几条命令依次看端口监听、服务状态,再从本机直接请求一次,最后两条把错误日志也带出来。

# 80/443 有没有进程在监听
ss -lntp | grep -E ':80|:443'

# Web 服务状态(Apache 环境换成 httpd)
systemctl status nginx --no-pager

# 绕开 DNS 和外部网络,从本机直接请求
curl -I http://127.0.0.1/
curl -I -H 'Host: www.example.com' http://127.0.0.1/

# 错误日志通常直接写着症结
tail -n 50 /var/log/nginx/error.log
journalctl -u nginx --since '30 min ago' -p err --no-pager

本机请求正常、外网请求不正常,问题在网络或前置代理;本机请求也不正常,问题就在 Web 服务这一层。看状态时重点看两样:最近有没有被重启过、日志里有没有反复出现的报错。配置写错一个字符 nginx 就起不来,而错误日志会把出问题的那一行写得很清楚。

五、第四层是后端程序,502 和 504 别混着看

这两个码经常被当成一回事,其实指向完全不同。502 是网关从后端拿到了无效响应,通常是后端进程挂了、端口没起、连接被拒;504 是网关等后端等到超时,后端进程还在,只是处理不完,症结多半在慢查询、外部接口卡住或者死循环。判断路径是:先看后端进程在不在,再看后端端口有没有起,最后翻程序自己的日志。php-fpm 打满、Java 进程被 OOM 干掉、Node 单进程被占死,都是这一层的常客。

六、第五层是数据库,最容易被跳过的一层

程序没毛病,但所有页面都卡住或者统一返回 500,就该往数据库想。磁盘写满会让数据库拒绝写入,连接数打满会让新请求排队,慢查询会把整个页面拖死。这三样几个命令就能看穿。

最后一层看数据库。下面这几个命令先确认磁盘是不是写满,再看负载、内存和 MySQL 连接情况,数据库层的故障一眼就能看穿。

# 磁盘是不是写满了(故障现场第一眼就看它)
df -h

# 负载和内存,有没有被换到 swap
uptime
free -m

# MySQL 连接情况(换成自己的账号密码)
mysql -uroot -p -e 'show processlist;'
mysql -uroot -p -e 'show status like "Threads_connected";'
mysql -uroot -p -e 'show variables like "max_connections";

磁盘写满最容易造成“突然全站打不开”,而且日志也写不进去,会连着把排查线索一起弄丢。养成一个习惯:不管什么故障,登上去先敲一次 df -h,一秒钟的事,能排掉一个高频原因。

七、把顺序固化成脚本,别靠临场回忆

上面五层的顺序,就是请求实际经过的顺序,跳层容易漏。实用的做法是拼成一个体检脚本,出事的时候跑一遍,几十秒拿到一份分层结果。

#!/bin/bash
# 分层体检:解析、端口、服务、本机、资源、日志一次跑完
DOMAIN="www.example.com"

echo "===== 1. 解析 ====="
dig +short "$DOMAIN" @223.5.5.5

echo "===== 2. 端口 ====="
nc -vz "$DOMAIN" 80
nc -vz "$DOMAIN" 443

echo "===== 3. Web 服务 ====="
systemctl is-active nginx

echo "===== 4. 本机请求 ====="
curl -s -o /dev/null -w "http_code=%{http_code} total=%{time_total}s\n" http://127.0.0.1/

echo "===== 5. 资源 ====="
uptime
df -h /

echo "===== 6. 最近错误日志 ====="
journalctl -u nginx -n 20 --no-pager

这个脚本只负责定型,不能代替判断,它的价值是把“先看什么、后看什么”固化下来,半夜出事不用靠脑子回忆命令。

分层定位的核心不是命令多熟,而是顺序:从上往下,一层一条命令确认,确认没问题再往下走。很多人排查慢,是因为一上来就跳到自己熟悉的那一层反复折腾,明明 502 是后端进程挂了,却一直在查 DNS。别跳层,也别一出事就重启,那个动作清掉的往往正是你最需要的证据。

相关阅读:

《浏览器打不开自己的网站?按这个顺序排查最快》

《网站打开速度慢怎么解决?从服务器到前端的优化路径》

《网站被攻击打不开?先止损再溯源的处理顺序》

相关文章

A5创业网 版权所有

返回顶部