web-dev-qa-db-ja.com

HAProxy-同じURLでポートが異なるサービスを区別するために、ACLにURLパラメータを追加する必要があります

異なるポートで実行されるサービスがいくつかあり、それぞれが同じURIパスを使用しています。例えば:

New York Housing Service
127.0.0.1:8080/homes
127.0.0.1:8080/prices

Las Vegas Housing Service
127.0.0.1:8081/homes
127.0.0.1:8081/prices

これまでは問題ありませんでしたが、サービスの負荷を分散するためにhaproxyを設定する必要があります。そのため、コンテンツの切り替えのためにそれらを区別できる必要があることは明らかです。私が想像するのは、ACLのパスにパラメーターを追加して、2つのバックエンドを区別することです。この場合、ACLにurlパラメーターを設定し、その後にアプリケーションの実際のパスパラメーターを追加します。


frontend http
  maxconn 2000
  bind 0.0.0.0:5000  

  acl new-york path_reg -i /newyork.*
  use_backend nyc-server if new-york

  acl las-vegas path_reg -i /lasvegas.*
  use_backend lv-server if las-vegas

backend nyc-server
  server www.test.com 127.0.0.1:8080 maxconn 100

backend lv-server
  server www.test.com 127.0.0.1:8081 maxconn 100

この設定では、127.0.0.1:5000/newyork/homeに移動すると127.0.0.1:808/homeに移動し、127.0.0.1:5000/lasvegas/homeに移動すると127.0.0.1に移動します。 :8081 /ホーム。これまでの私の試みは、単に404エラーを返しました。私はドキュメントを調べてきましたが、私のユースケースに完全に一致するものは見当たらなかったので、助けていただければ幸いです。

編集:私はhaproxy1.5.18を使用していることを言及するのを忘れました

1
SVill

HAPROXY構成が現在URLのパスをそのまま転送しているため、バックエンドサービスはHTTP404エラーで応答しています。たとえば、http://127.0.0.1:5000/newyork/home/wtc.pngに対するHTTPリクエストはnyc-serverとしてhttp://127.0.0.1:8000/newyork/home/wtc.pngバックエンドに転送されています。

$ wget -4O /dev/null http://localhost:5000/newyork/homes/wtc.png
--2020-02-01 13:00:09--  http://localhost:5000/newyork/homes/wtc.png
Resolving localhost (localhost)... 127.0.0.1, 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:5000... connected.
HTTP request sent, awaiting response... 404 File not found
2020-02-01 13:00:09 ERROR 404: File not found.
$ python -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
127.0.0.1 - - [01/Feb/2020 13:00:09] code 404, message File not found
127.0.0.1 - - [01/Feb/2020 13:00:09] "GET /newyork/homes/wtc.png HTTP/1.1" 404 -

HAproxyは、バックエンドからリソースをフェッチするときに最初のパスコンポーネントを削除して、URLのパスを変換するように構成する必要があります。フロントエンドの定義にreqrepディレクティブを追加することをお勧めします。これは、HTTPリクエストヘッダーの最初の行を操作し、GET /newyork/homes/wtc.png HTTP/1.1のようなものをGET /homes/wtc.png HTTP/1.1に変換することを目的としています。

frontend http
  reqrep ^([A-Z]+)\ /+[^/]+(/+.*)?$  \1\ \2

ただし、HAproxyはuse-backendディレクティブの前にreqrepディレクティブを評価するため、機能しません。したがって、バックエンドの評価が壊れます。

$ wget -4O /dev/null http://localhost:5000/newyork/homes/wtc.png
--2020-02-01 13:54:55--  http://localhost:5000/newyork/homes/wtc.png
Resolving localhost (localhost)... 127.0.0.1, 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:5000... connected.
HTTP request sent, awaiting response... 503 Service Unavailable
2020-02-01 13:54:55 ERROR 503: Service Unavailable.

2番目の実用的なアプローチは、バックエンド定義のURLパスを書き換えることです。ただし、サービス中のバックエンドの数によっては、reqrepディレクティブを記述し、URL書き換えを実行するように各バックエンドを構成するとエラーが発生しやすくなります。

backend nyc-server
  server www.test.com 127.0.0.1:8080 maxconn 100
  reqrep ^([A-Z]+)\ /+[^/]+(/+.*)?$  \1\ \2

backend lv-server
  server www.test.com 127.0.0.1:8081 maxconn 100
  reqrep ^([A-Z]+)\ /+[^/]+(/+.*)?$  \1\ \2
$ wget -4O /dev/null http://localhost:5000/newyork/homes/wtc.png
--2020-02-01 14:02:29--  http://localhost:5000/newyork/homes/wtc.png
Resolving localhost (localhost)... 127.0.0.1, 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:5000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 456892 (446K) [image/png]
Saving to: ‘/dev/null’

/dev/null        100%[===============>] 446.18K  --.-KB/s    in 0s      

2020-02-01 14:02:29 (1.83 GB/s) - ‘/dev/null’ saved [456892/456892]

$ python -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
127.0.0.1 - - [01/Feb/2020 14:02:29] "GET /homes/wtc.png HTTP/1.1" 200 -