
我目前在嘗試使用 Apache 充當應用程式前端和後端 API 的反向代理時遇到問題。
例如,如果使用者點擊 URL,https://my.app.com/
他們應該被帶到我們由 S3 提供的前端應用程式。如果您點擊該 URL,https://my.app.com/api/hello
您將收到來自我們後端 API 的 JSON 回應。
理想的行為是https://my.app.com/
反向代理到http://s3app.private
。
同樣,我們希望https://my.app.com/api/hello
反向代理到http://myapi.private/api/hello
我們目前的 apache 配置如下所示:
Listen 443
<VirtualHost *:443>
ServerName my.app.com
ErrorDocument 404 /index.html
ProxyErrorOverride On
RequestHeader set X-Forwarded-Proto https
SSLEngine on
SSLCertificateFile "/usr/local/apache2/certs/certificate.crt"
SSLCertificateKeyFile "/usr/local/apache2/certs/private.key"
SSLProtocol TLSv1.2
ProxyAddHeaders On
<Location "/">
ProxyPass "http://s3app.private/" retry=0
</Location>
<Location "/api">
ProxyPreserveHost On
ProxyPass "http://myapi.private/api" retry=0
</Location>
</VirtualHost>
目前的行為是,當我們點擊時,https://my.app.com/
我們會看到我們的前端應用程式。然而,當我們點擊時,我們從伺服器https://my.app.com/api/hello
收到一個錯誤。503
Apache 的日誌顯示以下幾行:
[proxy:error] The timeout specified has expired: AH00957: HTTP: attempt to connect to <internal_ip>:80 (api.private) failed
[proxy_http:error] AH01114: HTTP: failed to make connection to backend: myapi.private, referer: https://my.app.com/
"GET /api/hello HTTP/1.1" 503 299
我們已經透過將 Apache 單獨指向 API 來驗證我們的 API 確實正在透過此機制進行偵聽,如下所示:
Listen 443
<VirtualHost *:443>
ServerName my.app.com
ErrorDocument 404 /index.html
ProxyErrorOverride On
RequestHeader set X-Forwarded-Proto https
SSLEngine on
SSLCertificateFile "/usr/local/apache2/certs/certificate.crt"
SSLCertificateKeyFile "/usr/local/apache2/certs/private.key"
SSLProtocol TLSv1.2
ProxyAddHeaders On
<Location "/api">
ProxyPreserveHost On
ProxyPass "http://myapi.private/api" retry=0
</Location>
</VirtualHost>
這樣做可以讓我們點擊https://my.app.com/api/hello
並查看預期的 JSON 回應。但這僅在不存在其他位置區塊時才成功。
就其價值而言,我們的內部 DNS 由 Route53 提供,我們的 API 託管在 ECS 中。
任何和所有的幫助將不勝感激!
答案1
使用兩個虛擬主機可能會有所幫助,但它可能不是最理想的解決方案。
Listen 443
<VirtualHost *:443>
ServerName my.app.com
ErrorDocument 404 /index.html
ProxyErrorOverride On
RequestHeader set X-Forwarded-Proto https
SSLEngine on
SSLCertificateFile "/usr/local/apache2/certs/certificate.crt"
SSLCertificateKeyFile "/usr/local/apache2/certs/private.key"
SSLProtocol TLSv1.2
ProxyAddHeaders On
<Location "/">
ProxyPass "http://s3app.private/" retry=0
</Location>
<Location "/api">
ProxyPreserveHost On
ProxyPass "http://localhost:8443/api" retry=0
</Location>
</VirtualHost>
Listen 8443
<VirtualHost *:8443>
ServerName localhost
<Location "/api">
ProxyPreserveHost On
ProxyPass "http://myapi.private/api" retry=0
</Location>
</VirtualHost>
我沒有技術原因說明為什麼這可以解決您的問題,但可能值得一試。