服务器调试、测试与系统监测
服务器调试、测试与系统监测
时间:2026/05/04
关键词:文件描述符、内核参数、gdb、压力测试、tcpdump、lsof、nc、strace、ss、vmstat、mpstat
核心目标:建立 Linux 服务端排障和压测的基本工具箱,做到先观察、再定位、最后调参。
1. 先观察,再调参
服务端性能问题最忌讳:
- 一上来改 sysctl
- 一上来加线程
- 一上来怀疑 epoll
- 一上来重写架构
更稳的顺序是:
- 明确现象:吞吐低、延迟高、连接失败、CPU 高、内存涨
- 定位层次:应用、系统调用、内核网络栈、磁盘、网卡、对端
- 找证据:日志、连接状态、系统指标、抓包、性能采样
- 小步调整并压测验证
2. 最大文件描述符数
高并发服务端最常见资源限制是 fd 数。
查看当前 shell 限制:
1 | ulimit -n |
查看进程打开 fd:
1 | ls /proc/<pid>/fd | wc -l |
查看系统级限制:
1 | cat /proc/sys/fs/file-max |
程序里常见错误:
accept()返回EMFILE- 日志打不开
- 新连接失败
工程建议:
- 部署时显式配置 fd 上限
- 每个连接输入/输出缓冲也要有上限
- 监控进程 fd 使用量
3. 常见网络内核参数
常见查看方式:
1 | sysctl net.core.somaxconn |
常见参数:
| 参数 | 作用 |
|---|---|
net.core.somaxconn |
listen backlog 上限 |
net.ipv4.tcp_max_syn_backlog |
SYN 半连接队列上限 |
net.core.netdev_max_backlog |
网卡收包进入协议栈前的积压队列 |
net.ipv4.ip_local_port_range |
本地临时端口范围 |
net.ipv4.tcp_tw_reuse |
特定场景下 TIME_WAIT 复用 |
net.ipv4.tcp_syncookies |
SYN flood 防护 |
net.core.rmem_max/wmem_max |
socket 收发缓冲最大值 |
不要脱离现象硬改。
例如连接接不进来,可能是:
- 应用没及时 accept
- backlog 太小
- fd 耗尽
- SYN 队列满
- 防火墙或安全组问题
不同原因对应的处理完全不同。
4. gdb 调试多进程
多进程程序常见设置:
1 | set follow-fork-mode child |
含义:
follow-fork-mode child:fork 后跟踪子进程detach-on-fork off:父子进程都保留在 gdb 中
查看 inferiors:
1 | info inferiors |
常用思路:
- master/worker 模型里确认自己跟的是哪个进程
- 子进程崩溃时保留 core
- 用日志打印 pid,方便 attach
5. gdb 调试多线程
常用命令:
1 | info threads |
排查场景:
- 死锁:所有线程栈停在哪些锁上
- 卡顿:I/O 线程是否阻塞在慢调用
- 崩溃:当前线程栈和共享对象状态
编译时建议:
1 | -g -O0 |
或线上保留:
1 | -g -O2 |
方便在接近真实优化路径下分析。
6. 压力测试关注什么
压测不是只看 QPS。
至少要记录:
- QPS / TPS
- 平均延迟
- P95 / P99 / P999
- 错误率
- 连接失败数
- CPU 使用率
- 内存和 fd 数
- 上下文切换
- 网络收发吞吐
- 重传和丢包
常见工具:
abwrkheyiperf3- 自写协议压测客户端
压测原则:
- 压测机不要成为瓶颈
- 区分短连接和长连接
- 预热后再采样
- 看尾延迟,不只看平均值
- 每次只改一个变量
7. tcpdump:抓包看真相
常用命令:
1 | tcpdump -nn -i any tcp port 8080 |
保存到文件:
1 | tcpdump -nn -i eth0 -w out.pcap tcp port 8080 |
排查时重点看:
- 三次握手是否完成
- 谁先发
FIN - 是否出现
RST - 是否有大量重传
- ACK 是否异常
- 包是否到达本机
抓包能回答:
问题到底发生在应用之前,还是应用之后。
8. lsof:查看进程打开了什么
查看进程 fd:
1 | lsof -p <pid> |
查看端口:
1 | lsof -i :8080 |
常见用途:
- 找到哪个进程占用了端口
- 查看 fd 是否泄漏
- 看日志文件是否被删除但仍被进程持有
- 确认 socket 状态
9. nc:网络瑞士军刀
连接 TCP 服务:
1 | nc 127.0.0.1 8080 |
监听端口:
1 | nc -l 8080 |
发送简单请求:
1 | printf 'hello\n' | nc 127.0.0.1 9876 |
适合:
- 快速验证端口通不通
- 手工测试文本协议
- 配合 echo server 调试
10. strace:看系统调用
跟踪进程:
1 | strace -tt -p <pid> |
统计系统调用耗时:
1 | strace -c -p <pid> |
跟踪网络相关:
1 | strace -e trace=network -p <pid> |
常见用途:
- 确认程序卡在哪个系统调用
- 看
accept/read/write/epoll_wait返回值 - 看
EAGAIN/EINTR/ECONNRESET - 排查文件路径和权限问题
注意:
strace会带来额外开销- 线上使用要控制时间和范围
11. netstat 与 ss
现代 Linux 更推荐 ss。
查看监听端口:
1 | ss -lntp |
查看连接摘要:
1 | ss -s |
查看 TCP 详细信息:
1 | ss -tin sport = :8080 |
重点关注:
ESTABLISHEDTIME-WAITCLOSE-WAIT- send-q / recv-q
- retrans
- rtt
send-q 长期很大,通常说明对端慢读或网络发送受阻。recv-q 长期很大,通常说明应用读得不及时。
12. vmstat、mpstat、ifstat
vmstat 看整体系统:
1 | vmstat 1 |
关注:
r:运行队列si/so:swap in/outus/sy/id/wa:CPU 使用分布cs:上下文切换
mpstat 看每核 CPU:
1 | mpstat -P ALL 1 |
关注:
- 是否单核打满
- 软中断是否集中在某些 CPU
- I/O 线程是否分布合理
ifstat 或 sar -n DEV 看网卡吞吐:
1 | sar -n DEV 1 |
关注:
- 收发吞吐是否接近网卡上限
- 是否有明显丢包
- 多队列是否均衡
13. 现代补充工具
虽然经典书里会列传统工具,现代环境还常用:
perf top/record/report:CPU 热点pidstat -t:线程级 CPU 和上下文切换iotop:磁盘 I/Odmesg:内核日志journalctl:systemd 日志bpftool/ bpftrace:更深入的内核观测
排障时不要迷信单个工具。
最好把应用日志、系统指标、抓包和 profiler 放在同一条时间线上看。
14. 常见问题排查路径
14.1 连接不上
检查:
ss -lntp是否监听- 防火墙/安全组
tcpdump是否看到 SYN- backlog / SYN 队列 / fd 上限
- 应用日志是否 accept 报错
14.2 延迟高
检查:
- I/O 线程是否被阻塞
- worker 队列是否积压
- 日志是否同步刷盘
ss -tin是否有重传或 RTT 异常perf是否有明显热点
14.3 内存涨
检查:
- 连接数
- 每连接输入/输出缓冲
- 任务队列长度
- 慢客户端数量
- 是否有泄漏
14.4 CPU 高
检查:
perf toppidstat -t- 是否空转唤醒
- 锁竞争
- 系统调用频率
15. 一页总结
调试、测试和监测最值得记住的是:
- 先明确现象,再选工具
- fd 上限是高并发服务的基础配置
- gdb 调多进程/多线程时先确认跟踪对象
- 压测要看尾延迟和错误率,不只看平均 QPS
tcpdump看网络真相,strace看系统调用真相ss看连接状态和队列,vmstat/mpstat/ifstat看系统资源- 调参必须有证据和压测闭环
如果只记一句:
高性能服务端排障不是凭感觉调参数,而是用工具把应用、系统调用、内核和网络链路逐层照亮。
16. 参考资料
tcpdump manual
https://www.tcpdump.org/manpages/tcpdump.1.htmlLinux man-pages: strace
https://man7.org/linux/man-pages/man1/strace.1.htmlLinux man-pages: proc sys fs
https://man7.org/linux/man-pages/man5/proc_sys_fs.5.htmlLinux man-pages: proc sys net
https://man7.org/linux/man-pages/man5/proc_sys_net.5.html