Skip to content

Nuface Blog

隨意隨手記 Casual Notes

Menu
  • Home
  • About
  • Services
  • Blog
  • Contact
  • Privacy Policy
  • Login
Menu

在 AWS 上用 Apache 2.4 做反向代理:502 問題排查與實戰調校(含 vhost 分檔與 rotatelogs)

Posted on 2025-11-052025-11-05 by Rico

本文整理自一段真實排查經驗,所有公司與網域資訊已去識別化。
範例網域以 demodomain.com 表示,例如 wmsadmin.demodomain.com。


架構概述

  • server-a:AWS 上的 Apache 2.4(HTTPS 入口、反向代理)
  • server-b:同一子網內的應用(WMS / API 後端)
  • 需求:把外部對特定網域(例如 wmsadmin.demodomain.com)的 API 請求由 server-a 轉送至 server-b

典型 vhost(簡化示意):

<VirtualHost *:443>
    ServerName wmsadmin.demodomain.com

    ProxyPreserveHost On
    ProxyRequests Off

    # 轉送到內部後端
    ProxyPass        / http://10.0.10.20:16890/ connectiontimeout=5 timeout=120 keepalive=On retry=0
    ProxyPassReverse / http://10.0.10.20:16890/

    RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
    RequestHeader set X-Forwarded-SSL   expr=%{HTTPS}
    RequestHeader set X-Forwarded-For   "%{REMOTE_ADDR}s"

    # 某些後端不吃 chunked,上傳時轉為 Content-Length 比較穩
    SetEnv proxy-sendcl 1

    # SSL 憑證略
</VirtualHost>

問題現象

  • 偶發 502 Bad Gateway / Proxy Error
  • 後來確認根因是:外部大量上傳(大檔/大批量訂單)導致後端處理時間超過預設 timeout
  • 調整 Proxy timeout 後問題消失

排查思路(速查)

  1. 對時:鎖定 502 發生秒級時間,交叉比對 server-a(Apache)與 server-b(後端) log
  2. 直接從 server-a 測後端(排除網路/防火牆): curl -v --max-time 180 http://10.0.10.20:16890/health
  3. 開啟(僅排查時)代理偵錯: LogLevel proxy:debug proxy_http:trace5 看 error log 是否有 timeout、AH01102(讀取狀態行失敗)、Connection reset by peer 等關鍵訊息
    ➜ 排查完務必改回: LogLevel warn
  4. 確認 Docker/網路(若後端在容器內):容器 IP 是否固定?建議用自訂網路與服務名連線,避免容器重啟換 IP。

針對長耗時路徑「差異化」放寬 timeout

不要全站一刀切放到很長,避免把 worker 綁死;只對特定 URI 提高 timeout:

# 一般 API:保持較短
ProxyPass        /api/ http://10.0.10.20:16890/api/ connectiontimeout=5 timeout=60 keepalive=On
ProxyPassReverse /api/ http://10.0.10.20:16890/api/

# 大量上傳/批處理:提高 timeout(例如 10 分鐘)
ProxyPass        /orders/upload http://10.0.10.20:16890/orders/upload connectiontimeout=5 timeout=600 keepalive=On
ProxyPassReverse /orders/upload http://10.0.10.20:16890/orders/upload

若有啟用 mod_reqtimeout,避免慢速上傳被切斷:

RequestReadTimeout header=60-120,MinRate=0 body=120,MinRate=0
# 某些 client 的 Expect: 100-continue 會卡,必要時可拿掉:
# RequestHeader unset Expect early

如何判讀「滿版的 trace 訊息」?

看到像這樣的行:

[proxy_http:trace4] mod_proxy_http.c(...) Access-Control-Allow-Methods: *
[proxy_http:trace3] start body send

代表只是 偵錯等級很高時,Apache 把上游回應 header 與傳輸流程寫進 error log。
不是錯誤。要看真正異常,請降回 LogLevel warn,或在 access log 先找 502 再對照 error log 該時段的 warn/error 級別訊息。


vhost 各自分檔記錄(擺脫 other_vhosts_access.log)

在每個 vhost 內指定 ErrorLog/CustomLog,最簡單:

<VirtualHost *:443>
    ServerName wmsadmin.demodomain.com

    ErrorLog  ${APACHE_LOG_DIR}/wmsadmin-ssl-error.log
    CustomLog ${APACHE_LOG_DIR}/wmsadmin-ssl-access.log combined
    ...
</VirtualHost>

如不想再用全域 other_vhosts_access.log,可停用:

a2disconf other-vhosts-access-log
apache2ctl graceful

(注意:停用後,沒自訂 CustomLog 的 vhost 將不再被記錄。)


沒有 logrotate?用 Apache 內建 rotatelogs 最省事

不需要再跑 cron/logrotate,只要把 log 管線到 rotatelogs。
不同映像路徑不一樣,常見在:

  • 官方 httpd:2.4:/usr/local/apache2/bin/rotatelogs
  • Debian/Ubuntu 套件:/usr/sbin/rotatelogs(屬於 apache2-utils)

