List v1/versions routes based on source IP if found (#10603)

Routing using on source IP if found. This should distribute
the listing load for V1 and versioning on multiple nodes
evenly between different clients.

If source IP is not found from the http request header, then falls back
to bucket name instead.
master
Anis Elleuch 4 years ago committed by GitHub
parent 56d1b227cf
commit 0d45c38782
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      cmd/bucket-listobjects-handlers.go
  2. 14
      pkg/handlers/proxy.go

@ -27,6 +27,7 @@ import (
"github.com/minio/minio/cmd/logger" "github.com/minio/minio/cmd/logger"
"github.com/minio/minio/pkg/bucket/policy" "github.com/minio/minio/pkg/bucket/policy"
"github.com/minio/minio/pkg/handlers"
"github.com/minio/minio/pkg/sync/errgroup" "github.com/minio/minio/pkg/sync/errgroup"
) )
@ -113,7 +114,12 @@ func (api objectAPIHandlers) ListObjectVersionsHandler(w http.ResponseWriter, r
return return
} }
if proxyRequestByBucket(ctx, w, r, bucket) { // Forward the request using Source IP or bucket
forwardStr := handlers.GetSourceIPFromHeaders(r)
if forwardStr == "" {
forwardStr = bucket
}
if proxyRequestByStringHash(ctx, w, r, forwardStr) {
return return
} }
@ -340,8 +346,8 @@ func proxyRequestByNodeIndex(ctx context.Context, w http.ResponseWriter, r *http
return proxyRequest(ctx, w, r, ep) return proxyRequest(ctx, w, r, ep)
} }
func proxyRequestByBucket(ctx context.Context, w http.ResponseWriter, r *http.Request, bucket string) (success bool) { func proxyRequestByStringHash(ctx context.Context, w http.ResponseWriter, r *http.Request, str string) (success bool) {
return proxyRequestByNodeIndex(ctx, w, r, crcHashMod(bucket, len(globalProxyEndpoints))) return proxyRequestByNodeIndex(ctx, w, r, crcHashMod(str, len(globalProxyEndpoints)))
} }
// ListObjectsV1Handler - GET Bucket (List Objects) Version 1. // ListObjectsV1Handler - GET Bucket (List Objects) Version 1.
@ -382,7 +388,12 @@ func (api objectAPIHandlers) ListObjectsV1Handler(w http.ResponseWriter, r *http
return return
} }
if proxyRequestByBucket(ctx, w, r, bucket) { // Forward the request using Source IP or bucket
forwardStr := handlers.GetSourceIPFromHeaders(r)
if forwardStr == "" {
forwardStr = bucket
}
if proxyRequestByStringHash(ctx, w, r, forwardStr) {
return return
} }

@ -74,10 +74,9 @@ func GetSourceScheme(r *http.Request) string {
return scheme return scheme
} }
// GetSourceIP retrieves the IP from the X-Forwarded-For, X-Real-IP and RFC7239 // GetSourceIPFromHeaders retrieves the IP from the X-Forwarded-For, X-Real-IP
// Forwarded headers (in that order), falls back to r.RemoteAddr when all // and RFC7239 Forwarded headers (in that order)
// else fails. func GetSourceIPFromHeaders(r *http.Request) string {
func GetSourceIP(r *http.Request) string {
var addr string var addr string
if fwd := r.Header.Get(xForwardedFor); fwd != "" { if fwd := r.Header.Get(xForwardedFor); fwd != "" {
@ -106,6 +105,13 @@ func GetSourceIP(r *http.Request) string {
} }
} }
return addr
}
// GetSourceIP retrieves the IP from the request headers
// and falls back to r.RemoteAddr when necessary.
func GetSourceIP(r *http.Request) string {
addr := GetSourceIPFromHeaders(r)
if addr != "" { if addr != "" {
return addr return addr
} }

Loading…
Cancel
Save