应用故障排查
核心知识点
1. 应用故障类型
1.1 应用启动故障
┌─────────────────────────────────────────────────────┐
│ 应用启动故障 │
├─────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ 配置错误 │ │
│ │ - 配置文件错误 │ │
│ │ - 环境变量错误 │ │
│ │ - 依赖项缺失 │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────┐ │
│ │ 权限问题 │ │
│ │ - 文件权限不足 │ │
│ │ - 端口权限不足 │ │
│ │ - 用户权限不足 │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────┐ │
│ │ 资源不足 │ │
│ │ - 内存不足 │ │
│ │ - 磁盘空间不足 │ │
│ │ - 端口被占用 │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────┐ │
│ │ 依赖问题 │ │
│ │ - 库文件缺失 │ │
│ │ - 服务依赖未启动 │ │
│ │ - 版本不兼容 │ │
│ └─────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────┘1.2 应用运行时故障
| 故障类型 | 表现 | 常见原因 |
|---|---|---|
| 应用崩溃 | 进程退出 | 代码错误、异常未处理 |
| 响应慢 | 请求超时 | 性能瓶颈、资源不足 |
| 内存泄漏 | 内存持续增长 | 资源未释放、循环引用 |
| CPU 爆满 | CPU 使用率高 | 死循环、计算密集 |
| 死锁 | 应用无响应 | 资源竞争、锁等待 |
2. 应用监控工具
2.1 进程监控
# ps - 查看进程
ps aux
ps -ef
ps aux --sort=-%cpu
ps aux --sort=-%mem
# top - 实时监控
top
htop
# pstree - 进程树
pstree
pstree -p
# pgrep - 查找进程
pgrep -f <app-name>
pgrep -l <app-name>2.2 资源监控
# 监控进程资源
pidstat -p <pid> 1
pidstat -d -p <pid> 1
pidstat -r -p <pid> 1
# 查看进程内存
pmap -x <pid>
cat /proc/<pid>/status
cat /proc/<pid>/maps
# 查看进程文件描述符
ls -la /proc/<pid>/fd
lsof -p <pid>2.3 日志监控
# 查看应用日志
tail -f /var/log/app.log
tail -n 100 /var/log/app.log
# 查看系统日志
journalctl -u <service>
journalctl -f -u <service>
# 查看错误日志
grep -i error /var/log/app.log
grep -i error /var/log/syslog3. 应用启动故障排查
3.1 配置错误排查
# 1. 检查配置文件
cat /etc/app/config.conf
cat /var/www/app/.env
# 2. 验证配置语法
app --config-check
nginx -t
apache2ctl configtest
# 3. 检查环境变量
env | grep APP_
printenv | grep APP_
# 4. 检查配置差异
diff /etc/app/config.conf /etc/app/config.conf.bak
# 5. 恢复配置
cp /etc/app/config.conf.bak /etc/app/config.conf
# 6. 重启应用
systemctl restart app3.2 权限问题排查
# 1. 检查文件权限
ls -la /var/www/app
ls -la /etc/app
# 2. 检查用户权限
whoami
id
# 3. 修改文件权限
sudo chown -R www-data:www-data /var/www/app
sudo chmod -R 755 /var/www/app
# 4. 检查端口权限
sudo netstat -tlnp | grep <port>
sudo ss -tlnp | grep <port>
# 5. 检查 SELinux
getenforce
sestatus
# 6. 临时禁用 SELinux
sudo setenforce 03.3 资源不足排查
# 1. 检查内存使用
free -h
ps aux --sort=-%mem | head -20
# 2. 检查磁盘空间
df -h
du -sh /var/www/app
# 3. 检查端口占用
sudo netstat -tlnp | grep <port>
sudo ss -tlnp | grep <port>
# 4. 检查文件描述符
ulimit -n
cat /proc/<pid>/limits | grep "open files"
# 5. 增加资源限制
ulimit -n 65535
echo "* soft nofile 65535" >> /etc/security/limits.conf
# 6. 释放资源
sudo rm -rf /tmp/*
sudo journalctl --vacuum-time=7d3.4 依赖问题排查
# 1. 检查库文件
ldd /usr/bin/app
ldd /usr/lib/libapp.so
# 2. 检查服务依赖
systemctl list-dependencies app
systemctl list-dependencies --reverse app
# 3. 检查包依赖
dpkg -I app.deb
rpm -qR app
# 4. 安装缺失依赖
sudo apt-get install -f
sudo yum install <dependency>
# 5. 检查版本兼容性
app --version
dpkg -l | grep app
# 6. 更新应用
sudo apt-get update
sudo apt-get upgrade app4. 应用运行时故障排查
4.1 应用崩溃排查
# 1. 查看崩溃日志
tail -f /var/log/app.log
journalctl -u app -n 100
# 2. 查看系统日志
dmesg | grep -i app
cat /var/log/syslog | grep -i app
# 3. 查看核心转储
ls /var/crash/
ls /var/lib/systemd/coredump/
# 4. 分析核心转储
gdb /usr/bin/app /var/crash/core.<pid>
bt
# 5. 启用核心转储
echo "/tmp/core.%e.%p.%h.%t" > /proc/sys/kernel/core_pattern
ulimit -c unlimited
# 6. 调试应用
gdb /usr/bin/app
run
bt4.2 响应慢排查
# 1. 监控进程资源
pidstat -p <pid> 1
top -p <pid>
# 2. 查看进程线程
ps -eLf | grep <pid>
top -H -p <pid>
# 3. 分析系统调用
strace -p <pid>
strace -c -p <pid>
# 4. 分析性能瓶颈
perf top -p <pid>
perf record -g -p <pid>
perf report
# 5. 查看网络连接
netstat -anp | grep <pid>
ss -anp | grep <pid>
# 6. 优化应用
# - 优化代码
# - 增加缓存
# - 调整配置4.3 内存泄漏排查
# 1. 监控内存使用
watch -n 1 "cat /proc/<pid>/status | grep -i mem"
pidstat -r -p <pid> 1
# 2. 查看进程内存
pmap -x <pid>
cat /proc/<pid>/maps
# 3. 使用 valgrind 检测
valgrind --leak-check=full --show-leak-kinds=all ./myapp
# 4. 使用 address sanitizer
gcc -fsanitize=address -g myapp.c -o myapp
./myapp
# 5. 分析堆转储
jmap -dump:format=b,file=heap.bin <pid>
jhat heap.bin
# 6. 修复内存泄漏
# - 检查未释放的内存
# - 检查循环引用
# - 使用智能指针4.4 CPU 爆满排查
# 1. 查看 CPU 使用
top -p <pid>
htop
# 2. 查看线程
ps -eLf | grep <pid>
top -H -p <pid>
# 3. 分析进程
strace -p <pid>
perf top -p <pid>
# 4. 查看调用栈
pstack <pid>
cat /proc/<pid>/stack
# 5. 分析代码
# - 查看热点函数
# - 查看死循环
# - 查看性能瓶颈
# 6. 优化代码
# - 优化算法
# - 减少计算
# - 使用缓存4.5 死锁排查
# 1. 查看进程状态
ps aux | grep <pid>
cat /proc/<pid>/status
# 2. 查看线程状态
ps -eLf | grep <pid>
cat /proc/<pid>/task/*/status
# 3. 查看调用栈
cat /proc/<pid>/stack
cat /proc/<pid>/task/*/stack
# 4. 查看锁信息
# - 使用调试工具
# - 查看日志
# - 分析代码
# 5. 使用 gdb 调试
gdb -p <pid>
thread apply all bt
# 6. 解决死锁
# - 优化锁粒度
# - 使用读写锁
# - 避免嵌套锁5. 应用日志分析
5.1 日志收集
# 1. 查看应用日志
tail -f /var/log/app.log
tail -n 100 /var/log/app.log
# 2. 查看系统日志
journalctl -u app
journalctl -f -u app
# 3. 查看错误日志
grep -i error /var/log/app.log
grep -i error /var/log/syslog
# 4. 查看访问日志
tail -f /var/log/nginx/access.log
tail -f /var/log/apache2/access.log
# 5. 导出日志
cp /var/log/app.log /tmp/app.log
tar -czf app-logs.tar.gz /var/log/app.log*5.2 日志分析
# 1. 统计错误数量
grep -i error /var/log/app.log | wc -l
# 2. 查看最新错误
grep -i error /var/log/app.log | tail -20
# 3. 按时间过滤
grep "2024-01-01 10:" /var/log/app.log
# 4. 按关键词过滤
grep "keyword" /var/log/app.log
# 5. 统计访问量
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr
# 6. 分析响应时间
awk '{print $NF}' /var/log/nginx/access.log | sort -n | tail -105.3 日志可视化
# 1. 使用 ELK Stack
# - 安装 Elasticsearch
# - 安装 Logstash
# - 安装 Kibana
# 2. 配置 Logstash
cat > /etc/logstash/conf.d/app.conf << 'EOF'
input {
file {
path => "/var/log/app.log"
start_position => "beginning"
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "app-logs"
}
}
EOF
# 3. 启动服务
systemctl start logstash
systemctl start elasticsearch
systemctl start kibana
# 4. 访问 Kibana
# http://localhost:5601实用案例分析
案例 1:Web 应用无法启动
场景描述
Nginx Web 应用无法启动。
排查步骤
# 1. 检查服务状态
systemctl status nginx
# 2. 查看服务日志
journalctl -u nginx -n 100
tail -f /var/log/nginx/error.log
# 3. 验证配置文件
nginx -t
# 4. 检查端口占用
sudo netstat -tlnp | grep :80
sudo ss -tlnp | grep :80
# 5. 检查文件权限
ls -la /var/www/html
ls -la /etc/nginx
# 6. 修复配置
sudo nano /etc/nginx/nginx.conf
# 7. 重启服务
sudo systemctl restart nginx
# 8. 验证效果
curl http://localhost/案例 2:数据库应用响应慢
场景描述
MySQL 数据库查询响应慢。
排查步骤
# 1. 检查数据库状态
systemctl status mysql
mysqladmin -u root -p status
# 2. 查看慢查询
mysql -u root -p -e "SHOW VARIABLES LIKE 'slow_query_log';"
tail -f /var/log/mysql/slow.log
# 3. 分析查询计划
mysql -u root -p -e "EXPLAIN SELECT * FROM users WHERE id = 1;"
# 4. 添加索引
mysql -u root -p -e "CREATE INDEX idx_id ON users(id);"
# 5. 优化查询
mysql -u root -p -e "SELECT id, name FROM users WHERE id = 1;"
# 6. 调整缓冲池
mysql -u root -p -e "SET GLOBAL innodb_buffer_pool_size = 2G;"
# 7. 验证效果
mysql -u root -p -e "SHOW STATUS LIKE 'Slow_queries';"案例 3:Java 应用内存泄漏
场景描述
Java 应用内存持续增长。
排查步骤
# 1. 监控内存使用
jstat -gc <pid>
jmap -heap <pid>
# 2. 分析堆转储
jmap -dump:format=b,file=heap.bin <pid>
jhat heap.bin
# 3. 使用 MAT 分析
# - 下载 MAT
# - 打开 heap.bin
# - 分析内存泄漏
# 4. 优化 JVM 参数
java -Xms512m -Xmx1024m -XX:+UseG1GC -jar myapp.jar
# 5. 检查代码
# - 检查未释放的对象
# - 检查循环引用
# - 检查缓存使用
# 6. 验证效果
jstat -gc <pid>最佳实践
完善日志记录:记录关键操作和错误信息。
配置监控告警:及时发现应用问题。
定期备份配置:便于快速恢复。
使用版本控制:管理应用配置和代码。
建立文档:记录问题和解决方案。
定期测试:验证应用功能。
性能优化:持续优化应用性能。
安全加固:保护应用安全。
总结
本教程详细介绍了 Linux 系统应用故障的排查方法和实践。通过实际案例,我们学习了如何排查应用启动故障和运行时故障,以及如何使用监控工具和日志分析工具。掌握这些知识后,可以快速定位和解决应用级问题。