如何轉發來自我的網路伺服器的請求?
這是一個關於反向代理、它們如何工作以及如何配置的規範問題。
如何為來自不同埠上的服務或來自具有相同網路伺服器的不同伺服器的請求提供服務,並通過 URL 區分它?
如果您想提供來自多個服務或來自同一域的多個伺服器的內容,您可以將您的網路伺服器配置為充當反向代理。服務(通常稱為後端伺服器或應用程序伺服器)不一定需要可從客戶端直接訪問,通常只有實際為客戶端服務的 Web 伺服器可直接訪問。客戶端和伺服器之間以及伺服器和後端之間也可以有不同的方案或協議(http、https、ajp…)。
Client ---[https]---> Server ---[http]---> backend:8080 | |---[direct]---> files from document root `---[http]---> localhost:4000
例子
- https://example.com/ -> 直接從網路伺服器提供
- https://example.com/jenkins/ -> 代理到可以從網路伺服器訪問的不同伺服器
- https://api.example.com/ -> 代理到同一主機上具有不同埠的服務
反向代理可以配置為虛擬目錄或子域。
Apache 的範例配置
您需要載入必要的 apache 模組才能將其用作反向代理。這些至少是:
對於更多協議,您將需要啟用更多模組。
您可以使用基於 Debian/Ubuntu 的發行版啟用模組,如下所示:
sudo a2enmod proxy proxy_http
對於基於 RedHat/CentOS 的發行版,您需要在其中找到正確的配置文件
/etc/httpd/
並手動啟用這些模組。上述範例的配置可能如下所示:
<VirtualHost *:443> ServerName example.com DocumentRoot /var/www/html # SSL options left out for simplicity ProxyRequests Off ProxyPreserveHost On ProxyPass /jenkins/ http://192.168.42.18:8080/ ProxyPassReverse /jenkins/ http://192.168.42.18:8080/ </VirtualHost> <VirtualHost *:443> ServerName api.example.com DocumentRoot /var/www/html # SSL options left out for simplicity ProxyRequests Off ProxyPreserveHost On ProxyPass / http://localhost:4000/ ProxyPassReverse / http://localhost:4000/ </VirtualHost>
nginx 的範例配置
server { listen 443; server_name example.com; root /var/www/html; # SSL options left out for simplicity location /jenkins/ { proxy_pass http://192.168.42.18:8080/; } } server { listen 443; server_name api.example.com; # SSL options left out for simplicity location / { proxy_pass http://localhost:4000/; } }
後端配置
要記住的一件事是後端伺服器應該進行相應的配置。例如,如果 Jenkins 被配置為使用 URL 服務請求
http://192.168.42.18:8080/
,它將使用此基本 URL 作為 CSS、JS 和圖像文件的路徑,從而導致大量 404 錯誤或超時以及伺服器無法工作。必須將代理 URL配置https://example.com/jenkins/
為基本 URL 才能使其工作。其他後端需要類似的配置。這是解決 URL 指向後端伺服器而不是前端伺服器的問題的首選方法。如果由於某種原因無法更改後端伺服器的配置,您可以配置前端伺服器以在將 HTML 提供給客戶端之前重寫 HTML。
但是,這應該被視為最後的手段,因為它給前端伺服器增加了不必要的負載。
阿帕奇
使用 Apache,您可以使用該模組
mod_proxy_html
。該模組提供了指令ProxyHTMLURLMap
,您可以使用它來重寫響應。ProxyPass /jenkins/ http://192.168.42.18:8080/ ProxyPassReverse /jenkins/ http://192.168.42.18:8080/ SetOutputFilter proxy-html # make sure the output is filtered by proxy-html ProxyHTMLURLMap http://192.168.42.18:8080/ https://example.com/jenkins/ ProxyHTMLExtended On # by default only HTML output is filtered
這應該使用 publichostname URL 重寫答案中所有出現的 localserver URL。
nginx
使用 nginx 可以使用ngx_http_sub_module實現類似的結果:
location /jenkins/ { proxy_pass http://192.168.42.18:8080/; sub_filter '<a href="http://192.168.42.18:8080/' '<a href="https://$host/jenkins/'; sub_filter_once on; }