Apache ProxyPass-ing 多个位置

Apache ProxyPass-ing 多个位置

我目前在尝试使用 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

我们已经验证了我们的 API 确实正在通过这种机制进行监听,方法是将 Apache 单独指向 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>

我不知道从技术角度上为什么这能解决你的问题,但也许值得一试。

相关内容