簡體   English   中英

Apache 2.4 從負載平衡反向代理重定向不起作用但在非負載平衡反向代理中工作

[英]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/foohttp://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 的傳入和傳出流量,並確認確實發生了重寫。

重寫發生如下:

  1. GET /foo ,這是發送到外部服務器的原始請求。
  2. GET /foo/ ,這是發送到內部服務器的請求。 請注意在末尾添加斜線的重寫。
  3. Location /foo ,這是內部服務器的重定向響應位置。 這是一個預期的位置,因為在內部服務器中, GET /foo/將被重定向到Location /fooGET /foo將被重定向到Location /foo/bar/baz 在正常情況下,重定向將由內部服務器處理,這意味着GET /foo/將導致重定向導致GET /foo ,最終產生Location /foo/bar/baz但這不會發生在反向代理中。
  4. 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_balancermod_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM