Apache:Apache日常运维
发布时间:2026-04-22 17:01
一、前言
搞过的人都知道,Apache跑久了最烦的是:时不时502、不明不白的高负载、日志塞满磁盘、配置改完没生效还不知道咋回事。本章讲的是日常巡检和故障排查的实战套路,不废话,直接上命令。
二、操作步骤
第1步:快速判断Apache还活着没
# CentOS/RHEL 检查进程和端口
$ ps aux | grep httpd | head -5
www-data 1234 0.0 1.2 123456 8900 ? S 10:00 0:01 /usr/sbin/apache2 -k start
www-data 1235 0.0 1.1 123456 8700 ? S 10:00 0:00 /usr/sbin/apache2 -k start
$ netstat -tlnp | grep :80
tcp6 0 0 :::80 :::* LISTEN 1234/apache2
# Ubuntu 检查进程和端口
$ ps aux | grep apache2 | head -5
www-data 2345 0.0 1.2 123456 8900 ? S 10:00 0:01 /usr/sbin/apache2 -k start
$ ss -tlnp | grep :80
LISTEN 0 128 *:80 *:* users:(("apache2",pid=2345,fd=4))
如果进程不在、端口没监听,别犹豫,直接往下走排查流程。
第2步:检查Apache版本和编译参数
$ httpd -v # CentOS/RHEL
Server version: Apache/2.4.6 (CentOS)
Server built: Jul 18 2017 15:41:21
$ apache2 -v # Ubuntu
Server version: Apache/2.4.29 (Ubuntu)
Server built: 2018-10-03 15:39:11
# 看编译时带了哪些模块,关键参数记一下
$ httpd -V # CentOS/RHEL
Server MPM: Prefork
Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP
$ apache2 -V # Ubuntu
Server MPM: Prefork
Server compiled with.... -D APR_HAS_SENDFILE
这步看似没用,但当你需要排错或升级时,版本号和MPM模式是必须记住的。
第3步:查看实时的连接和负载状态
# 实时看有多少连接在跑
$ watch -n 2 "ss -s"
Every 2.0s: ss -s
Total: 156 (kernel 178)
TCP: 234 (estab 12, closed 180, orphaned 0, synrecv 0, timewait 180/0)
# 看Apache当前处理多少请求
$ apache2ctl status # Ubuntu带mod_status
Server uptime: 12345 seconds
Current workers: .rdR .rW....................................
Server load: 0.12
$ /usr/sbin/httpd -M 2>/dev/null | grep status # CentOS找status模块
负载超过CPU核数基本就是出问题了。TIME_WAIT多说明短连接频繁,考虑改keepalive参数。
第4步:日志分析找异常
# 看最近有没有500错误爆了
$ tail -200 /var/log/apache2/error.log | grep -i error # Ubuntu
[Mon Jan 15 10:23:45.123456 2024] [error] [pid 5678] [client 192.168.1.100]
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted
$ tail -200 /var/log/httpd/error_log | grep -i error # CentOS/RHEL
# 统计各类HTTP状态码占比
$ awk '{print $9}' /var/log/apache2/access.log | sort | uniq -c | sort -rn | head -10
12345 200
2345 304
567 404
89 500
45 502
# 找访问量最高的IP,可能是被人刷或者被爬虫搞了
$ awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -rn | head -10
5678 203.0.113.45
1234 192.168.1.100
890 10.0.0.5
502/503突然增多先看后端PHP-FPM还活着没,别上来就重启Apache。
第5步:检查配置文件语法和生效状态
# 配置改完后先测试语法,别直接reload
$ apache2ctl configtest # Ubuntu
Syntax OK
$ httpd -t # CentOS/RHEL
Syntax OK
# 看当前加载了哪些配置,理解Include顺序
$ apache2ctl -S # Ubuntu
VirtualHost configuration:
*:80 is a NameVirtualHost
default server www.example.com (/etc/apache2/sites-enabled/000-default.conf:1)
port 80 namevhost www.example.com (/etc/apache2/sites-enabled/000-default.conf:1)
$ httpd -S # CentOS/RHEL
VirtualHost configuration:
*:80 is a NameVirtualHost
default server www.example.com (/etc/apache2/conf.d/vhost.conf:1)
Include顺序搞反了,认证先过、rewriterule不生效这类玄学问题就会出现。
第6步:磁盘空间和日志轮转
# 先看Apache写了多少东西到磁盘
$ df -h /var/log/apache2/
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 45G 5.5G 90% /var/log/apache2
# 看哪些日志文件最大
$ du -sh /var/log/apache2/* 2>/dev/null | sort -rh | head -10
5.2G /var/log/apache2/access.log
1.8G /var/log/apache2/error.log
234M /var/log/apache2/other_vhost_access.log
# 手动触发一次日志轮转,别等它自己爆
$ logrotate -f /etc/logrotate.d/apache2 # Ubuntu
$ logrotate -f /etc/logrotate.d/httpd # CentOS/RHEL
磁盘90%是红线,Apache写入会失败但进程还活着,502就这么来的。
第7步:优雅重启和强制重启
# 改了配置先测试再平滑重启,不影响现有连接
$ apache2ctl graceful # Ubuntu
$ httpd -k graceful # CentOS/RHEL
# 正在处理的请求会等它完成,新请求走新配置
# 等半天没反应,强制杀掉再启动
$ apache2ctl stop && sleep 2 && apache2ctl start # Ubuntu
$ systemctl restart httpd # CentOS/RHEL
# 如果进程僵死,用kill杀
$ ps aux | grep apache2
www-data 5678 0.0 0.0 0 0 ? Z 10:00 0:00 [apache2]
$ kill -9 5678
$ apache2ctl start
频繁重启会爆premature end of headers错误,日志文件权限也会乱,动手前三思。
三、常见问题FAQ
Q1:Apache突然不处理请求了,但进程还在,端口也监听正常,怎么排查?
这种情况基本是worker卡死或者被打满。先看状态:apachectl status,如果全是._RW_这种状态说明worker全在等待后端。再看错误日志有没有PHP-FPM或数据库超时。如果请求堆积严重,netstat -an | grep :80 | wc -l看连接数是不是过万。基本上是后端服务挂导致的,Apache本身不会自己死。
Q2:改了httpd.conf或者vhost配置,reload后新配置不生效怎么办?
先跑apache2ctl -S看Include了哪些文件,确认文件路径没写错。有时候改的是主配置但虚拟主机覆写了设置。如果确认配置正确但还是不行,用apachectl stop && sleep 3 && apachectl start完整重启,别用reload有时候缓存不刷。Ubuntu有个坑是sites-enabled里的软链接被删了但sites-available还在,改了半天才发现根本没生效。
Q3:如何防止日志把磁盘撑爆?生产环境日志到底该不该开?
access_log开不开看需求,静态站可以关掉,动态站建议只记录关键字段。不要用combined格式记录referer和user-agent,高并发下IO是瓶颈。错误日志error_reporting关闭E_ALL,只开E_WARNING以上级别。logrotate配置里加个daily size限制,超过100M就强制轮转,别让单个日志文件跑到几十个G。
Q4:系统负载高,但CPU使用率Apache进程占比不高,是谁在抢资源?
先top按CPU排序,如果apache进程不靠前,说明瓶颈不在Apache。常见原因是:PHP-FPM进程占用高、IO等待(磁盘慢)、内存不足导致swap频繁。看每个Apache进程占用内存,prefork模式下一个进程大概吃20-50MB,如果内存不够系统会疯狂swap,这时候Apache反而闲着。用iostat -x 1 5看磁盘IO有没有打满。
Q5:服务器只跑Apache,为啥开了80端口还被扫?需要额外加防火墙吗?
Apache本身不防扫描,它只管处理请求。如果不想被扫,可以在Apache层加黑白名单:用mod_evasive限流,或者在httpd.conf里加SetEnvIf根据IP做访问控制。但更靠谱的是在服务器前端加防火墙或者云安全组,只放行必要端口。生产环境别裸奔,iptables把非80/443的入站全drop,别让SSH直接暴露在公网。
四、总结
Apache日常运维的核心就三句话:进程活着不等于服务正常、99%的问题先看日志、配置改完必须测试语法再reload。别犯懒,每次改配置前-t检测,reload后立刻看error_log有没有报错。日志轮转必须配好,磁盘空间报警比服务挂了还难处理。
延伸阅读:
- Apache MPM选择指南:prefork与event对比,根据业务场景选
- mod_status详解:用好server-status监控实时状态
- 日志分析工具:awstats和goaccess,自动生成报表
- 安全加固:mod_security和mod_evasive的实战配置