查路徑:

command -v rotatelogs || find / -type f -name rotatelogs 2>/dev/null

設定範例(每日一檔+保留「當前檔」的 symlink):

ErrorLog  "|/usr/local/apache2/bin/rotatelogs -l -f -L /var/log/apache2/wmsadmin-error.log  /var/log/apache2/wmsadmin-error-%Y%m%d.log 86400"
CustomLog "|/usr/local/apache2/bin/rotatelogs -l -f -L /var/log/apache2/wmsadmin-access.log /var/log/apache2/wmsadmin-access-%Y%m%d.log 86400" combined

想改成「依大小輪替」:把最後的 86400 改成 10M 等。


讓 access log 更有用:記錄 I/O 與耗時

加一個 combined_io 格式,把請求/回應位元組與處理時間寫進去,方便事後定位「大檔或耗時」:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O %D" combined_io
CustomLog ${APACHE_LOG_DIR}/wmsadmin-access.log combined_io
  • %I / %O:request / response 位元組數
  • %D:處理耗時(微秒)

查大於 60 秒的請求(例):

awk '$NF>60000000' /var/log/apache2/wmsadmin-access.log

常見細節與最佳實務

  • ProxyPreserveHost On:不少後端依 Host 路由/產 URL,建議開啟
  • SetEnv proxy-sendcl 1:把 chunked 上傳改成帶 Content-Length,相容性更好
  • retry=0:避免 Apache 判定後端暫時壞掉而長時間不嘗試
  • keepalive=On:減少連線建立成本
  • 資源與併發:監看 MaxRequestWorkers、CPU/RAM、ulimit -n;高峰期才 502 的,多半是併發/連線池不足
  • CORS/RateLimit header:常見於上游回應,與 Apache 502 無直接關係;但請評估是否過度寬鬆(安全面)

驗證與監控

  • curl 模擬長請求: curl -v --max-time 900 -F "file=@big_orders.csv" https://wmsadmin.demodomain.com/orders/upload
  • mod_status(快速看 Busy/Idle worker)
  • 日誌告警:以 %D(耗時)或 5xx 比例作為告警門檻
  • 從流程面優化:長任務改 非同步(202 Accepted + 狀態輪詢/SSE/WebSocket),proxy timeout 就能回到合理值

最終小抄(Checklist)

  • 只為「長耗時路徑」提高 ProxyPass ... timeout=...
  • ProxyPreserveHost On、SetEnv proxy-sendcl 1
  • RequestReadTimeout 放寬(若有啟用)
  • vhost 各自 ErrorLog/CustomLog,配合 rotatelogs 分檔
  • combined_io 記錄 %I/%O/%D
  • 排查時才開 LogLevel proxy:debug proxy_http:trace5,完畢恢復 warn
  • 直接從 server-a 用 curl -v 測後端
  • 觀察 worker/資源、後端連線池與 DB/GC 等瓶頸
  • 考慮把巨量上傳/批量處理改為非同步

如果你使用的映像沒有 rotatelogs,用套件管理器安裝 apache2-utils(Debian/Ubuntu/Alpine 名稱相同)或改寫成正確路徑即可。

Recent Posts

  • Postfix + Let’s Encrypt + BIND9 + DANE Fully Automated TLSA Update Guide
  • Postfix + Let’s Encrypt + BIND9 + DANE TLSA 指紋自動更新完整教學
  • Deploying DANE in Postfix
  • 如何在 Postfix 中部署 DANE
  • DANE: DNSSEC-Based TLS Protection

Recent Comments

  1. Building a Complete Enterprise-Grade Mail System (Overview) - Nuface Blog on High Availability Architecture, Failover, GeoDNS, Monitoring, and Email Abuse Automation (SOAR)
  2. Building a Complete Enterprise-Grade Mail System (Overview) - Nuface Blog on MariaDB + PostfixAdmin: The Core of Virtual Domain & Mailbox Management
  3. Building a Complete Enterprise-Grade Mail System (Overview) - Nuface Blog on Daily Operations, Monitoring, and Performance Tuning for an Enterprise Mail System
  4. Building a Complete Enterprise-Grade Mail System (Overview) - Nuface Blog on Final Chapter: Complete Troubleshooting Guide & Frequently Asked Questions (FAQ)
  5. Building a Complete Enterprise-Grade Mail System (Overview) - Nuface Blog on Network Architecture, DNS Configuration, TLS Design, and Postfix/Dovecot SNI Explained

Archives

  • December 2025
  • November 2025
  • October 2025

Categories

  • AI
  • Apache
  • Cybersecurity
  • Database
  • DNS
  • Docker
  • Fail2Ban
  • FileSystem
  • Firewall
  • Linux
  • LLM
  • Mail
  • N8N
  • OpenLdap
  • OPNsense
  • PHP
  • QoS
  • Samba
  • Switch
  • Virtualization
  • VPN
  • WordPress
© 2025 Nuface Blog | Powered by Superbs Personal Blog theme