1. 診斷內存占用根源
首先確認Apache是否為內存占用高的主因,使用top -p $(pgrep apache2 | paste -s -d,)
(Ubuntu/Debian)或top -p $(pgrep httpd | paste -s -d,)
(CentOS/RHEL)查看Apache進程的**RES(常駐內存)**列,判斷單個進程內存消耗;通過ps aux | grep apache | grep -v grep | wc -l
統計活躍進程數量,若進程數過多(如數百個),則需調整進程管理配置。同時,使用apache2ctl -V | grep 'MPM'
(Ubuntu/Debian)或httpd -V | grep 'MPM'
(CentOS/RHEL)確認當前MPM(多處理模塊),Prefork模式(每請求一個進程)內存占用遠高于Event/Worker模式(多線程),需優先考慮切換。
2. 切換至低內存MPM模式
若當前使用Prefork MPM(常見于傳統PHP環境),建議升級至Event或Worker模式(需確保PHP使用PHP-FPM而非mod_php)。修改配置文件(路徑取決于發行版,如Ubuntu的/etc/apache2/mods-enabled/mpm_event.conf
、CentOS的/etc/httpd/conf.d/mpm_event.conf
),調整Event MPM參數(以1GB內存為例):
<IfModule mpm_event_module>
StartServers 3 # 啟動時的子進程數
MinSpareThreads 25 # 最小空閑線程數
MaxSpareThreads 75 # 最大空閑線程數
ThreadLimit 64 # 線程數上限
ThreadsPerChild 25 # 每個子進程創建的線程數
MaxRequestWorkers 150 # 最大并發請求數(關鍵參數,需根據內存計算)
MaxConnectionsPerChild 5000 # 每個子進程處理的請求數(防內存泄漏)
</IfModule>
Event模式通過異步處理提升并發能力,內存占用較Prefork降低50%-80%。
3. 調整Apache核心配置參數
根據服務器內存計算MaxRequestWorkers
(關鍵參數):
MaxRequestWorkers = (總內存 - 系統及其他應用占用) / 單個Apache進程平均內存
(如1GB內存,系統占用200MB,單個進程平均20MB,則MaxRequestWorkers = (1024-200)/20 ≈ 41
)。MaxConnectionsPerChild
(如5000),避免單個進程長期運行導致內存泄漏(尤其適用于PHP應用)。KeepAlive On
(啟用持久連接)、KeepAliveTimeout 5
(超時時間,減少TCP握手開銷)、MaxKeepAliveRequests 100
(每個連接最大請求數,避免單個連接占用過久)。4. 禁用不必要的Apache模塊
通過apachectl -M
(Ubuntu/Debian)或httpd -M
(CentOS/RHEL)列出已加載模塊,禁用未使用的模塊(如mod_info
、mod_status
(若無需狀態頁)、mod_autoindex
(若無需目錄列表)、mod_negotiation
(若無需內容協商))。使用a2dismod 模塊名
(Ubuntu/Debian)或注釋配置文件中的LoadModule
行(CentOS/RHEL)禁用模塊,減少內存開銷。
5. 啟用緩存機制降低動態內容開銷
mod_cache
和mod_cache_disk
,配置緩存目錄(如/var/cache/apache2
),將靜態文件(HTML、CSS、JS、圖片)緩存到磁盤,減少重復讀取開銷。示例配置:LoadModule cache_module modules/mod_cache.so
LoadModule cache_disk_module modules/mod_cache_disk.so
CacheEnable disk / # 緩存根目錄
CacheRoot /var/cache/apache2
CacheDirLevels 2 # 緩存目錄層級
CacheDirLength 1 # 目錄名長度
mod_expires
設置靜態資源過期時間(如CSS/JS/圖片緩存1周),減少客戶端重復請求;或通過反向代理(如Nginx)緩存動態內容,降低Apache負載。6. 優化PHP處理(若使用PHP)
mod_php
(模塊方式),通過mod_proxy_fcgi
將PHP請求轉發給PHP-FPM處理,減少Apache內存占用。配置示例(Ubuntu/Debian):<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
</FilesMatch>
php.ini
中的memory_limit
(如128M
),避免單個PHP腳本占用過多內存;啟用opcache.enable=1
(OPcache),緩存編譯后的PHP腳本,減少重復解析開銷。7. 監控與持續優化
htop
(可視化進程監控)、apachetop
(Apache請求監控)、sar -r 1 5
(系統內存趨勢)等工具,定期檢查內存使用情況。mod_status
(路徑如/server-status
),通過ExtendedStatus On
查看實時請求狀態,排查慢請求或異常流量(如DDoS攻擊)。systemctl restart apache2
),釋放內存。8. 系統級優化(輔助手段)
sync && echo 1 | sudo tee /proc/sys/vm/drop_caches
(清理PageCache)、echo 3 | sudo tee /proc/sys/vm/drop_caches
(清理PageCache+目錄項+inodes)。/etc/sysctl.conf
,降低vm.swappiness
(如vm.swappiness=10
,減少交換分區使用)、開啟vm.overcommit_memory=2
(允許內存超發,提高利用率),然后運行sudo sysctl -p
生效。