diff --git a/cluster/router/chain/chain.go b/cluster/router/chain/chain.go index b94beb65ed10c34d3cc679f17c167e2ec6a03990..1ca7d479d14860947427cd9d1a7c53ae7620beab 100644 --- a/cluster/router/chain/chain.go +++ b/cluster/router/chain/chain.go @@ -81,8 +81,8 @@ func (c *RouterChain) Route(url *common.URL, invocation protocol.Invocation) []p indexes := bitmap.ToArray() finalInvokers := make([]protocol.Invoker, len(indexes)) - for _, index := range indexes { - finalInvokers = append(finalInvokers, cache.Invokers[index]) + for i, index := range indexes { + finalInvokers[i] = cache.Invokers[index] } return finalInvokers } diff --git a/cluster/router/chain/chain_test.go b/cluster/router/chain/chain_test.go index c1f723525f5307e7732f0ea1ecc27eca7ba09c8d..8890c293ed20b4d78ec5ae3f69ebf6fbaaede135 100644 --- a/cluster/router/chain/chain_test.go +++ b/cluster/router/chain/chain_test.go @@ -168,10 +168,12 @@ func TestRouterChainRoute(t *testing.T) { invokers := []protocol.Invoker{} dubboURL, _ := common.NewURL(fmt.Sprintf(dubboForamt, test1234IP, port20000)) invokers = append(invokers, protocol.NewBaseInvoker(dubboURL)) + chain.SetInvokers(invokers) + chain.buildCache() targetURL, _ := common.NewURL(fmt.Sprintf(consumerFormat, test1111IP)) inv := &invocation.RPCInvocation{} - finalInvokers := chain.Route(invokers, &targetURL, inv) + finalInvokers := chain.Route(&targetURL, inv) assert.Equal(t, 1, len(finalInvokers)) } @@ -205,10 +207,12 @@ conditions: invokers := []protocol.Invoker{} dubboURL, _ := common.NewURL(fmt.Sprintf(dubboForamt, test1234IP, port20000)) invokers = append(invokers, protocol.NewBaseInvoker(dubboURL)) + chain.SetInvokers(invokers) + chain.buildCache() targetURL, _ := common.NewURL(fmt.Sprintf(consumerFormat, test1111IP)) inv := &invocation.RPCInvocation{} - finalInvokers := chain.Route(invokers, &targetURL, inv) + finalInvokers := chain.Route(&targetURL, inv) assert.Equal(t, 0, len(finalInvokers)) } @@ -232,10 +236,12 @@ func TestRouterChainRouteNoRoute(t *testing.T) { invokers := []protocol.Invoker{} dubboURL, _ := common.NewURL(fmt.Sprintf(dubboForamt, test1234IP, port20000)) invokers = append(invokers, protocol.NewBaseInvoker(dubboURL)) + chain.SetInvokers(invokers) + chain.buildCache() targetURL, _ := common.NewURL(fmt.Sprintf(consumerFormat, test1111IP)) inv := &invocation.RPCInvocation{} - finalInvokers := chain.Route(invokers, &targetURL, inv) + finalInvokers := chain.Route(&targetURL, inv) assert.Equal(t, 0, len(finalInvokers)) } diff --git a/cluster/router/condition/factory_test.go b/cluster/router/condition/factory_test.go index 0f61b39fc71af3aaeffc731974a0fa997503693e..91aeb8d886bcbc873a73087f7fe0fbc0e0fe0267 100644 --- a/cluster/router/condition/factory_test.go +++ b/cluster/router/condition/factory_test.go @@ -32,6 +32,8 @@ import ( ) import ( + "github.com/apache/dubbo-go/cluster/router" + "github.com/apache/dubbo-go/cluster/router/utils" "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/logger" @@ -180,30 +182,30 @@ func TestRoute_matchFilter(t *testing.T) { router5, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule5)) router6, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule6)) cUrl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - fileredInvokers1 := router1.Route(invokers, &cUrl, &invocation.RPCInvocation{}) - fileredInvokers2 := router2.Route(invokers, &cUrl, &invocation.RPCInvocation{}) - fileredInvokers3 := router3.Route(invokers, &cUrl, &invocation.RPCInvocation{}) - fileredInvokers4 := router4.Route(invokers, &cUrl, &invocation.RPCInvocation{}) - fileredInvokers5 := router5.Route(invokers, &cUrl, &invocation.RPCInvocation{}) - fileredInvokers6 := router6.Route(invokers, &cUrl, &invocation.RPCInvocation{}) - assert.Equal(t, 1, len(fileredInvokers1)) - assert.Equal(t, 0, len(fileredInvokers2)) - assert.Equal(t, 0, len(fileredInvokers3)) - assert.Equal(t, 1, len(fileredInvokers4)) - assert.Equal(t, 2, len(fileredInvokers5)) - assert.Equal(t, 1, len(fileredInvokers6)) + ret1 := router1.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), &cUrl, &invocation.RPCInvocation{}) + ret2 := router2.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), &cUrl, &invocation.RPCInvocation{}) + ret3 := router3.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), &cUrl, &invocation.RPCInvocation{}) + ret4 := router4.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), &cUrl, &invocation.RPCInvocation{}) + ret5 := router5.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), &cUrl, &invocation.RPCInvocation{}) + ret6 := router6.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), &cUrl, &invocation.RPCInvocation{}) + assert.Equal(t, 1, len(ret1.ToArray())) + assert.Equal(t, 0, len(ret2.ToArray())) + assert.Equal(t, 0, len(ret3.ToArray())) + assert.Equal(t, 1, len(ret4.ToArray())) + assert.Equal(t, 2, len(ret5.ToArray())) + assert.Equal(t, 1, len(ret6.ToArray())) } func TestRoute_methodRoute(t *testing.T) { inv := invocation.NewRPCInvocationWithOptions(invocation.WithMethodName("getFoo"), invocation.WithParameterTypes([]reflect.Type{}), invocation.WithArguments([]interface{}{})) rule := base64.URLEncoding.EncodeToString([]byte("host !=4.4.4.* & host = 2.2.2.2,1.1.1.1,3.3.3.3 => host = 1.2.3.4")) - router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) url, _ := common.NewURL("consumer://1.1.1.1/com.foo.BarService?methods=setFoo,getFoo,findFoo") - matchWhen := router.(*ConditionRouter).MatchWhen(&url, inv) + matchWhen := r.(*ConditionRouter).MatchWhen(&url, inv) assert.Equal(t, true, matchWhen) url1, _ := common.NewURL(fmt.Sprintf(factoryConsumerMethodFormat, factory1111Ip)) - matchWhen = router.(*ConditionRouter).MatchWhen(&url1, inv) + matchWhen = r.(*ConditionRouter).MatchWhen(&url1, inv) assert.Equal(t, true, matchWhen) url2, _ := common.NewURL(fmt.Sprintf(factoryConsumerMethodFormat, factory1111Ip)) rule2 := base64.URLEncoding.EncodeToString([]byte("methods=getFoo & host!=1.1.1.1 => host = 1.2.3.4")) @@ -225,9 +227,9 @@ func TestRoute_ReturnFalse(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => false")) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) - fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv) - assert.Equal(t, 0, len(fileredInvokers)) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), &curl, inv) + assert.Equal(t, 0, len(ret.ToArray())) } func TestRoute_ReturnEmpty(t *testing.T) { @@ -237,9 +239,9 @@ func TestRoute_ReturnEmpty(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => ")) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) - fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv) - assert.Equal(t, 0, len(fileredInvokers)) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), &curl, inv) + assert.Equal(t, 0, len(ret.ToArray())) } func TestRoute_ReturnAll(t *testing.T) { @@ -253,9 +255,9 @@ func TestRoute_ReturnAll(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = " + localIP)) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) - fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv) - assert.Equal(t, invokers, fileredInvokers) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), &curl, inv) + assert.Equal(t, len(invokers), len(ret.ToArray())) } func TestRoute_HostFilter(t *testing.T) { @@ -270,11 +272,11 @@ func TestRoute_HostFilter(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = " + localIP)) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) - fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv) - assert.Equal(t, 2, len(fileredInvokers)) - assert.Equal(t, invoker2, fileredInvokers[0]) - assert.Equal(t, invoker3, fileredInvokers[1]) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), &curl, inv) + assert.Equal(t, 2, len(ret.ToArray())) + assert.Equal(t, invoker2, invokers[ret.ToArray()[0]]) + assert.Equal(t, invoker3, invokers[ret.ToArray()[1]]) } func TestRoute_Empty_HostFilter(t *testing.T) { @@ -289,11 +291,11 @@ func TestRoute_Empty_HostFilter(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte(" => " + " host = " + localIP)) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) - fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv) - assert.Equal(t, 2, len(fileredInvokers)) - assert.Equal(t, invoker2, fileredInvokers[0]) - assert.Equal(t, invoker3, fileredInvokers[1]) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), &curl, inv) + assert.Equal(t, 2, len(ret.ToArray())) + assert.Equal(t, invoker2, invokers[ret.ToArray()[0]]) + assert.Equal(t, invoker3, invokers[ret.ToArray()[1]]) } func TestRoute_False_HostFilter(t *testing.T) { @@ -308,11 +310,11 @@ func TestRoute_False_HostFilter(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("true => " + " host = " + localIP)) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) - fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv) - assert.Equal(t, 2, len(fileredInvokers)) - assert.Equal(t, invoker2, fileredInvokers[0]) - assert.Equal(t, invoker3, fileredInvokers[1]) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), &curl, inv) + assert.Equal(t, 2, len(ret.ToArray())) + assert.Equal(t, invoker2, invokers[ret.ToArray()[0]]) + assert.Equal(t, invoker3, invokers[ret.ToArray()[1]]) } func TestRoute_Placeholder(t *testing.T) { @@ -327,11 +329,11 @@ func TestRoute_Placeholder(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte("host = " + localIP + " => " + " host = $host")) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) - fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv) - assert.Equal(t, 2, len(fileredInvokers)) - assert.Equal(t, invoker2, fileredInvokers[0]) - assert.Equal(t, invoker3, fileredInvokers[1]) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrl(rule)) + ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), &curl, inv) + assert.Equal(t, 2, len(ret.ToArray())) + assert.Equal(t, invoker2, invokers[ret.ToArray()[0]]) + assert.Equal(t, invoker3, invokers[ret.ToArray()[1]]) } func TestRoute_NoForce(t *testing.T) { @@ -346,9 +348,9 @@ func TestRoute_NoForce(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte(fmt.Sprintf(factoryHostIp1234Format, localIP))) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrlWithNoForce(rule)) - fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv) - assert.Equal(t, invokers, fileredInvokers) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrlWithNoForce(rule)) + ret := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), &curl, inv) + assert.Equal(t, len(invokers), len(ret.ToArray())) } func TestRoute_Force(t *testing.T) { @@ -363,9 +365,9 @@ func TestRoute_Force(t *testing.T) { inv := &invocation.RPCInvocation{} rule := base64.URLEncoding.EncodeToString([]byte(fmt.Sprintf(factoryHostIp1234Format, localIP))) curl, _ := common.NewURL(fmt.Sprintf(factoryConsumerFormat, localIP)) - router, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrlWithForce(rule, "true")) - fileredInvokers := router.(*ConditionRouter).Route(invokers, &curl, inv) - assert.Equal(t, 0, len(fileredInvokers)) + r, _ := newConditionRouterFactory().NewPriorityRouter(getRouteUrlWithForce(rule, "true")) + fileredInvokers := r.Route(utils.ToBitmap(invokers), setUpAddrCache(invokers), &curl, inv) + assert.Equal(t, 0, len(fileredInvokers.ToArray())) } func TestNewConditionRouterFactory(t *testing.T) { @@ -377,3 +379,10 @@ func TestNewAppRouterFactory(t *testing.T) { factory := newAppRouterFactory() assert.NotNil(t, factory) } + +func setUpAddrCache(addrs []protocol.Invoker) *router.AddrCache { + cache := &router.AddrCache{ + Invokers: addrs, + } + return cache +} diff --git a/cluster/router/condition/listenable_router.go b/cluster/router/condition/listenable_router.go index b6651d251910f3be7940d07380c9764de8434434..86f128bf4d8088b62a8e51f21bfd3ad4c6ba3289 100644 --- a/cluster/router/condition/listenable_router.go +++ b/cluster/router/condition/listenable_router.go @@ -19,16 +19,15 @@ package condition import ( "fmt" - "github.com/RoaringBitmap/roaring" - "github.com/apache/dubbo-go/cluster/router" - "sync" ) import ( + "github.com/RoaringBitmap/roaring" perrors "github.com/pkg/errors" ) import ( + "github.com/apache/dubbo-go/cluster/router" "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/config" "github.com/apache/dubbo-go/common/constant" @@ -43,24 +42,13 @@ const ( listenableRouterDefaultPriority = ^int64(0) ) -type conditionRouterSnapshot struct { - routers []*ConditionRouter -} - -func (s *conditionRouterSnapshot) Source() string { - return "listenable-router" -} - // listenableRouter Abstract router which listens to dynamic configuration type listenableRouter struct { conditionRouters []*ConditionRouter routerRule *RouterRule url *common.URL - routerKey string - changed bool force bool priority int64 - mutex sync.RWMutex } // RouterRule Get RouterRule instance from listenableRouter @@ -78,9 +66,6 @@ func newListenableRouter(url *common.URL, ruleKey string) (*AppRouter, error) { l.priority = listenableRouterDefaultPriority routerKey := ruleKey + constant.ConditionRouterRuleSuffix - l.routerKey = routerKey - l.changed = true - //add listener dynamicConfiguration := config.GetEnvInstance().GetDynamicConfiguration() if dynamicConfiguration == nil { @@ -107,8 +92,6 @@ func (l *listenableRouter) Process(event *config_center.ConfigChangeEvent) { logger.Infof("Notification of condition rule, change type is:[%s] , raw rule is:[%v]", event.ConfigType, event.Value) if remoting.EventTypeDel == event.ConfigType { l.routerRule = nil - l.mutex.Lock() - l.mutex.Unlock() if l.conditionRouters != nil { l.conditionRouters = l.conditionRouters[:0] } @@ -133,9 +116,6 @@ func (l *listenableRouter) generateConditions(rule *RouterRule) { if rule == nil || !rule.Valid { return } - - l.mutex.Lock() - defer l.mutex.Unlock() l.conditionRouters = make([]*ConditionRouter, 0, len(rule.Conditions)) l.routerRule = rule for _, c := range rule.Conditions { @@ -148,71 +128,20 @@ func (l *listenableRouter) generateConditions(rule *RouterRule) { router.enabled = rule.Enabled l.conditionRouters = append(l.conditionRouters, router) } - l.changed = true } // Route Determine the target invokers list. func (l *listenableRouter) Route(invokers *roaring.Bitmap, cache *router.AddrCache, url *common.URL, invocation protocol.Invocation) *roaring.Bitmap { - meta := cache.FindAddrMeta(l) - conditionRouters := meta.(*conditionRouterSnapshot).routers - - if invokers.IsEmpty() || len(conditionRouters) == 0 { + if invokers.IsEmpty() || len(l.conditionRouters) == 0 { return invokers } - //We will check enabled status inside each router. - newCache := l.convertCache(cache, conditionRouters) - for _, r := range conditionRouters { - invokers = r.Route(invokers, newCache, url, invocation) + for _, r := range l.conditionRouters { + invokers = r.Route(invokers, cache, url, invocation) } return invokers } -func (l *listenableRouter) convertCache(cache *router.AddrCache, conditionRouters []*ConditionRouter) *router.AddrCache { - pool := cache.FindAddrPool(l) - pools := make(map[string]router.RouterAddrPool) - for _, r := range conditionRouters { - rb := pool[r.Name()] - rp := make(router.RouterAddrPool) - rp["matched"] = rb - pools[r.Name()] = rp - } - - newCache := &router.AddrCache{ - Invokers: cache.Invokers, - Bitmap: cache.Bitmap, - AddrPool: pools, - } - return newCache -} - -func (l *listenableRouter) Pool(invokers []protocol.Invoker) (router.RouterAddrPool, router.AddrMetadata) { - l.mutex.RLock() - routers := make([]*ConditionRouter, len(l.conditionRouters)) - copy(routers, l.conditionRouters) - l.mutex.RUnlock() - - rb := make(router.RouterAddrPool) - for _, r := range routers { - pool, _ := r.Pool(invokers) - rb[r.Name()] = pool["matched"] - } - return rb, &conditionRouterSnapshot{routers} -} - -func (l *listenableRouter) ShouldRePool() bool { - if l.changed { - l.changed = false - return true - } else { - return false - } -} - -func (l *listenableRouter) Name() string { - return l.routerKey -} - // Priority Return Priority in listenable router func (l *listenableRouter) Priority() int64 { return l.priority diff --git a/cluster/router/condition/router.go b/cluster/router/condition/router.go index 5f62e9698fc23794d4d906683db5d8d7a42577b1..cd544477a121ca17a1bb637331fa69fd5501fff7 100644 --- a/cluster/router/condition/router.go +++ b/cluster/router/condition/router.go @@ -18,18 +18,17 @@ package condition import ( - "github.com/RoaringBitmap/roaring" - "github.com/apache/dubbo-go/cluster/router" - "github.com/apache/dubbo-go/cluster/router/utils" "regexp" "strings" ) import ( + "github.com/RoaringBitmap/roaring" perrors "github.com/pkg/errors" ) import ( + "github.com/apache/dubbo-go/cluster/router" "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/logger" @@ -54,8 +53,6 @@ type ConditionRouter struct { priority int64 Force bool enabled bool - rule string - isNew bool WhenCondition map[string]MatchPair ThenCondition map[string]MatchPair } @@ -101,8 +98,6 @@ func NewConditionRouterWithRule(rule string) (*ConditionRouter, error) { } return &ConditionRouter{ Pattern: pattern, - rule: rule, - isNew: true, WhenCondition: when, ThenCondition: then, }, nil @@ -167,18 +162,15 @@ func (c *ConditionRouter) Route(invokers *roaring.Bitmap, cache *router.AddrCach return router.EmptyAddr } - addrPool := cache.FindAddrPool(c) - result := utils.JoinIfNotEqual(addrPool["matched"], invokers) - - //result = roaring.NewBitmap() - //for iter := invokers.Iterator(); iter.HasNext(); { - // index := iter.Next() - // invokerUrl := cache.Invokers[index].GetUrl() - // isMatchThen := c.MatchThen(&invokerUrl, url) - // if isMatchThen { - // result.Add(index) - // } - //} + result := roaring.NewBitmap() + for iter := invokers.Iterator(); iter.HasNext(); { + index := iter.Next() + invokerUrl := cache.Invokers[index].GetUrl() + isMatchThen := c.MatchThen(&invokerUrl, url) + if isMatchThen { + result.Add(index) + } + } if !result.IsEmpty() { return result @@ -188,33 +180,8 @@ func (c *ConditionRouter) Route(invokers *roaring.Bitmap, cache *router.AddrCach logger.Warnf("The route result is empty and force execute. consumer: %s, service: %s, router: %s", localIP, url.Service(), rule) return result } - return invokers -} - -func (c *ConditionRouter) Pool(invokers []protocol.Invoker) (router.RouterAddrPool, router.AddrMetadata) { - rb := make(router.RouterAddrPool) - rb["matched"] = roaring.NewBitmap() - param := invokers[0].GetUrl() - for i, invoker := range invokers { - invokerUrl := invoker.GetUrl() - if c.MatchThen(&invokerUrl, ¶m) { - rb["matched"].AddInt(i) - } - } - return rb, nil -} - -func (c *ConditionRouter) ShouldRePool() bool { - if c.isNew { - c.isNew = false - return true - } else { - return false - } -} -func (c *ConditionRouter) Name() string { - return c.rule + return invokers } func parseRule(rule string) (map[string]MatchPair, error) { diff --git a/cluster/router/healthcheck/health_check_route_test.go b/cluster/router/healthcheck/health_check_route_test.go index d5862fb884114bac0ea2ec9ee8926baac57d5ba6..ddd68ec403b473d1dab57d7176b6cdc233545754 100644 --- a/cluster/router/healthcheck/health_check_route_test.go +++ b/cluster/router/healthcheck/health_check_route_test.go @@ -19,6 +19,8 @@ package healthcheck import ( "fmt" + "github.com/apache/dubbo-go/cluster/router" + "github.com/apache/dubbo-go/cluster/router/utils" "math" "testing" "time" @@ -59,25 +61,25 @@ func TestHealthCheckRouterRoute(t *testing.T) { invoker3 := NewMockInvoker(url3) invokers = append(invokers, invoker1, invoker2, invoker3) inv := invocation.NewRPCInvocation(healthCheckRouteMethodNameTest, nil, nil) - res := hcr.Route(invokers, &consumerURL, inv) + res := hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), &consumerURL, inv) // now all invokers are healthy - assert.True(t, len(res) == len(invokers)) + assert.True(t, len(res.ToArray()) == len(invokers)) for i := 0; i < 10; i++ { request(url1, healthCheckRouteMethodNameTest, 0, false, false) } - res = hcr.Route(invokers, &consumerURL, inv) + res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), &consumerURL, inv) // invokers1 is unhealthy now - assert.True(t, len(res) == 2 && !contains(res, invoker1)) + assert.True(t, len(res.ToArray()) == 2 && !res.Contains(0)) for i := 0; i < 10; i++ { request(url1, healthCheckRouteMethodNameTest, 0, false, false) request(url2, healthCheckRouteMethodNameTest, 0, false, false) } - res = hcr.Route(invokers, &consumerURL, inv) + res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), &consumerURL, inv) // only invokers3 is healthy now - assert.True(t, len(res) == 1 && !contains(res, invoker1) && !contains(res, invoker2)) + assert.True(t, len(res.ToArray()) == 1 && !res.Contains(0) && !res.Contains(1)) for i := 0; i < 10; i++ { request(url1, healthCheckRouteMethodNameTest, 0, false, false) @@ -85,37 +87,28 @@ func TestHealthCheckRouterRoute(t *testing.T) { request(url3, healthCheckRouteMethodNameTest, 0, false, false) } - res = hcr.Route(invokers, &consumerURL, inv) + res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), &consumerURL, inv) // now all invokers are unhealthy, so downgraded to all - assert.True(t, len(res) == 3) + assert.True(t, len(res.ToArray()) == 3) // reset the invoker1 successive failed count, so invoker1 go to healthy request(url1, healthCheckRouteMethodNameTest, 0, false, true) - res = hcr.Route(invokers, &consumerURL, inv) - assert.True(t, contains(res, invoker1)) + res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), &consumerURL, inv) + assert.True(t, res.Contains(0)) for i := 0; i < 6; i++ { request(url1, healthCheckRouteMethodNameTest, 0, false, false) } // now all invokers are unhealthy, so downgraded to all again - res = hcr.Route(invokers, &consumerURL, inv) - assert.True(t, len(res) == 3) + res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), &consumerURL, inv) + assert.True(t, len(res.ToArray()) == 3) time.Sleep(time.Second * 2) // invoker1 go to healthy again after 2s - res = hcr.Route(invokers, &consumerURL, inv) - assert.True(t, contains(res, invoker1)) + res = hcr.Route(utils.ToBitmap(invokers), setUpAddrCache(hcr.(*HealthCheckRouter), invokers), &consumerURL, inv) + assert.True(t, res.Contains(0)) } -func contains(invokers []protocol.Invoker, invoker protocol.Invoker) bool { - for _, e := range invokers { - if e == invoker { - return true - } - } - return false -} - func TestNewHealthCheckRouter(t *testing.T) { defer protocol.CleanAllStatus() url, _ := common.NewURL(fmt.Sprintf(healthCheckDubboUrlFormat, healthCheckDubbo1010IP)) @@ -143,3 +136,16 @@ func TestNewHealthCheckRouter(t *testing.T) { assert.Equal(t, dhc.requestSuccessiveFailureThreshold, int32(10)) assert.Equal(t, dhc.circuitTrippedTimeoutFactor, int32(500)) } + +func setUpAddrCache(r router.Poolable, addrs []protocol.Invoker) *router.AddrCache { + pool, info := r.Pool(addrs) + cache := &router.AddrCache{ + Invokers: addrs, + AddrPool: make(map[string]router.RouterAddrPool), + AddrMeta: make(map[string]router.AddrMetadata), + } + + cache.AddrMeta[r.Name()] = info + cache.AddrPool[r.Name()] = pool + return cache +} diff --git a/cluster/router/tag/file.go b/cluster/router/tag/file.go index 8144c83203dbe98778dd6bb8dcdb9888be664b3b..4f0f8517bd98631f1a8f9886d847d84c47e10beb 100644 --- a/cluster/router/tag/file.go +++ b/cluster/router/tag/file.go @@ -18,6 +18,8 @@ package tag import ( + "github.com/RoaringBitmap/roaring" + "github.com/apache/dubbo-go/cluster/router" "net/url" "strconv" "sync" @@ -74,9 +76,10 @@ func (f *FileTagRouter) Priority() int64 { return f.router.priority } -func (f *FileTagRouter) Route(invokers []protocol.Invoker, url *common.URL, invocation protocol.Invocation) []protocol.Invoker { - if len(invokers) == 0 { +func (f *FileTagRouter) Route(invokers *roaring.Bitmap, cache *router.AddrCache, url *common.URL, invocation protocol.Invocation) *roaring.Bitmap { + if invokers.IsEmpty() { return invokers } - return f.Route(invokers, url, invocation) + // FIXME: I believe this is incorrect. + return f.Route(invokers, cache, url, invocation) } diff --git a/cluster/router/tag/tag_router.go b/cluster/router/tag/tag_router.go index c2d8a0f8083debd38023a4ad9838d43e16c9a589..6b359b869dfee8ae624574a26933f6e397309c1e 100644 --- a/cluster/router/tag/tag_router.go +++ b/cluster/router/tag/tag_router.go @@ -65,15 +65,16 @@ func (c *tagRouter) Route(invokers *roaring.Bitmap, cache *router.AddrCache, url return invokers } - addrPool := cache.FindAddrPool(c) - if target, ok := addrPool[tag]; ok { - ret := utils.JoinIfNotEqual(target, invokers) - if ret.IsEmpty() && !isForceUseTag(url, invocation) { - return invokers - } - return ret + ret := router.EmptyAddr + if target, ok := cache.FindAddrPool(c)[tag]; ok { + ret = utils.JoinIfNotEqual(target, invokers) } - return invokers + + if ret.IsEmpty() && !isForceUseTag(url, invocation) { + return invokers + } + + return ret } func (c *tagRouter) URL() common.URL { diff --git a/cluster/router/tag/tag_router_test.go b/cluster/router/tag/tag_router_test.go index 000b3ec6724d85590c86456a009d5194c4e71e03..465f5504926d3042609c513dbefa24837d666382 100644 --- a/cluster/router/tag/tag_router_test.go +++ b/cluster/router/tag/tag_router_test.go @@ -19,6 +19,8 @@ package tag import ( "context" + "github.com/apache/dubbo-go/cluster/router" + "github.com/apache/dubbo-go/cluster/router/utils" "testing" ) @@ -116,17 +118,17 @@ func TestTagRouterRouteForce(t *testing.T) { invokers = append(invokers, inv2, inv3, inv4) inv := &invocation.RPCInvocation{} inv.SetAttachments(tagRouterTestDubboTag, tagRouterTestHangZhou) - invRst1 := tagRouter.Route(invokers, &u1, inv) - assert.Equal(t, 1, len(invRst1)) - assert.Equal(t, tagRouterTestHangZhou, invRst1[0].GetUrl().GetParam(tagRouterTestDubboTag, "")) + invRst1 := tagRouter.Route(utils.ToBitmap(invokers), setUpAddrCache(tagRouter, invokers), &u1, inv) + assert.Equal(t, 1, len(invRst1.ToArray())) + assert.Equal(t, tagRouterTestHangZhou, invokers[invRst1.ToArray()[0]].GetUrl().GetParam(tagRouterTestDubboTag, "")) inv.SetAttachments(tagRouterTestDubboTag, tagRouterTestGuangZhou) - invRst2 := tagRouter.Route(invokers, &u1, inv) - assert.Equal(t, 0, len(invRst2)) + invRst2 := tagRouter.Route(utils.ToBitmap(invokers), setUpAddrCache(tagRouter, invokers), &u1, inv) + assert.Equal(t, 0, len(invRst2.ToArray())) inv.SetAttachments(tagRouterTestDubboForceTag, tagRouterTestFalse) inv.SetAttachments(tagRouterTestDubboTag, tagRouterTestGuangZhou) - invRst3 := tagRouter.Route(invokers, &u1, inv) - assert.Equal(t, 3, len(invRst3)) + invRst3 := tagRouter.Route(utils.ToBitmap(invokers), setUpAddrCache(tagRouter, invokers), &u1, inv) + assert.Equal(t, 3, len(invRst3.ToArray())) } func TestTagRouterRouteNoForce(t *testing.T) { @@ -148,15 +150,28 @@ func TestTagRouterRouteNoForce(t *testing.T) { invokers = append(invokers, inv2, inv3, inv4) inv := &invocation.RPCInvocation{} inv.SetAttachments(tagRouterTestDubboTag, tagRouterTestHangZhou) - invRst := tagRouter.Route(invokers, &u1, inv) - assert.Equal(t, 1, len(invRst)) - assert.Equal(t, tagRouterTestHangZhou, invRst[0].GetUrl().GetParam(tagRouterTestDubboTag, "")) + invRst := tagRouter.Route(utils.ToBitmap(invokers), setUpAddrCache(tagRouter, invokers), &u1, inv) + assert.Equal(t, 1, len(invRst.ToArray())) + assert.Equal(t, tagRouterTestHangZhou, invokers[invRst.ToArray()[0]].GetUrl().GetParam(tagRouterTestDubboTag, "")) inv.SetAttachments(tagRouterTestDubboTag, tagRouterTestGuangZhou) inv.SetAttachments(tagRouterTestDubboForceTag, tagRouterTestTrue) - invRst1 := tagRouter.Route(invokers, &u1, inv) - assert.Equal(t, 0, len(invRst1)) + invRst1 := tagRouter.Route(utils.ToBitmap(invokers), setUpAddrCache(tagRouter, invokers), &u1, inv) + assert.Equal(t, 0, len(invRst1.ToArray())) inv.SetAttachments(tagRouterTestDubboForceTag, tagRouterTestFalse) - invRst2 := tagRouter.Route(invokers, &u1, inv) - assert.Equal(t, 3, len(invRst2)) + invRst2 := tagRouter.Route(utils.ToBitmap(invokers), setUpAddrCache(tagRouter, invokers), &u1, inv) + assert.Equal(t, 3, len(invRst2.ToArray())) +} + +func setUpAddrCache(r router.Poolable, addrs []protocol.Invoker) *router.AddrCache { + pool, info := r.Pool(addrs) + cache := &router.AddrCache{ + Invokers: addrs, + AddrPool: make(map[string]router.RouterAddrPool), + AddrMeta: make(map[string]router.AddrMetadata), + } + + cache.AddrMeta[r.Name()] = info + cache.AddrPool[r.Name()] = pool + return cache } diff --git a/go.sum b/go.sum index 56e2c3210e90dadd821597bc34069878e292a633..74d640b196258d05af542822b47ab1a28bb6fc57 100644 --- a/go.sum +++ b/go.sum @@ -22,6 +22,8 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEV github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/RoaringBitmap/roaring v0.4.23 h1:gpyfd12QohbqhFO4NVDUdoPOCXsyahYRQhINmlHxKeo= +github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo= github.com/SAP/go-hdb v0.12.0 h1:5hBQZ2jjyZ268qjDmoDZJuCyLzR6oRLI60eYzmTW9m4= github.com/SAP/go-hdb v0.12.0/go.mod h1:etBT+FAi1t5k3K3tf5vQTnosgYmhDkRi8jEnQqCnxF0= github.com/SermoDigital/jose v0.0.0-20180104203859-803625baeddc h1:LkkwnbY+S8WmwkWq1SVyRWMH9nYWO1P5XN3OD1tts/w= @@ -136,6 +138,9 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2 h1:Ujru1hufTHVb++eG6OuNDKMxZnGIvF6o/u8q/8h2+I4= +github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= +github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/go-co-op/gocron v0.1.1 h1:OfDmkqkCguFtFMsm6Eaayci3DADLa8pXvdmOlPU/JcU= github.com/go-co-op/gocron v0.1.1/go.mod h1:Y9PWlYqDChf2Nbgg7kfS+ZsXHDTZbMZYPEQ0MILqH+M= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= @@ -391,6 +396,7 @@ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lN github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nacos-group/nacos-sdk-go v0.3.3-0.20200617023039-50c7537d6a5f h1:gid5/0AkHvINWK69Fgbidb3BVIXqlf1YEm7wO0NVPsw= @@ -429,6 +435,8 @@ github.com/patrickmn/go-cache v0.0.0-20180527043350-9f6ff22cfff8 h1:BR6MM54q4W9p github.com/patrickmn/go-cache v0.0.0-20180527043350-9f6ff22cfff8/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ= +github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -505,6 +513,8 @@ github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIU github.com/tent/http-link-go v0.0.0-20130702225549-ac974c61c2f9/go.mod h1:RHkNRtSLfOK7qBTHaeSX1D6BNpI3qw7NTxsmNr4RvN8= github.com/tevid/gohamcrest v1.1.1 h1:ou+xSqlIw1xfGTg1uq1nif/htZ2S3EzRqLm2BP+tYU0= github.com/tevid/gohamcrest v1.1.1/go.mod h1:3UvtWlqm8j5JbwYZh80D/PVBt0mJ1eJiYgZMibh0H/k= +github.com/tinylib/msgp v1.1.0 h1:9fQd+ICuRIu/ue4vxJZu6/LzxN0HwMds2nq/0cFvxHU= +github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 h1:kF/7m/ZU+0D4Jj5eZ41Zm3IH/J8OElK1Qtd7tVKAwLk= @@ -513,6 +523,7 @@ github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/vmware/govmomi v0.18.0 h1:f7QxSmP7meCtoAmiKZogvVbLInT+CZx6Px6K5rYsJZo= github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= +github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/zouyx/agollo v0.0.0-20191114083447-dde9fc9f35b8 h1:k8TV7Gz7cpWpOw/dz71fx8cCZdWoPuckHJ/wkJl+meg= diff --git a/registry/directory/directory.go b/registry/directory/directory.go index bdeacfe169a8d63f035e8d83070297d4a3933de0..0c59d5e6774d38e46ff6397e1767d246cf6260bd 100644 --- a/registry/directory/directory.go +++ b/registry/directory/directory.go @@ -18,11 +18,14 @@ package directory import ( - "github.com/apache/dubbo-go/cluster/router/chain" + "fmt" + "net/url" + "os" "sync" ) import ( + gxnet "github.com/dubbogo/gost/net" perrors "github.com/pkg/errors" "go.uber.org/atomic" ) @@ -30,6 +33,7 @@ import ( import ( "github.com/apache/dubbo-go/cluster" "github.com/apache/dubbo-go/cluster/directory" + "github.com/apache/dubbo-go/cluster/router/chain" "github.com/apache/dubbo-go/common" "github.com/apache/dubbo-go/common/constant" "github.com/apache/dubbo-go/common/extension" @@ -77,7 +81,9 @@ func NewRegistryDirectory(url *common.URL, registry registry.Registry) (cluster. registry: registry, } - if routerChain, err := chain.NewRouterChain(url.SubURL); err == nil { + dir.cacheOriginUrl = dir.getConsumerUrl(url.SubURL) + + if routerChain, err := chain.NewRouterChain(dir.cacheOriginUrl); err == nil { dir.BaseDirectory.SetRouterChain(routerChain) } else { logger.Warnf("fail to create router chain with url: %s, err is: %v", url.SubURL, err) @@ -223,9 +229,8 @@ func (dir *RegistryDirectory) cacheInvoker(url *common.URL) protocol.Invoker { if url == nil && dir.cacheOriginUrl != nil { url = dir.cacheOriginUrl - } else { - dir.cacheOriginUrl = url } + if url == nil { logger.Error("URL is nil ,pls check if service url is subscribe successfully!") return nil @@ -296,6 +301,24 @@ func (dir *RegistryDirectory) overrideUrl(targetUrl *common.URL) { doOverrideUrl(dir.referenceConfigurationListener.Configurators(), targetUrl) } +func (dir *RegistryDirectory) getConsumerUrl(c *common.URL) *common.URL { + processID := fmt.Sprintf("%d", os.Getpid()) + localIP, _ := gxnet.GetLocalIP() + + params := url.Values{} + c.RangeParams(func(key, value string) bool { + params.Add(key, value) + return true + }) + + params.Add("pid", processID) + params.Add("ip", localIP) + params.Add("protocol", c.Protocol) + + return common.NewURLWithOptions(common.WithProtocol("consumer"), common.WithIp(localIP), common.WithPath(c.Path), + common.WithParams(params)) +} + func doOverrideUrl(configurators []config_center.Configurator, targetUrl *common.URL) { for _, v := range configurators { v.Configure(targetUrl)