[英]Apache 2.4 redirection from load-balanced reverse-proxy not working but working in non-load-balanced reverse-proxy
我有 2 個由 Apache 2.4 反向代理的 NextJS 內部服務器/應用程序。 Let's have the 2 internal servers as http://internal:3000/foo
and http://internal:3001/foo
and the external URL as http://external/foo
.
在基路徑(即http://internal:3000/foo
)上訪問 NextJS 時,會重定向到http://internal:3000/foo/bar/baz
on HTTP Code 308
因此,通過反向代理,我預計會發生同樣的情況,重定向將從http://external/foo
到http://external/foo/bar/baz
發生。
next.config.js
中的配置如下
... module.exports = {... async redirects() { return [ { source: '/', destination: '/bar/baz', permanent: true } ] }, basePath: 'foo' }
發生的情況是,當我嘗試反向代理到只有 1 個 NextJS 應用程序而沒有負載平衡時,這種重定向工作得很好,例如,我只反向代理到http://internal:3000/foo
。
我使用的配置如下
<Location "/foo"> ProxyPass "http://localhost:3000/foo" ProxyPassReverse "http://localhost:3000/foo" </Location>
但是,當我嘗試反向代理到 2 NextJS application on load balance 時,重定向不起作用。
我使用的配置如下
<Proxy "balancer://example"> BalancerMember "http://localhost:3000/foo" BalancerMember "http://localhost:3001/foo" </Proxy> <Location "/foo"> ProxyPass "balancer://example" ProxyPassReverse "balancer://example" </Location>
相反,它將繼續從http://external/foo
重定向到http://external/foo
即無限重定向,從而導致TOO_MANY_REDIRECT
。
令我感到困惑的是,重定向在非負載平衡情況下有效,但在使用負載平衡時失敗。 任何想法實際上發生了什么? 是否有響應 header 被寫入我在使用代理負載平衡時不知道? 謝謝
更新/進展(1):
我懷疑在以下部分的mod_proxy_balancer.c
中發生了重寫
access_status = rewrite_url(r, *worker, url); /* Add the session route to request notes if present */ if (route) { apr_table_setn(r->notes, "session-sticky", sticky); apr_table_setn(r->notes, "session-route", route); /* Add session info to env. */ apr_table_setn(r->subprocess_env, "BALANCER_SESSION_STICKY", sticky); apr_table_setn(r->subprocess_env, "BALANCER_SESSION_ROUTE", route); } ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01172) "%s: worker (%s) rewritten to %s", (*balancer)->s->name, (*worker)->s->name, *url); return access_status;
可以在https://github.com/apache/httpd/blob/317108ee6e84ae47bd0f6121e3a64074c5d68c7b/modules/proxy/mod_proxy_balancer.c#L631-L647
中找到
更新/進展(2):
我打開mod_dumpio
來記錄所有進出 apache 的傳入和傳出流量,並確認確實發生了重寫。
重寫發生如下:
GET /foo
,這是發送到外部服務器的原始請求。GET /foo/
,這是發送到內部服務器的請求。 請注意在末尾添加斜線的重寫。Location /foo
,這是內部服務器的重定向響應位置。 這是一個預期的位置,因為在內部服務器中, GET /foo/
將被重定向到Location /foo
而GET /foo
將被重定向到Location /foo/bar/baz
。 在正常情況下,重定向將由內部服務器處理,這意味着GET /foo/
將導致重定向導致GET /foo
,最終產生Location /foo/bar/baz
但這不會發生在反向代理中。Location /foo
,即外部服務器的重定向響應位置。 因為(4)和(1)是同一個URL,所以會產生重定向循環。確認重寫后,現在我正在尋找是否有辦法解決這種行為。
我終於設法解決了這個問題,並且關於上面的第二次更新,我設法找到了“重寫”發生的位置,這幫助我解決了這個問題。
tl;dr
修復基本上是將路徑從BalancerMember
移動到平衡器本身,即
<Proxy "balancer://example/foo"> // used to be "balancer://example" BalancerMember "http://localhost:3000" // used to be "http://localhost:3000/foo" BalancerMember "http://localhost:3001" // used to be "http://localhost:3001/foo" </Proxy> // change to point to the balancer accordingly <Location "/foo"> ProxyPass "balancer://example/foo" ProxyPassReverse "balancer://example/foo" </Location>
至於我的發現,“重寫”並不是重寫,而是實際上是 Apache 在mod_proxy_balancer
或mod_proxy_http
模塊中執行的 URL 規范化(或取決於您的方案)。 mod_proxy_balancer 中的規范化源代碼示例
更改balancer://example -> balancer://example/foo
使其 URL 方案結構與http://localhost:3000/foo
相同,在進行規范化時不會在末尾產生斜杠,這是由balancer://example
在“主機”之后沒有路徑,因此通過上述更改,使用負載均衡器或不使用負載均衡器的反向代理的行為最終將相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.