This is an automated email from the ASF dual-hosted git repository.

alexstocks pushed a commit to branch 1.5
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git


The following commit(s) were added to refs/heads/1.5 by this push:
     new 1f75d2d  Feature: Add some log when the router.Route return empty 
invokers (#1158)
1f75d2d is described below

commit 1f75d2d0107d3801e50f38ed1dcd0ce6e1689012
Author: cvictory <[email protected]>
AuthorDate: Sat May 15 11:41:57 2021 +0800

    Feature: Add some log when the router.Route return empty invokers (#1158)
    
    * fix sentinel cannot transport Context issue
    
    * optimize SentinelLogging reset
    
    * support print route info when there is no provider
    
    * revert to original version
---
 cluster/router/chain.go                           | 13 +++++
 cluster/router/chain/chain.go                     | 62 +++++++++++++++++++++++
 cluster/router/conncheck/conn_check_route.go      | 16 ++++++
 cluster/router/conncheck/conn_check_route_test.go | 50 ++++++++++++++++++
 cluster/router/router.go                          |  5 ++
 5 files changed, 146 insertions(+)

diff --git a/cluster/router/chain.go b/cluster/router/chain.go
index cb33cf9..3c6da4d 100644
--- a/cluster/router/chain.go
+++ b/cluster/router/chain.go
@@ -31,4 +31,17 @@ type Chain interface {
        AddRouters([]PriorityRouter)
        // GetNotifyChan get notify channel of this chain
        GetNotifyChan() chan struct{}
+       // Detect Route State
+       DetectRoute() (RouteSnapshot, error)
+}
+
+// RouteSnapshot is the snapshot of Route
+type RouteSnapshot struct {
+       Invokers       []protocol.Invoker
+       RouteSnapshots []string
+}
+
+// nolint
+func (rs *RouteSnapshot) AddRouteSnapshot(msg string) {
+       rs.RouteSnapshots = append(rs.RouteSnapshots, msg)
 }
diff --git a/cluster/router/chain/chain.go b/cluster/router/chain/chain.go
index 13cb1ff..a44ef10 100644
--- a/cluster/router/chain/chain.go
+++ b/cluster/router/chain/chain.go
@@ -18,7 +18,10 @@
 package chain
 
 import (
+       "reflect"
        "sort"
+       "strconv"
+       "strings"
        "sync"
        "time"
 )
@@ -73,6 +76,7 @@ func (c *RouterChain) GetNotifyChan() chan struct{} {
 func (c *RouterChain) Route(url *common.URL, invocation protocol.Invocation) 
[]protocol.Invoker {
        cache := c.loadCache()
        if cache == nil {
+               logger.Warnf("there is no cache invoker.")
                c.mutex.RLock()
                defer c.mutex.RUnlock()
                return c.invokers
@@ -84,6 +88,10 @@ func (c *RouterChain) Route(url *common.URL, invocation 
protocol.Invocation) []p
        }
 
        indexes := bitmap.ToArray()
+       // if the indexes is empty, print the routeSnapshot
+       if len(indexes) == 0 {
+               go c.printRouteSnapshot(cache, url, invocation)
+       }
        finalInvokers := make([]protocol.Invoker, len(indexes))
        for i, index := range indexes {
                finalInvokers[i] = cache.invokers[index]
@@ -121,6 +129,60 @@ func (c *RouterChain) SetInvokers(invokers 
[]protocol.Invoker) {
        }()
 }
 
+// Detect Route State
+func (c *RouterChain) DetectRoute() (router.RouteSnapshot, error) {
+       defer func() {
+               if err := recover(); err != nil {
+                       logger.Warnf("Detect Route fail. %+v", err)
+               }
+       }()
+       cache := c.loadCache()
+       if cache == nil {
+               c.mutex.RLock()
+               defer c.mutex.RUnlock()
+               return router.RouteSnapshot{Invokers: c.invokers}, nil
+       }
+       routers := c.copyRouters()
+       routeSnapshots := make([]string, 0, len(routers))
+       for _, r := range routers {
+               if v, ok := r.(router.PriorityRouterDetecter); ok {
+                       routeSnapshots = append(routeSnapshots, 
v.RouteSnapshot(cache))
+               }
+       }
+
+       return router.RouteSnapshot{Invokers: cache.invokers, RouteSnapshots: 
routeSnapshots}, nil
+}
+
+// nolint
+func (c *RouterChain) printRouteSnapshot(cache *InvokerCache, url *common.URL, 
invocation protocol.Invocation) {
+       defer func() {
+               if err := recover(); err != nil {
+                       logger.Warnf("print Route Snapshot fail. %+v", err)
+               }
+       }()
+
+       bitmap := cache.bitmap
+
+       logger.Warnf("start:print the route info:%s", url.ServiceKey())
+       for _, r := range c.copyRouters() {
+               bitmap = r.Route(bitmap, cache, url, invocation)
+               routeSnapshotSb := strings.Builder{}
+               routeSnapshotSb.WriteString(reflect.TypeOf(r).String())
+               routeSnapshotSb.WriteString(", count:")
+               
routeSnapshotSb.WriteString(strconv.FormatUint(bitmap.GetCardinality(), 10))
+               routeSnapshotSb.WriteString(bitmap.String())
+               logger.Warn(routeSnapshotSb.String())
+       }
+
+       if routerSnapshot, err := c.DetectRoute(); err == nil {
+               logger.Warnf("the size of invokers:%d", 
len(routerSnapshot.Invokers))
+               for _, item := range routerSnapshot.RouteSnapshots {
+                       logger.Warn(item)
+               }
+       }
+       logger.Warnf("end: print the route info:%s", url.ServiceKey())
+}
+
 // loop listens on events to update the address cache  when it receives 
notification
 // from address update,
 func (c *RouterChain) loop() {
diff --git a/cluster/router/conncheck/conn_check_route.go 
b/cluster/router/conncheck/conn_check_route.go
index 97f049d..6518dec 100644
--- a/cluster/router/conncheck/conn_check_route.go
+++ b/cluster/router/conncheck/conn_check_route.go
@@ -19,6 +19,8 @@ package conncheck
 
 import (
        "github.com/RoaringBitmap/roaring"
+       "strconv"
+       "strings"
 )
 
 import (
@@ -67,6 +69,20 @@ func (r *ConnCheckRouter) Route(invokers *roaring.Bitmap, 
cache router.Cache, ur
        return healthyInvokers
 }
 
+func (r *ConnCheckRouter) RouteSnapshot(cache router.Cache) string {
+       addrPool := cache.FindAddrPool(r)
+       // Add healthy invoker to the list
+       healthBit := addrPool[connHealthy]
+       sb := strings.Builder{}
+       sb.WriteString(r.Name())
+       sb.WriteString(" -> ")
+       sb.WriteString("Count:")
+       sb.WriteString(strconv.FormatUint(healthBit.GetCardinality(), 10))
+       sb.WriteString(" ")
+       sb.WriteString(healthBit.String())
+       return sb.String()
+}
+
 // Pool separates healthy invokers from others.
 func (r *ConnCheckRouter) Pool(invokers []protocol.Invoker) (router.AddrPool, 
router.AddrMetadata) {
        rb := make(router.AddrPool, 8)
diff --git a/cluster/router/conncheck/conn_check_route_test.go 
b/cluster/router/conncheck/conn_check_route_test.go
index fec7331..5f78722 100644
--- a/cluster/router/conncheck/conn_check_route_test.go
+++ b/cluster/router/conncheck/conn_check_route_test.go
@@ -102,6 +102,56 @@ func TestRecovery(t *testing.T) {
        assert.Equal(t, len(protocol.GetBlackListInvokers(16)), 0)
 }
 
+func TestPrintlnConnCheckRouterRoute(t *testing.T) {
+
+       connCheck1001URL2 := 
"dubbo://192.168.10.1/com.ikurento.user.UserNoProvider"
+       connCheckRouteUrl2Format := 
"dubbo://%s:20000/com.ikurento.user.UserNoProvider"
+
+       defer protocol.CleanAllStatus()
+       notify := make(chan struct{})
+       go func() {
+               for range notify {
+               }
+       }()
+       consumerURL, _ := common.NewURL(connCheck1001URL2)
+       url1, _ := common.NewURL(fmt.Sprintf(connCheckRouteUrl2Format, 
connCheckRoute1010IP))
+       url2, _ := common.NewURL(fmt.Sprintf(connCheckRouteUrl2Format, 
connCheckRoute1011IP))
+       url3, _ := common.NewURL(fmt.Sprintf(connCheckRouteUrl2Format, 
connCheckRoute1012IP))
+       hcr, _ := NewConnCheckRouter(consumerURL, notify)
+
+       var invokers []protocol.Invoker
+       invoker1 := NewMockInvoker(url1)
+       invoker2 := NewMockInvoker(url2)
+       invoker3 := NewMockInvoker(url3)
+       protocol.SetInvokerUnhealthyStatus(invoker1)
+       protocol.SetInvokerUnhealthyStatus(invoker2)
+       protocol.SetInvokerUnhealthyStatus(invoker3)
+
+       invokers = append(invokers, invoker1, invoker2, invoker3)
+       inv := invocation.NewRPCInvocation(connCheckRouteMethodNameTest, nil, 
nil)
+       cache := setUpAddrCache(hcr.(*ConnCheckRouter), invokers)
+       res := hcr.Route(utils.ToBitmap(invokers), cache, consumerURL, inv)
+
+       // now  invoker3 is healthy
+       assert.True(t, len(res.ToArray()) == 3)
+       var (
+               router *ConnCheckRouter
+               ok     bool
+       )
+       router, ok = hcr.(*ConnCheckRouter)
+       assert.True(t, ok)
+       assert.Equal(t, router.RouteSnapshot(cache), "conn-check-router -> 
Count:0 {}")
+
+       // check blacklist remove
+       protocol.RemoveInvokerUnhealthyStatus(invoker1)
+       protocol.RemoveInvokerUnhealthyStatus(invoker3)
+       cache = setUpAddrCache(hcr.(*ConnCheckRouter), invokers)
+       res = hcr.Route(utils.ToBitmap(invokers), cache, consumerURL, inv)
+       // now  invoker3 invoker1 is healthy
+       assert.True(t, len(res.ToArray()) == 2)
+       assert.Equal(t, router.RouteSnapshot(cache), "conn-check-router -> 
Count:2 {0,2}")
+}
+
 func setUpAddrCache(r router.Poolable, addrs []protocol.Invoker) router.Cache {
        pool, info := r.Pool(addrs)
        cache := chain.BuildCache(addrs)
diff --git a/cluster/router/router.go b/cluster/router/router.go
index 1d71554..93b0484 100644
--- a/cluster/router/router.go
+++ b/cluster/router/router.go
@@ -56,6 +56,11 @@ type PriorityRouter interface {
        Priority() int64
 }
 
+// PriorityRouterDetecter detect the router
+type PriorityRouterDetecter interface {
+       RouteSnapshot(cache Cache) string
+}
+
 // Poolable caches address pool and address metadata for a router instance 
which will be used later in Router's Route.
 type Poolable interface {
        // Pool created address pool and address metadata from the invokers.

Reply via email to