服务器"突然打不开了",是运维里最常见也最容易慌的一类故障。用户的说法往往是"网站挂了""连不上了""一直转圈",但同样是打不开,背后的原因可能差得很远:可能是运营商线路抖动,可能是安全组把端口封了,可能是系统负载炸了,可能是 Nginx 进程崩了,也可能是后端数据库卡死了。如果没有章法,很容易变成"改一下这个、重启一下那个",越弄越乱。
这篇文章要给的是一套分层排查的方法论:把"无法访问"拆成网络层、系统层、服务层、应用层、数据库层五个层次,从外往里一层一层缩小范围,每一步都用具体命令给出证据。读完你应该能做到:接到报警后不慌不忙,先判断"是哪一层的问题",再用最短的路径定位到根因,而不是靠猜。
需要强调的是,分层排查的核心不是命令本身,而是顺序和思路。从下往上还是从上往下其实都可以,关键是每一层都要有明确的"通过/不通过"判据,找到第一个不通过的层次,再往下深挖。下面按"从外到内"的顺序展开。
一、先搞清楚"访问不了"到底指什么
同样是访问不了,现象的细微差别会直接影响排查方向。动手敲命令之前,先问清楚或者自己确认几件事:
- 范围:是所有人访问不了,还是只有你访问不了?只有个别人打不开,通常是本地网络、DNS 缓存或者运营商线路的问题;所有人都打不开,才是服务器侧的问题。
- 方式:是完全连不上(连接超时/拒绝),还是能连上但页面报错(502、504、500)?前者偏网络和进程,后者偏服务和应用。
- 协议:是 HTTP 打不开,还是 SSH 也连不上?如果 SSH 也进不去,问题多半在网络层或系统层;如果 SSH 正常但网站 502,那基本锁定在服务层或应用层。
- 时间点:是刚刚突然发生的,还是一直如此?结合"最近有没有改过配置、发过版本、加过数据",能快速缩小范围。
一个实用的技巧是:先用自己的手机 4G/5G 网络访问一次。如果手机流量能打开、公司网络打不开,说明服务器没问题,是本地出口或 DNS 的问题;如果手机也打不开,才需要上服务器排查。这一步能省掉大量无效劳动。
二、网络层:先确认"能不能通"
网络层要回答的问题只有一个:数据包能不能到达服务器、端口是不是开着。
# 1. 先看域名解析是否正常,确认解析到的 IP 是不是你以为的那台
dig +short www.example.com
nslookup www.example.com
# 2. ping 通不通,看丢包和延迟
ping -c 4 www.example.com
# 3. 测端口是否可达(telnet 或 nc 都行,nc 更通用)
telnet 203.0.113.10 80
nc -zv 203.0.113.10 80
nc -zv -w 3 203.0.113.10 443 # -w 指定超时秒数,避免卡死
# 4. 从 HTTP 层面看返回了什么
curl -I -m 10 http://www.example.com
curl -v -m 10 https://www.example.com # -v 打印握手细节,排查 TLS/跳转很有用
判读方式:
| 现象 | 含义 | 排查方向 |
|---|---|---|
| ping 不通但业务能用 | ICMP 被禁,正常 | 不代表故障,忽略 |
| ping 通、端口不通 | 服务未监听或防火墙拦截 | 系统层、防火墙 |
| 端口拒绝(Connection refused) | 能到主机,但没人监听该端口 | 服务未启动或端口改错 |
| 连接超时(timeout) | 包被丢弃,防火墙/安全组/线路问题 | 安全组、firewalld/ufw、iptables |
| 能连上但返回 502/504 | 网络通,问题在后端 | 服务层、应用层 |
最常见的坑是"安全组没放行"。云服务器的安全组是独立于操作系统防火墙的一层,很多人在服务器里 systemctl status firewalld 看是关的,就以为没防火墙,结果云控制台的安全组把 80/443 拦了。排查时务必把云安全组、系统防火墙(firewalld/ufw/iptables)、应用监听地址三样分开确认。
如果 ping 不通而且确定不是 ICMP 被禁,可以用 mtr 或 traceroute 看断在哪一跳,判断是本地出口、中间线路还是机房的问题:
mtr -rw -c 20 www.example.com # 融合 ping 和 traceroute,持续采样更准
traceroute www.example.com
三、系统层:看资源是否被耗尽
网络通了、端口也开着,但服务就是慢或者进不去,先把系统本身的资源看一遍。系统层要排查的是:负载、CPU、内存、磁盘、进程数、inode。
# 负载与运行时长:看 1/5/15 分钟平均负载
uptime
# CPU 与内存总览,按 M 键可按内存排序,按 P 按 CPU 排序
top -bn1 | head -20
free -h
# 磁盘空间和 inode(inode 用尽同样会导致写不进去、服务异常)
df -h
df -i
# 磁盘 IO 是否卡住
iostat -x 1 3 # 需 sysstat:yum install sysstat / apt install sysstat
iotop -oP # 需 iotop 包,看谁在疯狂读写
# 进程数、句柄数是否触顶
ps aux | wc -l
cat /proc/sys/kernel/pid_max
# 找出吃资源最多的进程
ps aux --sort=-%cpu | head -10
ps aux --sort=-%mem | head -10
几个关键判据(经验值,视机器规格而定):
- 负载:平均负载持续高于 CPU 核数(
nproc查看),说明有排队。4 核机器负载长期 > 4 就要警惕,> 8 基本就是过载。 - 内存:
free -h的 available 接近 0,且 swap 在被大量使用,往往伴随 OOM 风险。 - 磁盘:
df -h使用率超过 90% 要清理;df -iinode 使用率 100% 时,即使还有空间也写不进新文件,报错通常是No space left on device。 - IO:
iostat里%util长期贴着 100%,说明磁盘是瓶颈。
如果发现某个进程把 CPU 或内存吃满,先别急着 kill,先确认它是不是业务进程、能不能重启。正确做法是记录 PID、进程名、启动命令(ps -fp 、ls -l /proc/),再决定是限流、重启还是扩容。
四、服务层:进程在不在、端口听没听
系统资源没问题,就要看具体服务(Nginx、MySQL、Tomcat、Redis 等)的进程和端口状态。这是"能连上但 502/连不上"的高发区。
# 看服务状态(systemd 管理)
systemctl status nginx
systemctl status mysqld # Rocky/CentOS 上是 mysqld,Ubuntu 上可能是 mysql
systemctl is-active nginx # 只返回 active/inactive,适合脚本判断
# 查看最近日志(journalctl,systemd 系统通用)
journalctl -u nginx -n 100 --no-pager
journalctl -u nginx --since "1 hour ago" -p err
# 看端口有没有在监听、被谁监听
ss -lntp # 列出 TCP 监听端口及对应进程
ss -lntp | grep ':80'
ss -lnup | grep ':53' # udp 端口
# 老系统没有 ss 时用 netstat(net-tools 包)
netstat -lntp | grep ':80'
重点看两件事:进程是否存活、端口是否在监听。
- 进程不在、
systemctl status显示failed或activating (auto-restart):去看日志找崩溃原因,不要无脑systemctl restart,否则可能反复崩。 - 进程在、但端口没监听:可能是配置里绑定了特定 IP(比如只听了
127.0.0.1),外部访问不到;也可能是启动到一半卡住了。 - 进程在、端口也在听,但外部访问不了:多半是防火墙或安全组。
# 典型情况:Nginx 只监听了 127.0.0.1,外部访问不到
ss -lntp | grep ':80'
LISTEN 0 511 127.0.0.1:80 0.0.0.0:* users:(("nginx",pid=1234,fd=6))
# 注意 127.0.0.1 和 0.0.0.0 的区别,前者只接受本机连接
如果服务反复重启,看 systemctl status 输出里的 Restart= 和日志里的时间线;如果是被系统杀掉的,可能是 OOM(后面第六篇专门讲)。
五、应用层:看应用自身日志和依赖
服务进程、端口都正常,但访问还是报错,就要进到应用这一层。这里看的是应用自己的日志、配置文件、依赖服务。
# 应用日志在哪?先看配置和常见路径
ls -lh /var/log/nginx/
ls -lh /var/log/myapp/
tail -f /var/log/nginx/error.log
tail -n 200 /var/log/myapp/app.log | grep -i error
# 如果应用是 systemd 服务,stdout 会进 journal
journalctl -u myapp -f
# 从服务器本地直接请求,绕过外网干扰,看真实返回
curl -v http://127.0.0.1:8080/health
curl -v -H "Host: www.example.com" http://127.0.0.1/
应用层常见原因:配置写错(改完没 reload)、依赖服务连不上(数据库/Redis/MQ)、代码 bug、磁盘权限不足、证书过期(HTTPS 场景)。
证书过期是特别容易忽略的一类"全站突然打不开",因为它是按时触发的。用 curl -v 或下面命令能看到证书到期时间:
echo | openssl s_client -connect www.example.com:443 -servername www.example.com 2>/dev/null \
| openssl x509 -noout -dates
六、数据库层:最后确认后端是否响应
如果前端表现是接口超时、页面转圈、502/504,而 Nginx 和应用进程都正常,那根因很可能在后端数据库。数据库慢会一路传导到用户侧。
# MySQL 是否还在监听、能否登录
mysqladmin -uroot -p status
mysql -e "SHOW PROCESSLIST;" # 看有没有大量卡住的查询
mysql -e "SHOW ENGINE INNODB STATUS\G" | head -60 # 看锁等待、死锁
# 从应用服务器测数据库端口
nc -zv 10.0.0.5 3306
# Redis 是否响应
redis-cli ping # 返回 PONG 即正常
redis-cli info memory | grep used_memory_human
判读要点:SHOW PROCESSLIST 里如果有大量 Sending data、Locked 状态的连接,通常是有慢 SQL 或者表被锁住;连接数打满(接近 max_connections)会导致新连接直接被拒。这时不要盲目重启数据库(会丢事务、影响更大),先看慢查询、看锁、看连接数。
七、一张分层排查顺序表
把上面的内容压缩成一张表,遇到"无法访问"按顺序从上往下走,找到第一个不通过的层次即可:
| 顺序 | 层次 | 关键命令 | 判据 | 常见根因 |
|---|---|---|---|---|
| 1 | 客户端/本地 | 手机流量访问、换网络 | 换网络能开 | 本地 DNS、出口线路 |
| 2 | 网络/DNS | dig、ping、nc -zv、curl -I |
端口可达、返回预期状态码 | DNS 解析、安全组、线路 |
| 3 | 防火墙 | firewall-cmd、ufw status、iptables -L |
端口放行 | 安全组+系统防火墙双重拦截 |
| 4 | 系统资源 | uptime、free -h、df -h、df -i |
负载/内存/磁盘/inode 正常 | 过载、内存耗尽、磁盘满 |
| 5 | 服务进程/端口 | systemctl status、ss -lntp |
进程 active、端口 LISTEN | 进程崩溃、监听地址错 |
| 6 | 应用 | tail 日志、curl 127.0.0.1 |
本地请求正常返回 | 配置错、依赖不通、证书过期 |
| 7 | 数据库 | SHOW PROCESSLIST、nc -zv 3306 |
连接正常、无大量卡住查询 | 慢 SQL、锁等待、连接打满 |
绝大多数"无法访问"都能在这七步内定位。养成"先分层、再造证据"的习惯,比记住一堆零散命令更重要。
八、几个必须注意的风险点
排查过程中会用到一些有副作用的命令,动手前想清楚:
- 重启服务:
systemctl restart会中断现有连接。生产环境先确认有没有正在处理的任务,能reload就reload(Nginx、PHP-FPM 支持平滑重载),不要无脑 restart。 - 改防火墙:改之前先留一条能进的退路,尤其是 SSH 端口。远程改防火墙要用
firewall-cmd --add-* --timeout=60临时生效先测试,确认能进再永久保存。 - kill 进程:先想清楚这个进程是不是业务进程、杀掉会不会丢数据。数据库、MQ 这类有状态服务尤其要谨慎,优先用服务管理命令而非
kill -9。
# 防火墙临时放行示例(60 秒后自动失效,安全测试)
# RHEL/CentOS/Rocky
firewall-cmd --add-port=80/tcp --timeout=60
firewall-cmd --permanent --add-port=80/tcp && firewall-cmd --reload # 永久生效
# Debian/Ubuntu
ufw allow 80/tcp
ufw status verbose
常见问题
Q:服务器 ping 不通,但网站能打开,是不是有问题?
不是问题。很多云环境默认禁用 ICMP,ping 不通是正常的。判断连通性应该用 nc -zv 测端口,而不是靠 ping。
Q:安全组放行了,为什么还是连不上?
很可能是系统防火墙(firewalld/ufw/iptables)也拦着。云安全组和系统防火墙是两层,要分别确认。用 firewall-cmd --list-all 或 ufw status verbose 看系统侧,用 iptables -L -n 看底层规则。
Q:SSH 都进不去了,怎么办?
先确认是 SSH 端口不通还是口令错误。在能 ping 通的前提下用 nc -zv 测端口。如果端口不通,去云控制台用 VNC/救援终端登录,检查 sshd 状态和防火墙。如果端口通但登不上,看 journalctl -u sshd 或 /var/log/secure(Debian/Ubuntu 是 /var/log/auth.log)。
Q:能连上但页面一直转圈,该看哪一层?
页面转圈通常是后端响应慢,直接跳到第五、六层看应用日志和数据库。先用 curl -m 10 从本地请求接口,看是否超时,再去看慢 SQL 和锁等待。
Q:磁盘还有空间,为什么写文件报 No space left on device?
大概率是 inode 用尽了。用 df -i 查看,如果 inode 使用率 100%,需要找出大量小文件的目录(常是日志、缓存、session 文件)并清理。
总结
"无法访问"要先分层,再找证据。顺序是:客户端 → 网络/DNS → 防火墙 → 系统资源 → 服务进程/端口 → 应用 → 数据库,找到第一个不通过的层次深挖。
判断连通性用 nc -zv 测端口,不要只靠 ping;云安全组和系统防火墙是两层,必须分别确认。
服务层重点看进程是否存活、端口是否 LISTEN,注意监听地址是 0.0.0.0 还是 127.0.0.1;应用层重点看日志和本地 curl;后端慢就查数据库的连接数、慢查询和锁等待。
涉及重启服务、改防火墙、kill 进程等操作前,先评估影响、留好退路,能用 reload 和 --timeout 临时规则就不要用破坏性操作。
企业QQ咨询




