From 2c3e3116c096bad155d4ea3aa2b5053b738284ba Mon Sep 17 00:00:00 2001 From: charles Date: Tue, 11 Jul 2023 15:12:17 +0200 Subject: [PATCH] Resolved/Balancer: Pass a serverID down to the balancer to avoid loop-redirection. --- common/client/http/balancer.go | 22 ++++++++++++++++------ common/client/http/resolver.go | 6 +++--- common/server/caddy/caddy.go | 5 +++-- common/server/caddy/mux/mux.go | 10 +++++----- common/server/http/http.go | 5 +++-- common/server/http/mux/registrymux.go | 4 ++-- 6 files changed, 32 insertions(+), 20 deletions(-) diff --git a/common/client/http/balancer.go b/common/client/http/balancer.go index 01917c913c..dddca736a8 100644 --- a/common/client/http/balancer.go +++ b/common/client/http/balancer.go @@ -42,7 +42,7 @@ type Balancer interface { PickEndpoint(path string) (*httputil.ReverseProxy, error) } -func NewBalancer() Balancer { +func NewBalancer(excludeID string) Balancer { var clusterConfig *client.ClusterConfig config.Get("cluster").Default(&client.ClusterConfig{}).Scan(&clusterConfig) clientConfig := clusterConfig.GetClientConfig("http") @@ -54,12 +54,14 @@ func NewBalancer() Balancer { return &balancer{ readyProxies: map[string]*reverseProxy{}, options: opts, + excludeID: excludeID, } } type balancer struct { readyProxies map[string]*reverseProxy options *client.BalancerOptions + excludeID string } type reverseProxy struct { @@ -84,7 +86,10 @@ func (p *proxyBalancerTarget) Attributes() *attributes.Attributes { func (b *balancer) Build(m map[string]*client.ServerAttributes) error { usedAddr := map[string]struct{}{} - for _, mm := range m { + for srvID, mm := range m { + if b.excludeID != "" && srvID == b.excludeID { + continue + } for _, addr := range mm.Addresses { usedAddr[addr] = struct{}{} proxy, ok := b.readyProxies[addr] @@ -162,23 +167,28 @@ func (b *balancer) PickService(name string) (*httputil.ReverseProxy, error) { } func (b *balancer) PickEndpoint(path string) (*httputil.ReverseProxy, error) { - var targets []*proxyBalancerTarget + dedup := map[string]*proxyBalancerTarget{} + for addr, proxy := range b.readyProxies { for _, endpoint := range proxy.Endpoints { if endpoint == "/" { continue } if strings.HasPrefix(path, endpoint) { - targets = append(targets, &proxyBalancerTarget{ + dedup[addr] = &proxyBalancerTarget{ proxy: proxy, address: addr, - }) + } } } } - if len(targets) == 0 { + if len(dedup) == 0 { return nil, fmt.Errorf("no proxy found for endpoint %s", path) } + var targets []*proxyBalancerTarget + for _, pbt := range dedup { + targets = append(targets, pbt) + } if b.options != nil && len(b.options.Filters) > 0 { for _, f := range b.options.Filters { targets = b.applyFilter(f, targets) diff --git a/common/client/http/resolver.go b/common/client/http/resolver.go index 61c8a087a1..df3ac62c91 100644 --- a/common/client/http/resolver.go +++ b/common/client/http/resolver.go @@ -31,7 +31,7 @@ var grpcTransport = &http.Transport{ type Resolver interface { ServeHTTP(w http.ResponseWriter, r *http.Request) (bool, error) - Init(ctx context.Context, s server.HttpMux) + Init(ctx context.Context, serverID string, s server.HttpMux) Stop() } @@ -49,12 +49,12 @@ type resolver struct { userReady bool } -func (m *resolver) Init(ctx context.Context, s server.HttpMux) { +func (m *resolver) Init(ctx context.Context, serverID string, s server.HttpMux) { conn := clientcontext.GetClientConn(ctx) reg := servercontext.GetRegistry(ctx) rc, _ := client.NewResolverCallback(reg) - bal := NewBalancer() + bal := NewBalancer(serverID) rc.Add(bal.Build) m.c = conn diff --git a/common/server/caddy/caddy.go b/common/server/caddy/caddy.go index c0b9fa90b9..d184908cd9 100644 --- a/common/server/caddy/caddy.go +++ b/common/server/caddy/caddy.go @@ -160,7 +160,8 @@ func New(ctx context.Context, dir string) (server.Server, error) { }) srvMUX := server.NewListableMux() - mux.RegisterServerMux(ctx, srvMUX) + srvID := "caddy-" + uuid.New() + mux.RegisterServerMux(ctx, srvID, srvMUX) caddyStorePath := filepath.Join(runtime.ApplicationWorkingDir(), "caddy") _ = os.MkdirAll(caddyStorePath, 0755) @@ -170,7 +171,7 @@ func New(ctx context.Context, dir string) (server.Server, error) { } srv := &Server{ - id: "caddy-" + uuid.New(), + id: srvID, name: "caddy", meta: make(map[string]string), diff --git a/common/server/caddy/mux/mux.go b/common/server/caddy/mux/mux.go index 1a032f95a4..755b9bb837 100644 --- a/common/server/caddy/mux/mux.go +++ b/common/server/caddy/mux/mux.go @@ -37,14 +37,14 @@ var ( module *Middleware ) -func RegisterServerMux(ctx context.Context, s server.HttpMux) { +func RegisterServerMux(ctx context.Context, serverID string, s server.HttpMux) { if module != nil { module.Stop() - module.Init(ctx, s) + module.Init(ctx, serverID, s) return } module = &Middleware{Resolver: clienthttp.NewResolver()} - module.Init(ctx, s) + module.Init(ctx, serverID, s) caddy.RegisterModule(module) httpcaddyfile.RegisterHandlerDirective("mux", parseCaddyfile) } @@ -53,8 +53,8 @@ type Middleware struct { clienthttp.Resolver } -func (m *Middleware) Init(ctx context.Context, s server.HttpMux) { - m.Resolver.Init(ctx, s) +func (m *Middleware) Init(ctx context.Context, serverID string, s server.HttpMux) { + m.Resolver.Init(ctx, serverID, s) } func (m *Middleware) Stop() { diff --git a/common/server/http/http.go b/common/server/http/http.go index 0f38cd87c0..c1d4852a66 100644 --- a/common/server/http/http.go +++ b/common/server/http/http.go @@ -71,14 +71,15 @@ func New(ctx context.Context) server.Server { */ srv := &http.Server{} - srv.Handler = mux.NewMiddleware(ctx, lMux) + srvID := "http-" + uuid.New() + srv.Handler = mux.NewMiddleware(ctx, srvID, lMux) srv.Handler = ContextMiddlewareHandler(middleware.ClientConnIncomingContext(ctx))(srv.Handler) srv.Handler = ContextMiddlewareHandler(middleware.RegistryIncomingContext(ctx))(srv.Handler) ctx, cancel := context.WithCancel(ctx) return server.NewServer(ctx, &Server{ - id: "http-" + uuid.New(), + id: srvID, name: "http", meta: make(map[string]string), diff --git a/common/server/http/mux/registrymux.go b/common/server/http/mux/registrymux.go index 0bae03d75c..80383a90d3 100644 --- a/common/server/http/mux/registrymux.go +++ b/common/server/http/mux/registrymux.go @@ -33,11 +33,11 @@ type Middleware struct { clienthttp.Resolver } -func NewMiddleware(ctx context.Context, s server.HttpMux) Middleware { +func NewMiddleware(ctx context.Context, serverID string, s server.HttpMux) Middleware { m := Middleware{ Resolver: clienthttp.NewResolver(), } - m.Resolver.Init(ctx, s) + m.Resolver.Init(ctx, serverID, s) return m }