You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by as...@apache.org on 2017/12/26 07:55:31 UTC

[incubator-servicecomb-service-center] branch master updated: SCB-127 The consumer micro-service can discovery SC instances. (#224)

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

asifdxtreme pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-service-center.git


The following commit(s) were added to refs/heads/master by this push:
     new 7bc2e8f  SCB-127 The consumer micro-service can discovery SC instances. (#224)
7bc2e8f is described below

commit 7bc2e8f711d8f3ce16ad27762426373997ae62a0
Author: little-cui <su...@qq.com>
AuthorDate: Tue Dec 26 15:55:29 2017 +0800

    SCB-127 The consumer micro-service can discovery SC instances. (#224)
    
    * Use the event driven design in dep-rules.
    
    * New feature: Auto compact etcd data.
    
    * Async handle add or update dependency requests.
    
    * Use the event driven design in dep-rules.
    
    * Async handle add or update dependency requests.
    
    * Use the event driven design in dep-rules.
    
    * Bug fix: Auto compact never stop.
    
    * Update imports.
    
    * Fix UT/IT failure.
    
    * New feature: the consumer micro-service can discovery SC instances.
    
    * Bug fix: Dead lock in mux.Try().
    
    * Optimize dependency.go
    
    * Fix some bugs in dependency.go
    
    * Fix UT failure.
---
 integration/microservices_test.go                  |   3 +
 pkg/etcdsync/mutex.go                              |  45 +-
 pkg/etcdsync/mutex_test.go                         |  12 +-
 pkg/util/goroutines.go                             |   1 +
 pkg/util/util.go                                   |  24 +
 server/core/backend/store/cacher.go                |   4 +-
 server/core/backend/store/event.go                 |   1 +
 server/core/backend/store/indexer.go               |  18 +-
 server/core/backend/store/opt.go                   |   2 +-
 server/core/backend/store/store.go                 |  67 +--
 server/core/key_generator.go                       |  18 +
 server/core/microservice.go                        |  12 +-
 server/core/proto/services.go                      |  31 +-
 server/core/proto/services.pb.go                   | 515 ++++++++++-----------
 server/core/proto/services.proto                   |  14 +-
 server/govern/service.go                           |   2 +-
 server/handler/context/context.go                  |   2 +
 server/handler/context/v3.go                       |  19 +-
 server/handler/context/v4.go                       |  42 +-
 server/infra/registry/registry.go                  |  32 +-
 server/mux/mux.go                                  |  11 +-
 server/plugin/infra/registry/buildin/buildin.go    |   3 +
 .../infra/registry/embededetcd/embededetcd.go      |  31 +-
 server/plugin/infra/registry/etcd/etcd.go          |  88 ++--
 server/server.go                                   |  41 +-
 server/service/concurrent_test.go                  |   6 +-
 server/service/event/dependency_event_handler.go   | 202 ++++++++
 server/service/event/event.go                      |   1 +
 server/service/event/instance_event_handler.go     |   2 +-
 server/service/event/rule_event_handler.go         |   2 +-
 server/service/event/service_event_handler.go      |  15 +-
 server/service/event/tag_event_handler.go          |   2 +-
 server/service/instances.go                        |  51 +-
 server/service/microservices.go                    |   6 +-
 server/service/microservices_test.go               |   2 +
 server/service/service_dependency.go               |  59 +--
 server/service/service_dependency_test.go          |  41 +-
 server/service/util/dependency.go                  | 305 ++++++------
 server/service/util/dependency_test.go             |  20 +-
 server/service/util/instance_util.go               |   4 +-
 server/service/util/instance_util_test.go          |   2 +-
 server/service/util/rule_util.go                   |  17 +-
 server/service/util/rule_util_test.go              |  38 +-
 43 files changed, 1072 insertions(+), 741 deletions(-)

diff --git a/integration/microservices_test.go b/integration/microservices_test.go
index a5f1657..9544580 100644
--- a/integration/microservices_test.go
+++ b/integration/microservices_test.go
@@ -30,6 +30,7 @@ import (
 	"strconv"
 	"strings"
 	"testing"
+	"time"
 )
 
 var serviceName = ""
@@ -409,6 +410,8 @@ var _ = Describe("MicroService Api Test", func() {
 					// Validate the dependency creation
 					Expect(resp.StatusCode).To(Equal(http.StatusOK))
 
+					<-time.After(time.Second)
+
 					//Get Provider by ConsumerID
 					url := strings.Replace(GETCONPRODEPENDENCY, ":consumerId", consumerServiceID, 1)
 					req, _ = http.NewRequest(GET, SCURL+url, nil)
diff --git a/pkg/etcdsync/mutex.go b/pkg/etcdsync/mutex.go
index 5a722ca..0ef019f 100644
--- a/pkg/etcdsync/mutex.go
+++ b/pkg/etcdsync/mutex.go
@@ -36,7 +36,7 @@ const (
 )
 
 // A Mutex is a mutual exclusion lock which is distributed across a cluster.
-type LockerFactory struct {
+type DLockFactory struct {
 	key    string
 	ctx    context.Context
 	ttl    int64
@@ -44,13 +44,13 @@ type LockerFactory struct {
 	logger io.Writer
 }
 
-type Locker struct {
-	builder *LockerFactory
+type DLock struct {
+	builder *DLockFactory
 	id      string
 }
 
 var (
-	globalMap map[string]*LockerFactory
+	globalMap map[string]*DLockFactory
 	globalMux sync.Mutex
 	IsDebug   bool
 	hostname  string
@@ -58,7 +58,7 @@ var (
 )
 
 func init() {
-	globalMap = make(map[string]*LockerFactory)
+	globalMap = make(map[string]*DLockFactory)
 	IsDebug = false
 
 	var err error
@@ -72,7 +72,7 @@ func init() {
 // New creates a Mutex with the given key which must be the same
 // across the cluster nodes.
 // machines are the ectd cluster addresses
-func New(key string, ttl int64) *LockerFactory {
+func NewLockFactory(key string, ttl int64) *DLockFactory {
 	if len(key) == 0 {
 		return nil
 	}
@@ -80,7 +80,7 @@ func New(key string, ttl int64) *LockerFactory {
 		ttl = defaultTTL
 	}
 
-	return &LockerFactory{
+	return &DLockFactory{
 		key:   key,
 		ctx:   context.Background(),
 		ttl:   ttl,
@@ -90,21 +90,27 @@ func New(key string, ttl int64) *LockerFactory {
 
 // Lock locks m.
 // If the lock is already in use, the calling goroutine
-// blocks until the mutex is available.
-func (m *LockerFactory) Lock() (l *Locker, err error) {
+// blocks until the mutex is available. Flag wait is false,
+// this function is non-block when lock exist.
+func (m *DLockFactory) NewDLock(wait bool) (l *DLock, err error) {
 	if !IsDebug {
 		m.mutex.Lock()
 	}
-	l = &Locker{
+	l = &DLock{
 		builder: m,
 		id:      fmt.Sprintf("%v-%v-%v", hostname, pid, time.Now().Format("20060102-15:04:05.999999999")),
 	}
 	for try := 1; try <= defaultTry; try++ {
-		err = l.Lock()
+		err = l.Lock(wait)
 		if err == nil {
 			return l, nil
 		}
 
+		if !wait {
+			l, err = nil, nil
+			break
+		}
+
 		if try <= defaultTry {
 			util.Logger().Warnf(err, "Try to lock key %s again, id=%s", m.key, l.id)
 		} else {
@@ -117,11 +123,11 @@ func (m *LockerFactory) Lock() (l *Locker, err error) {
 	return l, err
 }
 
-func (m *Locker) ID() string {
+func (m *DLock) ID() string {
 	return m.id
 }
 
-func (m *Locker) Lock() error {
+func (m *DLock) Lock(wait bool) error {
 	opts := []registry.PluginOpOption{
 		registry.WithStrKey(m.builder.key),
 		registry.WithStrValue(m.id)}
@@ -142,6 +148,11 @@ func (m *Locker) Lock() error {
 			util.Logger().Infof("Create Lock OK, key=%s, id=%s", m.builder.key, m.id)
 			return nil
 		}
+
+		if !wait {
+			return fmt.Errorf("Key %s is locked by id=%s", m.builder.key, m.id)
+		}
+
 		util.Logger().Warnf(err, "Key %s is locked, waiting for other node releases it, id=%s", m.builder.key, m.id)
 
 		ctx, cancel := context.WithTimeout(m.builder.ctx, defaultTTL*time.Second)
@@ -177,7 +188,7 @@ func (m *Locker) Lock() error {
 // A locked Mutex is not associated with a particular goroutine.
 // It is allowed for one goroutine to lock a Mutex and then
 // arrange for another goroutine to unlock it.
-func (m *Locker) Unlock() (err error) {
+func (m *DLock) Unlock() (err error) {
 	opts := []registry.PluginOpOption{
 		registry.DEL,
 		registry.WithStrKey(m.builder.key)}
@@ -206,13 +217,13 @@ func (m *Locker) Unlock() (err error) {
 	return err
 }
 
-func Lock(key string) (*Locker, error) {
+func Lock(key string, wait bool) (*DLock, error) {
 	globalMux.Lock()
 	lc, ok := globalMap[key]
 	if !ok {
-		lc = New(fmt.Sprintf("%s%s", ROOT_PATH, key), -1)
+		lc = NewLockFactory(fmt.Sprintf("%s%s", ROOT_PATH, key), -1)
 		globalMap[key] = lc
 	}
 	globalMux.Unlock()
-	return lc.Lock()
+	return lc.NewDLock(wait)
 }
diff --git a/pkg/etcdsync/mutex_test.go b/pkg/etcdsync/mutex_test.go
index d8da891..23a333b 100644
--- a/pkg/etcdsync/mutex_test.go
+++ b/pkg/etcdsync/mutex_test.go
@@ -26,21 +26,21 @@ import (
 var _ = Describe("Mutex", func() {
 	Context("normal", func() {
 		It("TestLockTimeout", func() {
-			m1 := New("key1", 10)
-			m2 := New("key1", 2)
-			m1.Lock()
+			m1 := NewLockFactory("key1", 10)
+			m2 := NewLockFactory("key1", 2)
+			m1.NewDLock(true)
 			fmt.Println("UT===================m1 locked")
 			ch := make(chan bool)
 			go func() {
-				l, _ := m2.Lock()
+				l, _ := m2.NewDLock(true)
 				fmt.Println("UT===================m2 locked")
 				l.Unlock()
 				ch <- true
 			}()
 			<-ch
 			fmt.Println("lock m1 timeout")
-			m3 := New("key1", 2)
-			l, _ := m3.Lock()
+			m3 := NewLockFactory("key1", 2)
+			l, _ := m3.NewDLock(true)
 			fmt.Println("UT===================m3 locked")
 			l.Unlock()
 
diff --git a/pkg/util/goroutines.go b/pkg/util/goroutines.go
index 5a3d3f8..a021f52 100644
--- a/pkg/util/goroutines.go
+++ b/pkg/util/goroutines.go
@@ -77,6 +77,7 @@ func GoInit() {
 
 func GoCloseAndWait() {
 	defaultGo.Close(true)
+	Logger().Debugf("all goroutines quit normally")
 }
 
 func NewGo(stopCh chan struct{}) *GoRoutine {
diff --git a/pkg/util/util.go b/pkg/util/util.go
index 2f2ac8c..eea2da3 100644
--- a/pkg/util/util.go
+++ b/pkg/util/util.go
@@ -149,6 +149,14 @@ func ParseDomainProject(ctx context.Context) string {
 	return ParseDomain(ctx) + "/" + ParseProject(ctx)
 }
 
+func ParseTargetDomainProject(ctx context.Context) string {
+	domain := ParseTargetDomain(ctx)
+	if len(domain) == 0 {
+		return ParseDomainProject(ctx)
+	}
+	return domain + "/" + ParseTargetProject(ctx)
+}
+
 func ParseDomain(ctx context.Context) string {
 	v, ok := FromContext(ctx, "domain").(string)
 	if !ok {
@@ -157,6 +165,14 @@ func ParseDomain(ctx context.Context) string {
 	return v
 }
 
+func ParseTargetDomain(ctx context.Context) string {
+	v, ok := FromContext(ctx, "target-domain").(string)
+	if !ok {
+		return ""
+	}
+	return v
+}
+
 func ParseProject(ctx context.Context) string {
 	v, ok := FromContext(ctx, "project").(string)
 	if !ok {
@@ -165,6 +181,14 @@ func ParseProject(ctx context.Context) string {
 	return v
 }
 
+func ParseTargetProject(ctx context.Context) string {
+	v, ok := FromContext(ctx, "target-project").(string)
+	if !ok {
+		return ""
+	}
+	return v
+}
+
 func GetIPFromContext(ctx context.Context) string {
 	v, ok := FromContext(ctx, "x-remote-ip").(string)
 	if !ok {
diff --git a/server/core/backend/store/cacher.go b/server/core/backend/store/cacher.go
index d698e23..b1ab867 100644
--- a/server/core/backend/store/cacher.go
+++ b/server/core/backend/store/cacher.go
@@ -430,7 +430,7 @@ func (c *KvCacher) onEvents(evts []*Event) {
 
 		switch evt.Type {
 		case proto.EVT_CREATE, proto.EVT_UPDATE:
-			util.Logger().Debugf("sync %s event and notify watcher, cache key %s, %+v", evt.Type, key, kv)
+			util.Logger().Debugf("sync %s event and notify watcher, cache %v", evt.Type, kv)
 
 			t := evt.Type
 			if !ok && evt.Type != proto.EVT_CREATE {
@@ -458,7 +458,7 @@ func (c *KvCacher) onEvents(evts []*Event) {
 				continue
 			}
 
-			util.Logger().Debugf("sync %s event and notify watcher, remove key %s, %+v", evt.Type, key, kv)
+			util.Logger().Debugf("sync %s event and notify watcher, remove cache %v", evt.Type, kv)
 			delete(store, key)
 			kvEvts[idx] = &KvEvent{
 				Revision: evt.Revision,
diff --git a/server/core/backend/store/event.go b/server/core/backend/store/event.go
index 91c6f89..9991f3d 100644
--- a/server/core/backend/store/event.go
+++ b/server/core/backend/store/event.go
@@ -71,6 +71,7 @@ func EventProxy(t StoreType) *KvEventProxy {
 	return evtProxies[t]
 }
 
+// the event handler/func must be good performance, or will block the event bus.
 func AddEventHandleFunc(t StoreType, f KvEventFunc) {
 	EventProxy(t).AddHandleFunc(f)
 }
diff --git a/server/core/backend/store/indexer.go b/server/core/backend/store/indexer.go
index 3cfc1f8..65349bd 100644
--- a/server/core/backend/store/indexer.go
+++ b/server/core/backend/store/indexer.go
@@ -157,7 +157,7 @@ func (i *Indexer) searchPrefixKeyWithCache(ctx context.Context, op registry.Plug
 		kvs[idx] = c.(*mvccpb.KeyValue)
 		idx++
 	}
-	util.LogNilOrWarnf(t, "too long to copy data[%d] from cache with prefix %s", idx, prefix)
+	util.LogNilOrWarnf(t, "too long to copy data[%d] from cache[%d] with prefix %s", idx, len(i.prefixIndex), prefix)
 
 	resp.Kvs = kvs[:idx]
 	return resp, nil
@@ -196,6 +196,7 @@ func (i *Indexer) buildIndex() {
 				if !ok {
 					return
 				}
+				t := time.Now()
 				key := util.BytesToStringWithNoCopy(evt.KV.Key)
 				prefix := key[:strings.LastIndex(key[:len(key)-1], "/")+1]
 
@@ -208,6 +209,8 @@ func (i *Indexer) buildIndex() {
 				}
 				i.prefixLock.Unlock()
 
+				util.LogNilOrWarnf(t, "too long to rebuild(action: %s) index[%d], key is %s",
+					evt.Action, key, len(i.prefixIndex))
 			}
 		}
 		util.Logger().Debugf("build %s index goroutine is stopped", i.cacheType)
@@ -235,10 +238,10 @@ func (i *Indexer) getPrefixKey(arr *[]string, prefix string) (count int) {
 			}
 			break
 		}
-		count += n
+		/*count += n
 		if arr != nil {
 			*arr = append(*arr, *childs...)
-		}
+		}*/
 	}
 	return count
 }
@@ -268,11 +271,18 @@ func (i *Indexer) deletePrefixKey(prefix, key string) {
 	if !ok {
 		return
 	}
-
+	// remove child
 	for k := range i.prefixIndex[key] {
 		i.deletePrefixKey(key, k)
 	}
+
 	delete(m, key)
+
+	// remove parent which has no child
+	if len(m) == 0 {
+		delete(i.prefixIndex, prefix)
+		i.deletePrefixKey(prefix[:strings.LastIndex(prefix[:len(prefix)-1], "/")+1], prefix)
+	}
 }
 
 func (i *Indexer) Run() {
diff --git a/server/core/backend/store/opt.go b/server/core/backend/store/opt.go
index 6aa3bbd..252f244 100644
--- a/server/core/backend/store/opt.go
+++ b/server/core/backend/store/opt.go
@@ -24,7 +24,7 @@ import (
 const (
 	DEFAULT_MAX_NO_EVENT_INTERVAL     = 1 // TODO it should be set to 1 for prevent etcd data is lost accidentally.
 	DEFAULT_LISTWATCH_TIMEOUT         = 30 * time.Second
-	DEFAULT_SELF_PRESERVATION_PERCENT = 0.85
+	DEFAULT_SELF_PRESERVATION_PERCENT = 0.8
 )
 
 type KvCacherCfg struct {
diff --git a/server/core/backend/store/store.go b/server/core/backend/store/store.go
index 5311d60..d2f89e7 100644
--- a/server/core/backend/store/store.go
+++ b/server/core/backend/store/store.go
@@ -38,6 +38,7 @@ const (
 	RULE_INDEX
 	DEPENDENCY
 	DEPENDENCY_RULE
+	DEPENDENCY_QUEUE
 	SCHEMA // big data should not be stored in memory.
 	SCHEMA_SUMMARY
 	INSTANCE
@@ -49,39 +50,41 @@ const (
 const TIME_FORMAT = "15:04:05.000"
 
 var TypeNames = []string{
-	SERVICE:         "SERVICE",
-	INSTANCE:        "INSTANCE",
-	DOMAIN:          "DOMAIN",
-	SCHEMA:          "SCHEMA",
-	SCHEMA_SUMMARY:  "SCHEMA_SUMMARY",
-	RULE:            "RULE",
-	LEASE:           "LEASE",
-	SERVICE_INDEX:   "SERVICE_INDEX",
-	SERVICE_ALIAS:   "SERVICE_ALIAS",
-	SERVICE_TAG:     "SERVICE_TAG",
-	RULE_INDEX:      "RULE_INDEX",
-	DEPENDENCY:      "DEPENDENCY",
-	DEPENDENCY_RULE: "DEPENDENCY_RULE",
-	PROJECT:         "PROJECT",
-	ENDPOINTS:       "ENDPOINTS",
+	SERVICE:          "SERVICE",
+	INSTANCE:         "INSTANCE",
+	DOMAIN:           "DOMAIN",
+	SCHEMA:           "SCHEMA",
+	SCHEMA_SUMMARY:   "SCHEMA_SUMMARY",
+	RULE:             "RULE",
+	LEASE:            "LEASE",
+	SERVICE_INDEX:    "SERVICE_INDEX",
+	SERVICE_ALIAS:    "SERVICE_ALIAS",
+	SERVICE_TAG:      "SERVICE_TAG",
+	RULE_INDEX:       "RULE_INDEX",
+	DEPENDENCY:       "DEPENDENCY",
+	DEPENDENCY_RULE:  "DEPENDENCY_RULE",
+	DEPENDENCY_QUEUE: "DEPENDENCY_QUEUE",
+	PROJECT:          "PROJECT",
+	ENDPOINTS:        "ENDPOINTS",
 }
 
 var TypeRoots = map[StoreType]string{
-	SERVICE:         apt.GetServiceRootKey(""),
-	INSTANCE:        apt.GetInstanceRootKey(""),
-	DOMAIN:          apt.GetDomainRootKey() + "/",
-	SCHEMA:          apt.GetServiceSchemaRootKey(""),
-	SCHEMA_SUMMARY:  apt.GetServiceSchemaSummaryRootKey(""),
-	RULE:            apt.GetServiceRuleRootKey(""),
-	LEASE:           apt.GetInstanceLeaseRootKey(""),
-	SERVICE_INDEX:   apt.GetServiceIndexRootKey(""),
-	SERVICE_ALIAS:   apt.GetServiceAliasRootKey(""),
-	SERVICE_TAG:     apt.GetServiceTagRootKey(""),
-	RULE_INDEX:      apt.GetServiceRuleIndexRootKey(""),
-	DEPENDENCY:      apt.GetServiceDependencyRootKey(""),
-	DEPENDENCY_RULE: apt.GetServiceDependencyRuleRootKey(""),
-	PROJECT:         apt.GetProjectRootKey(""),
-	ENDPOINTS:       apt.GetEndpointsRootKey(""),
+	SERVICE:          apt.GetServiceRootKey(""),
+	INSTANCE:         apt.GetInstanceRootKey(""),
+	DOMAIN:           apt.GetDomainRootKey() + "/",
+	SCHEMA:           apt.GetServiceSchemaRootKey(""),
+	SCHEMA_SUMMARY:   apt.GetServiceSchemaSummaryRootKey(""),
+	RULE:             apt.GetServiceRuleRootKey(""),
+	LEASE:            apt.GetInstanceLeaseRootKey(""),
+	SERVICE_INDEX:    apt.GetServiceIndexRootKey(""),
+	SERVICE_ALIAS:    apt.GetServiceAliasRootKey(""),
+	SERVICE_TAG:      apt.GetServiceTagRootKey(""),
+	RULE_INDEX:       apt.GetServiceRuleIndexRootKey(""),
+	DEPENDENCY:       apt.GetServiceDependencyRootKey(""),
+	DEPENDENCY_RULE:  apt.GetServiceDependencyRuleRootKey(""),
+	DEPENDENCY_QUEUE: apt.GetServiceDependencyQueueRootKey(""),
+	PROJECT:          apt.GetProjectRootKey(""),
+	ENDPOINTS:        apt.GetEndpointsRootKey(""),
 }
 
 var store = &KvStore{}
@@ -276,6 +279,10 @@ func (s *KvStore) DependencyRule() *Indexer {
 	return s.indexers[DEPENDENCY_RULE]
 }
 
+func (s *KvStore) DependencyQueue() *Indexer {
+	return s.indexers[DEPENDENCY_QUEUE]
+}
+
 func (s *KvStore) Domain() *Indexer {
 	return s.indexers[DOMAIN]
 }
diff --git a/server/core/key_generator.go b/server/core/key_generator.go
index 959dbc3..73775e8 100644
--- a/server/core/key_generator.go
+++ b/server/core/key_generator.go
@@ -40,6 +40,7 @@ const (
 	REGISTRY_LEASE_KEY          = "leases"
 	REGISTRY_DEPENDENCY_KEY     = "deps"
 	REGISTRY_DEPS_RULE_KEY      = "dep-rules"
+	REGISTRY_DEPS_QUEUE_KEY     = "dep-queue"
 	REGISTRY_METRICS_KEY        = "metrics"
 	ENDPOINTS_ROOT_KEY          = "eps"
 )
@@ -300,6 +301,15 @@ func GetServiceDependencyRuleRootKey(domainProject string) string {
 	}, "/")
 }
 
+func GetServiceDependencyQueueRootKey(domainProject string) string {
+	return util.StringJoin([]string{
+		GetRootKey(),
+		REGISTRY_SERVICE_KEY,
+		REGISTRY_DEPS_QUEUE_KEY,
+		domainProject,
+	}, "/")
+}
+
 func GenerateConsumerDependencyKey(domainProject string, consumerId string, providerId string) string {
 	return GenerateServiceDependencyKey("c", domainProject, consumerId, providerId)
 }
@@ -317,6 +327,14 @@ func GenerateProviderDependencyKey(domainProject string, providerId string, cons
 	return GenerateServiceDependencyKey("p", domainProject, providerId, consumerId)
 }
 
+func GenerateConsumerDependencyQueueKey(domainProject, consumerId, uuid string) string {
+	return util.StringJoin([]string{
+		GetServiceDependencyQueueRootKey(domainProject),
+		consumerId,
+		uuid,
+	}, "/")
+}
+
 func GetServiceDependencyRootKey(domainProject string) string {
 	return util.StringJoin([]string{
 		GetRootKey(),
diff --git a/server/core/microservice.go b/server/core/microservice.go
index 7536cc8..d42ec00 100644
--- a/server/core/microservice.go
+++ b/server/core/microservice.go
@@ -80,11 +80,18 @@ func IsDefaultDomainProject(domainProject string) bool {
 	return domainProject == util.StringJoin([]string{REGISTRY_DOMAIN, REGISTRY_PROJECT}, "/")
 }
 
-func IsSCKey(key *pb.MicroServiceKey) bool {
+func IsShared(key *pb.MicroServiceKey) bool {
 	if !IsDefaultDomainProject(key.Tenant) {
 		return false
 	}
-	return key.AppId == Service.AppId && key.ServiceName == Service.ServiceName
+	return key.AppId == Service.AppId
+}
+
+func IsSCKey(key *pb.MicroServiceKey) bool {
+	if !IsShared(key) {
+		return false
+	}
+	return key.ServiceName == Service.ServiceName
 }
 
 func IsSCInstance(ctx context.Context) bool {
@@ -93,6 +100,7 @@ func IsSCInstance(ctx context.Context) bool {
 	}
 	return false
 }
+
 func GetExistenceRequest() *pb.GetExistenceRequest {
 	return &pb.GetExistenceRequest{
 		Type:        pb.EXISTENCE_MS,
diff --git a/server/core/proto/services.go b/server/core/proto/services.go
index e9eeadd..23ba8b4 100644
--- a/server/core/proto/services.go
+++ b/server/core/proto/services.go
@@ -221,7 +221,7 @@ func GetInfoFromSvcIndexKV(kv *mvccpb.KeyValue) (key *MicroServiceKey, data []by
 func GetInfoFromSchemaSummaryKV(kv *mvccpb.KeyValue) (schemaId string, data []byte) {
 	keys, data := KvToResponse(kv)
 	l := len(keys)
-	if l < 2 {
+	if l < 1 {
 		return
 	}
 
@@ -231,25 +231,31 @@ func GetInfoFromSchemaSummaryKV(kv *mvccpb.KeyValue) (schemaId string, data []by
 func GetInfoFromSchemaKV(kv *mvccpb.KeyValue) (schemaId string, data []byte) {
 	keys, data := KvToResponse(kv)
 	l := len(keys)
-	if l < 2 {
+	if l < 1 {
 		return
 	}
 
 	return keys[l-1], data
 }
 
-func DependenciesToKeys(in []*DependencyKey, domainProject string) []*MicroServiceKey {
-	rst := []*MicroServiceKey{}
+func GetInfoFromDependencyQueueKV(kv *mvccpb.KeyValue) (consumerId, domainProject string, data []byte) {
+	keys, data := KvToResponse(kv)
+	l := len(keys)
+	if l < 4 {
+		return
+	}
+	consumerId = keys[l-2]
+	domainProject = fmt.Sprintf("%s/%s", keys[l-4], keys[l-3])
+	return
+}
+
+func DependenciesToKeys(in []*MicroServiceKey, domainProject string) []*MicroServiceKey {
 	for _, value := range in {
-		rst = append(rst, &MicroServiceKey{
-			Tenant:      domainProject,
-			Environment: value.Environment,
-			AppId:       value.AppId,
-			ServiceName: value.ServiceName,
-			Version:     value.Version,
-		})
+		if len(value.Tenant) == 0 {
+			value.Tenant = domainProject
+		}
 	}
-	return rst
+	return in
 }
 
 func MicroServiceToKey(domainProject string, in *MicroService) *MicroServiceKey {
@@ -258,6 +264,7 @@ func MicroServiceToKey(domainProject string, in *MicroService) *MicroServiceKey
 		Environment: in.Environment,
 		AppId:       in.AppId,
 		ServiceName: in.ServiceName,
+		Alias:       in.Alias,
 		Version:     in.Version,
 	}
 }
diff --git a/server/core/proto/services.pb.go b/server/core/proto/services.pb.go
index 63099d0..f490822 100644
--- a/server/core/proto/services.pb.go
+++ b/server/core/proto/services.pb.go
@@ -89,7 +89,6 @@ It has these top-level messages:
 	AddDependenciesRequest
 	AddDependenciesResponse
 	CreateDependenciesRequest
-	DependencyKey
 	ConsumerDependency
 	CreateDependenciesResponse
 	GetDependenciesRequest
@@ -529,7 +528,7 @@ type MicroService struct {
 	Status       string             `protobuf:"bytes,8,opt,name=status" json:"status,omitempty"`
 	Properties   map[string]string  `protobuf:"bytes,9,rep,name=properties" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
 	Timestamp    string             `protobuf:"bytes,11,opt,name=timestamp" json:"timestamp,omitempty"`
-	Providers    []*DependencyKey   `protobuf:"bytes,12,rep,name=providers" json:"providers,omitempty"`
+	Providers    []*MicroServiceKey `protobuf:"bytes,12,rep,name=providers" json:"providers,omitempty"`
 	Alias        string             `protobuf:"bytes,13,opt,name=alias" json:"alias,omitempty"`
 	LBStrategy   map[string]string  `protobuf:"bytes,14,rep,name=LBStrategy" json:"LBStrategy,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
 	ModTimestamp string             `protobuf:"bytes,15,opt,name=modTimestamp" json:"modTimestamp,omitempty"`
@@ -620,7 +619,7 @@ func (m *MicroService) GetTimestamp() string {
 	return ""
 }
 
-func (m *MicroService) GetProviders() []*DependencyKey {
+func (m *MicroService) GetProviders() []*MicroServiceKey {
 	if m != nil {
 		return m.Providers
 	}
@@ -2413,70 +2412,38 @@ func (m *CreateDependenciesRequest) GetDependencies() []*ConsumerDependency {
 	return nil
 }
 
-type DependencyKey struct {
-	AppId       string `protobuf:"bytes,1,opt,name=appId" json:"appId,omitempty"`
-	ServiceName string `protobuf:"bytes,2,opt,name=serviceName" json:"serviceName,omitempty"`
-	Version     string `protobuf:"bytes,3,opt,name=version" json:"version,omitempty"`
-	Environment string `protobuf:"bytes,4,opt,name=environment" json:"environment,omitempty"`
-}
-
-func (m *DependencyKey) Reset()                    { *m = DependencyKey{} }
-func (m *DependencyKey) String() string            { return proto1.CompactTextString(m) }
-func (*DependencyKey) ProtoMessage()               {}
-func (*DependencyKey) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{81} }
-
-func (m *DependencyKey) GetAppId() string {
-	if m != nil {
-		return m.AppId
-	}
-	return ""
-}
-
-func (m *DependencyKey) GetServiceName() string {
-	if m != nil {
-		return m.ServiceName
-	}
-	return ""
-}
-
-func (m *DependencyKey) GetVersion() string {
-	if m != nil {
-		return m.Version
-	}
-	return ""
-}
-
-func (m *DependencyKey) GetEnvironment() string {
-	if m != nil {
-		return m.Environment
-	}
-	return ""
-}
-
 type ConsumerDependency struct {
-	Consumer  *DependencyKey   `protobuf:"bytes,1,opt,name=consumer" json:"consumer,omitempty"`
-	Providers []*DependencyKey `protobuf:"bytes,2,rep,name=providers" json:"providers,omitempty"`
+	Consumer  *MicroServiceKey   `protobuf:"bytes,1,opt,name=consumer" json:"consumer,omitempty"`
+	Providers []*MicroServiceKey `protobuf:"bytes,2,rep,name=providers" json:"providers,omitempty"`
+	Override  bool               `protobuf:"varint,3,opt,name=override" json:"override,omitempty"`
 }
 
 func (m *ConsumerDependency) Reset()                    { *m = ConsumerDependency{} }
 func (m *ConsumerDependency) String() string            { return proto1.CompactTextString(m) }
 func (*ConsumerDependency) ProtoMessage()               {}
-func (*ConsumerDependency) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{82} }
+func (*ConsumerDependency) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{81} }
 
-func (m *ConsumerDependency) GetConsumer() *DependencyKey {
+func (m *ConsumerDependency) GetConsumer() *MicroServiceKey {
 	if m != nil {
 		return m.Consumer
 	}
 	return nil
 }
 
-func (m *ConsumerDependency) GetProviders() []*DependencyKey {
+func (m *ConsumerDependency) GetProviders() []*MicroServiceKey {
 	if m != nil {
 		return m.Providers
 	}
 	return nil
 }
 
+func (m *ConsumerDependency) GetOverride() bool {
+	if m != nil {
+		return m.Override
+	}
+	return false
+}
+
 type CreateDependenciesResponse struct {
 	Response *Response `protobuf:"bytes,1,opt,name=response" json:"response,omitempty"`
 }
@@ -2484,7 +2451,7 @@ type CreateDependenciesResponse struct {
 func (m *CreateDependenciesResponse) Reset()                    { *m = CreateDependenciesResponse{} }
 func (m *CreateDependenciesResponse) String() string            { return proto1.CompactTextString(m) }
 func (*CreateDependenciesResponse) ProtoMessage()               {}
-func (*CreateDependenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{83} }
+func (*CreateDependenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{82} }
 
 func (m *CreateDependenciesResponse) GetResponse() *Response {
 	if m != nil {
@@ -2500,7 +2467,7 @@ type GetDependenciesRequest struct {
 func (m *GetDependenciesRequest) Reset()                    { *m = GetDependenciesRequest{} }
 func (m *GetDependenciesRequest) String() string            { return proto1.CompactTextString(m) }
 func (*GetDependenciesRequest) ProtoMessage()               {}
-func (*GetDependenciesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{84} }
+func (*GetDependenciesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{83} }
 
 func (m *GetDependenciesRequest) GetServiceId() string {
 	if m != nil {
@@ -2517,7 +2484,7 @@ type GetConDependenciesResponse struct {
 func (m *GetConDependenciesResponse) Reset()                    { *m = GetConDependenciesResponse{} }
 func (m *GetConDependenciesResponse) String() string            { return proto1.CompactTextString(m) }
 func (*GetConDependenciesResponse) ProtoMessage()               {}
-func (*GetConDependenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{85} }
+func (*GetConDependenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{84} }
 
 func (m *GetConDependenciesResponse) GetResponse() *Response {
 	if m != nil {
@@ -2541,7 +2508,7 @@ type GetProDependenciesResponse struct {
 func (m *GetProDependenciesResponse) Reset()                    { *m = GetProDependenciesResponse{} }
 func (m *GetProDependenciesResponse) String() string            { return proto1.CompactTextString(m) }
 func (*GetProDependenciesResponse) ProtoMessage()               {}
-func (*GetProDependenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{86} }
+func (*GetProDependenciesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{85} }
 
 func (m *GetProDependenciesResponse) GetResponse() *Response {
 	if m != nil {
@@ -2573,7 +2540,7 @@ type ServiceDetail struct {
 func (m *ServiceDetail) Reset()                    { *m = ServiceDetail{} }
 func (m *ServiceDetail) String() string            { return proto1.CompactTextString(m) }
 func (*ServiceDetail) ProtoMessage()               {}
-func (*ServiceDetail) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{87} }
+func (*ServiceDetail) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{86} }
 
 func (m *ServiceDetail) GetMicroService() *MicroService {
 	if m != nil {
@@ -2647,7 +2614,7 @@ type GetServiceDetailResponse struct {
 func (m *GetServiceDetailResponse) Reset()                    { *m = GetServiceDetailResponse{} }
 func (m *GetServiceDetailResponse) String() string            { return proto1.CompactTextString(m) }
 func (*GetServiceDetailResponse) ProtoMessage()               {}
-func (*GetServiceDetailResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{88} }
+func (*GetServiceDetailResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{87} }
 
 func (m *GetServiceDetailResponse) GetResponse() *Response {
 	if m != nil {
@@ -2672,7 +2639,7 @@ type DelServicesRequest struct {
 func (m *DelServicesRequest) Reset()                    { *m = DelServicesRequest{} }
 func (m *DelServicesRequest) String() string            { return proto1.CompactTextString(m) }
 func (*DelServicesRequest) ProtoMessage()               {}
-func (*DelServicesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{89} }
+func (*DelServicesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{88} }
 
 func (m *DelServicesRequest) GetServiceIds() []string {
 	if m != nil {
@@ -2697,7 +2664,7 @@ type DelServicesRspInfo struct {
 func (m *DelServicesRspInfo) Reset()                    { *m = DelServicesRspInfo{} }
 func (m *DelServicesRspInfo) String() string            { return proto1.CompactTextString(m) }
 func (*DelServicesRspInfo) ProtoMessage()               {}
-func (*DelServicesRspInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{90} }
+func (*DelServicesRspInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{89} }
 
 func (m *DelServicesRspInfo) GetErrMessage() string {
 	if m != nil {
@@ -2722,7 +2689,7 @@ type DelServicesResponse struct {
 func (m *DelServicesResponse) Reset()                    { *m = DelServicesResponse{} }
 func (m *DelServicesResponse) String() string            { return proto1.CompactTextString(m) }
 func (*DelServicesResponse) ProtoMessage()               {}
-func (*DelServicesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{91} }
+func (*DelServicesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{90} }
 
 func (m *DelServicesResponse) GetResponse() *Response {
 	if m != nil {
@@ -2745,7 +2712,7 @@ type GetAppsRequest struct {
 func (m *GetAppsRequest) Reset()                    { *m = GetAppsRequest{} }
 func (m *GetAppsRequest) String() string            { return proto1.CompactTextString(m) }
 func (*GetAppsRequest) ProtoMessage()               {}
-func (*GetAppsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{92} }
+func (*GetAppsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{91} }
 
 func (m *GetAppsRequest) GetEnvironment() string {
 	if m != nil {
@@ -2762,7 +2729,7 @@ type GetAppsResponse struct {
 func (m *GetAppsResponse) Reset()                    { *m = GetAppsResponse{} }
 func (m *GetAppsResponse) String() string            { return proto1.CompactTextString(m) }
 func (*GetAppsResponse) ProtoMessage()               {}
-func (*GetAppsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{93} }
+func (*GetAppsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{92} }
 
 func (m *GetAppsResponse) GetResponse() *Response {
 	if m != nil {
@@ -2860,7 +2827,6 @@ func init() {
 	proto1.RegisterType((*AddDependenciesRequest)(nil), "com.huawei.paas.cse.serviceregistry.api.AddDependenciesRequest")
 	proto1.RegisterType((*AddDependenciesResponse)(nil), "com.huawei.paas.cse.serviceregistry.api.AddDependenciesResponse")
 	proto1.RegisterType((*CreateDependenciesRequest)(nil), "com.huawei.paas.cse.serviceregistry.api.CreateDependenciesRequest")
-	proto1.RegisterType((*DependencyKey)(nil), "com.huawei.paas.cse.serviceregistry.api.DependencyKey")
 	proto1.RegisterType((*ConsumerDependency)(nil), "com.huawei.paas.cse.serviceregistry.api.ConsumerDependency")
 	proto1.RegisterType((*CreateDependenciesResponse)(nil), "com.huawei.paas.cse.serviceregistry.api.CreateDependenciesResponse")
 	proto1.RegisterType((*GetDependenciesRequest)(nil), "com.huawei.paas.cse.serviceregistry.api.GetDependenciesRequest")
@@ -4228,219 +4194,218 @@ var _GovernServiceCtrl_serviceDesc = grpc.ServiceDesc{
 func init() { proto1.RegisterFile("services.proto", fileDescriptor0) }
 
 var fileDescriptor0 = []byte{
-	// 3422 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5c, 0xdb, 0x6f, 0x24, 0x47,
-	0xd5, 0x57, 0x8d, 0x67, 0x3c, 0x9e, 0xe3, 0xf5, 0xee, 0xba, 0xd6, 0x5e, 0xf7, 0x4e, 0xf2, 0xe5,
-	0x5b, 0xb5, 0x22, 0x7d, 0x79, 0x88, 0xfc, 0x25, 0x0e, 0x49, 0x96, 0xbd, 0x64, 0x63, 0x7b, 0x37,
-	0x5e, 0xef, 0x66, 0xb3, 0x9b, 0x1e, 0x27, 0x4b, 0x12, 0x20, 0x6a, 0xcf, 0x94, 0x67, 0x3a, 0x3b,
-	0xd3, 0x3d, 0xe9, 0xee, 0xf1, 0x66, 0x24, 0x24, 0x94, 0x90, 0x40, 0x20, 0x90, 0x10, 0x01, 0x4f,
-	0x79, 0x00, 0x01, 0x79, 0x04, 0x09, 0x84, 0x14, 0xa1, 0x88, 0x08, 0x81, 0x78, 0x41, 0x44, 0x3c,
-	0x21, 0x9e, 0xf8, 0x0f, 0x78, 0xe3, 0x0f, 0x00, 0xd5, 0xa5, 0xbb, 0xab, 0x2f, 0x9e, 0x9d, 0xea,
-	0x76, 0x27, 0xe2, 0xc9, 0x5d, 0xd5, 0xae, 0x53, 0xa7, 0xce, 0xad, 0x4e, 0xfd, 0xea, 0x4c, 0xc3,
-	0x51, 0x8f, 0xb8, 0xfb, 0x56, 0x9b, 0x78, 0xab, 0x43, 0xd7, 0xf1, 0x1d, 0xfc, 0x7f, 0x6d, 0x67,
-	0xb0, 0xda, 0x1b, 0x99, 0x77, 0x88, 0xb5, 0x3a, 0x34, 0x4d, 0x6f, 0xb5, 0xed, 0x91, 0x55, 0xf1,
-	0x3f, 0x2e, 0xe9, 0x5a, 0x9e, 0xef, 0x8e, 0x57, 0xcd, 0xa1, 0xa5, 0x7f, 0x1d, 0x96, 0xae, 0x3b,
-	0x1d, 0x6b, 0x6f, 0xdc, 0x6a, 0xf7, 0xc8, 0xc0, 0xf4, 0x0c, 0xf2, 0xea, 0x88, 0x78, 0x3e, 0xbe,
-	0x17, 0x1a, 0xe2, 0xdf, 0xb7, 0x3b, 0x1a, 0x3a, 0x8d, 0x1e, 0x68, 0x18, 0x51, 0x07, 0xde, 0x86,
-	0xba, 0xc7, 0xff, 0x5f, 0xab, 0x9c, 0x9e, 0x79, 0x60, 0x7e, 0xed, 0xff, 0x57, 0xa7, 0x9c, 0x70,
-	0x95, 0xcf, 0x63, 0x04, 0xe3, 0xf5, 0xe7, 0x61, 0x96, 0x77, 0xe1, 0x26, 0xcc, 0xf1, 0xce, 0x70,
-	0xc6, 0xb0, 0x8d, 0x35, 0xa8, 0x7b, 0xa3, 0xc1, 0xc0, 0x74, 0xc7, 0x5a, 0x85, 0xbd, 0x0a, 0x9a,
-	0xf8, 0x24, 0xcc, 0xf2, 0xff, 0xd2, 0x66, 0xd8, 0x0b, 0xd1, 0xd2, 0xf7, 0x60, 0x39, 0xb1, 0x30,
-	0x6f, 0xe8, 0xd8, 0x1e, 0xc1, 0xd7, 0x61, 0xce, 0x15, 0xcf, 0x6c, 0x9a, 0xf9, 0xb5, 0x87, 0xa7,
-	0x66, 0x3e, 0x20, 0x62, 0x84, 0x24, 0xf4, 0x57, 0xe1, 0xc4, 0x15, 0x62, 0xba, 0xfe, 0x2e, 0x31,
-	0xfd, 0x16, 0xf1, 0x03, 0xf9, 0xbd, 0x08, 0x0d, 0xcb, 0xf6, 0x7c, 0xd3, 0x6e, 0x13, 0x4f, 0x43,
-	0x4c, 0x46, 0xe7, 0xa7, 0x9e, 0x46, 0x26, 0x78, 0xb9, 0x4f, 0x06, 0xc4, 0xf6, 0x8d, 0x88, 0x9c,
-	0xde, 0x8a, 0x4f, 0x29, 0xfe, 0xe3, 0x2e, 0x2a, 0xbb, 0x0f, 0x20, 0xa0, 0xb0, 0xdd, 0x11, 0x42,
-	0x94, 0x7a, 0xf4, 0x8f, 0x11, 0x2c, 0xc5, 0x17, 0x52, 0x8a, 0xbc, 0xf0, 0x8e, 0x2c, 0x18, 0x6e,
-	0x3c, 0x8f, 0x4d, 0x4d, 0x6f, 0x5b, 0x8c, 0xbc, 0xb2, 0x6b, 0x78, 0x31, 0x91, 0x0c, 0x60, 0x21,
-	0xf6, 0xae, 0x98, 0x30, 0xe8, 0x7b, 0xe2, 0xba, 0xd7, 0x89, 0xe7, 0x99, 0x5d, 0x22, 0x0c, 0x4b,
-	0xea, 0xd1, 0x37, 0xa1, 0xd1, 0xf2, 0x5b, 0x9c, 0x1c, 0x5e, 0x82, 0x5a, 0xdb, 0x19, 0xd9, 0x3e,
-	0x9b, 0x66, 0xc6, 0xe0, 0x0d, 0x7c, 0x1a, 0xe6, 0x1d, 0xbb, 0x6f, 0xd9, 0x64, 0x93, 0xbd, 0xab,
-	0xb0, 0x77, 0x72, 0x97, 0xae, 0x03, 0xb4, 0xfc, 0x80, 0xeb, 0x6c, 0x2a, 0xfa, 0xff, 0x40, 0xad,
-	0xe5, 0xaf, 0x0f, 0x87, 0x07, 0xbc, 0xfe, 0x17, 0xa2, 0x34, 0x4c, 0xdf, 0xf2, 0x7c, 0xab, 0xed,
-	0xe1, 0x67, 0x60, 0x2e, 0x88, 0x03, 0x42, 0x55, 0x6b, 0xd3, 0xfb, 0x65, 0xb0, 0x1e, 0x23, 0xa4,
-	0x81, 0x9f, 0x8d, 0xeb, 0x8a, 0x12, 0x7c, 0x44, 0x81, 0x60, 0xb0, 0x36, 0x49, 0x51, 0x78, 0x03,
-	0xaa, 0xe6, 0x70, 0xe8, 0x31, 0x99, 0xce, 0xaf, 0xad, 0x2a, 0x50, 0x5b, 0x1f, 0x0e, 0x0d, 0x36,
-	0x56, 0x7f, 0x1b, 0xc1, 0xc9, 0x2d, 0x12, 0xf0, 0xeb, 0x6d, 0xdb, 0x7b, 0x4e, 0xe0, 0x76, 0x1a,
-	0xd4, 0x9d, 0xa1, 0x6f, 0x39, 0x36, 0x77, 0xba, 0x86, 0x11, 0x34, 0xa9, 0x00, 0xcd, 0xe1, 0x30,
-	0xd4, 0x36, 0x6f, 0x50, 0x2d, 0x89, 0xd9, 0x9e, 0x31, 0x07, 0x81, 0xa6, 0xe5, 0x2e, 0x6a, 0x48,
-	0x4c, 0xd6, 0x37, 0xec, 0xfe, 0x58, 0xab, 0x9e, 0x46, 0x0f, 0xcc, 0x19, 0x51, 0x87, 0xfe, 0xb3,
-	0x0a, 0xac, 0xa4, 0x58, 0x29, 0xc7, 0x71, 0x3a, 0xb0, 0x68, 0xf6, 0xfb, 0xc1, 0x4c, 0x97, 0x88,
-	0x6f, 0x5a, 0x7d, 0x65, 0x07, 0x12, 0xc3, 0xf9, 0x68, 0x23, 0x4d, 0x10, 0xb7, 0x00, 0xbc, 0xd0,
-	0xa0, 0x84, 0x96, 0x54, 0x74, 0x1e, 0x0c, 0x35, 0x24, 0x32, 0xfa, 0xa7, 0x08, 0x8e, 0x5d, 0xb7,
-	0xda, 0xae, 0x23, 0x26, 0xbb, 0x46, 0x58, 0xdc, 0xf6, 0x89, 0x6d, 0x0a, 0x8b, 0x6e, 0x18, 0xa2,
-	0x45, 0x35, 0x38, 0x74, 0x9d, 0x57, 0x48, 0xdb, 0x0f, 0x22, 0xbd, 0x68, 0x46, 0x1a, 0x9c, 0x99,
-	0xa0, 0xc1, 0x6a, 0x5a, 0x83, 0x1a, 0xd4, 0xf7, 0x89, 0xeb, 0x59, 0x8e, 0xad, 0xd5, 0x38, 0x45,
-	0xd1, 0xa4, 0x63, 0x89, 0xbd, 0x6f, 0xb9, 0x8e, 0x4d, 0x03, 0xa8, 0x36, 0xcb, 0xc7, 0x4a, 0x5d,
-	0x6c, 0xce, 0xbe, 0x65, 0x7a, 0x5a, 0x5d, 0xcc, 0x49, 0x1b, 0xfa, 0x9f, 0xeb, 0x70, 0x44, 0x5e,
-	0xcf, 0x5d, 0xa2, 0x4d, 0x5e, 0xd3, 0x93, 0x18, 0xaf, 0xa6, 0x18, 0xef, 0x10, 0xaf, 0xed, 0x5a,
-	0xcc, 0xb8, 0xc5, 0xb2, 0xe4, 0x2e, 0x3a, 0x67, 0x9f, 0xec, 0x93, 0xbe, 0x58, 0x14, 0x6f, 0xb0,
-	0x6d, 0x54, 0xec, 0xdb, 0x75, 0xee, 0x1e, 0xa2, 0x89, 0xaf, 0x42, 0x6d, 0x68, 0xfa, 0x3d, 0x4f,
-	0x03, 0x66, 0x51, 0x5f, 0x50, 0xb5, 0xa8, 0x9b, 0xa6, 0xdf, 0x33, 0x38, 0x09, 0xb6, 0x25, 0xfb,
-	0xa6, 0x3f, 0xf2, 0xb4, 0x39, 0xb1, 0x25, 0xb3, 0x16, 0x26, 0x00, 0x43, 0xd7, 0x19, 0x12, 0xd7,
-	0xb7, 0x88, 0xa7, 0x35, 0xd8, 0x44, 0x97, 0xa7, 0x9e, 0x48, 0x16, 0xf8, 0xea, 0xcd, 0x90, 0xce,
-	0x65, 0xdb, 0x77, 0xc7, 0x86, 0x44, 0x98, 0x2a, 0xc3, 0xb7, 0x06, 0xc4, 0xf3, 0xcd, 0xc1, 0x50,
-	0x9b, 0xe7, 0xca, 0x08, 0x3b, 0xe8, 0xfe, 0x33, 0x74, 0x9d, 0x7d, 0xab, 0x43, 0x5c, 0x4f, 0x3b,
-	0xa2, 0xe8, 0x3e, 0x97, 0xc8, 0x90, 0xd8, 0x1d, 0x62, 0xb7, 0xc7, 0xd7, 0xc8, 0xd8, 0x88, 0x08,
-	0x45, 0x76, 0xb2, 0x20, 0xd9, 0x09, 0x5d, 0xf0, 0xd3, 0x1b, 0x2d, 0xdf, 0x35, 0x7d, 0xd2, 0x1d,
-	0x6b, 0x47, 0x8b, 0x2c, 0x38, 0xa2, 0x23, 0x16, 0x1c, 0x75, 0x60, 0x1d, 0x8e, 0x0c, 0x9c, 0xce,
-	0x4e, 0xb8, 0xe6, 0x63, 0x8c, 0x87, 0x58, 0x5f, 0xd2, 0xd4, 0x8f, 0xa7, 0x4d, 0xfd, 0x3e, 0x00,
-	0x3e, 0x3d, 0x71, 0x37, 0xc6, 0xda, 0x22, 0xdf, 0xf3, 0xa2, 0x1e, 0xfc, 0x25, 0x68, 0xec, 0xb9,
-	0xe6, 0x80, 0xdc, 0x71, 0xdc, 0xdb, 0x1a, 0x66, 0x81, 0xe1, 0xec, 0xd4, 0x6b, 0x79, 0x8a, 0x8e,
-	0xbc, 0xe5, 0xb8, 0xb7, 0x85, 0xe2, 0xc6, 0x46, 0x44, 0xac, 0x79, 0x01, 0x8e, 0x25, 0xf4, 0x89,
-	0x8f, 0xc3, 0xcc, 0x6d, 0x32, 0x16, 0xae, 0x44, 0x1f, 0xa9, 0x84, 0xf7, 0xcd, 0xfe, 0x88, 0x04,
-	0x4e, 0xc4, 0x1a, 0x67, 0x2b, 0x67, 0x10, 0x1d, 0x9e, 0x90, 0x8e, 0xca, 0x70, 0x7d, 0x1d, 0x16,
-	0x53, 0xdc, 0x61, 0x0c, 0x55, 0x9b, 0x7a, 0x25, 0xa7, 0xc0, 0x9e, 0x65, 0x77, 0xac, 0xc4, 0xdc,
-	0x51, 0xff, 0x07, 0x82, 0xf9, 0x60, 0xf7, 0x1c, 0xf5, 0x09, 0x75, 0x00, 0x77, 0xd4, 0x8f, 0x62,
-	0x81, 0x68, 0xd1, 0x0c, 0x97, 0x3e, 0xed, 0x8c, 0x87, 0x01, 0x1f, 0x61, 0x9b, 0x5a, 0xad, 0xe9,
-	0xfb, 0xae, 0xb5, 0x3b, 0xf2, 0x83, 0x60, 0x10, 0x75, 0xb0, 0xa8, 0x68, 0xfa, 0x3e, 0x71, 0xc3,
-	0x50, 0x20, 0x9a, 0x53, 0x84, 0x82, 0x98, 0x3f, 0xcc, 0x26, 0xfd, 0x21, 0x69, 0x3c, 0xf5, 0xb4,
-	0xf1, 0xe8, 0xef, 0x22, 0x38, 0xb9, 0xde, 0xe9, 0xdc, 0x70, 0x9f, 0x1b, 0x76, 0x4c, 0x9f, 0xc8,
-	0x4b, 0x95, 0x97, 0x84, 0x26, 0x2d, 0xa9, 0x32, 0x61, 0x49, 0x33, 0x13, 0x97, 0x54, 0x4d, 0x2d,
-	0x49, 0xff, 0x24, 0x12, 0x38, 0x0d, 0x3c, 0x54, 0x5d, 0x34, 0xf4, 0x04, 0xea, 0xa2, 0xcf, 0xf8,
-	0xab, 0x30, 0x27, 0x82, 0xc2, 0x58, 0x6c, 0x93, 0x1b, 0x79, 0x82, 0x5a, 0x10, 0x6a, 0x84, 0xdf,
-	0x85, 0x34, 0x9b, 0xe7, 0x60, 0x21, 0xf6, 0x4a, 0xc9, 0xe8, 0xce, 0xc0, 0x5c, 0x98, 0x27, 0x60,
-	0xa8, 0xb6, 0x9d, 0x0e, 0x17, 0x5f, 0xcd, 0x60, 0xcf, 0x54, 0x38, 0x03, 0x91, 0x7d, 0x0a, 0x5b,
-	0x13, 0x4d, 0xfd, 0xef, 0x08, 0x4e, 0x6c, 0x11, 0xff, 0xf2, 0x6b, 0xd4, 0x2f, 0x69, 0x72, 0x25,
-	0x32, 0x1f, 0x0c, 0x55, 0x3f, 0x52, 0x02, 0x7b, 0x2e, 0x61, 0xe3, 0x89, 0x6d, 0x74, 0xb5, 0xe4,
-	0x46, 0x27, 0x9f, 0xe0, 0x66, 0x13, 0x27, 0xb8, 0x44, 0x00, 0xaa, 0xa7, 0x02, 0x90, 0xfe, 0x5b,
-	0x04, 0x4b, 0xf1, 0x95, 0x95, 0x93, 0x48, 0xc5, 0xd6, 0x50, 0x99, 0xb4, 0x86, 0x99, 0x83, 0x4f,
-	0xa1, 0xd5, 0xd8, 0x29, 0x54, 0xff, 0xd5, 0x0c, 0x2c, 0x6d, 0xba, 0x44, 0x72, 0x0e, 0xa1, 0x96,
-	0x1b, 0x50, 0x17, 0xb4, 0x05, 0xeb, 0x8f, 0xe6, 0x8a, 0xff, 0x46, 0x40, 0x05, 0x3f, 0x07, 0x35,
-	0xea, 0x60, 0xc1, 0xd9, 0xe9, 0xe2, 0xd4, 0xe4, 0xb2, 0x1d, 0xd8, 0xe0, 0xd4, 0xf0, 0x4b, 0x50,
-	0xf5, 0xcd, 0x2e, 0xcd, 0xf8, 0x28, 0xd5, 0xad, 0xa9, 0xa9, 0x66, 0x2d, 0x7a, 0x75, 0xc7, 0xec,
-	0x8a, 0x7d, 0x99, 0x11, 0xc5, 0x2f, 0xc9, 0xe7, 0x88, 0x2a, 0x9b, 0xe1, 0x42, 0x2e, 0x31, 0x64,
-	0x9c, 0x28, 0x9a, 0x8f, 0x43, 0x23, 0x9c, 0x4f, 0xc9, 0x07, 0xdf, 0x44, 0xb0, 0x9c, 0x60, 0xff,
-	0x73, 0x30, 0x38, 0xfd, 0x2a, 0x2c, 0x5d, 0x22, 0x7d, 0x92, 0xb2, 0x9c, 0xbb, 0xe6, 0x94, 0x7b,
-	0x8e, 0xdb, 0xe6, 0xcb, 0x9a, 0x33, 0x78, 0x43, 0xdf, 0x83, 0xe5, 0x04, 0xad, 0x72, 0x40, 0x8f,
-	0x87, 0x61, 0x31, 0x3a, 0xf5, 0x4c, 0xc5, 0xb0, 0xfe, 0x1b, 0x04, 0x58, 0x1e, 0x53, 0x8e, 0xa8,
-	0x25, 0x77, 0xab, 0x1c, 0x86, 0xbb, 0xe9, 0x4b, 0x32, 0xd7, 0x01, 0x3a, 0xa6, 0x7f, 0xc4, 0x83,
-	0x70, 0xd4, 0x5d, 0xce, 0x6a, 0x9e, 0x95, 0xce, 0xf3, 0xdc, 0xdd, 0x73, 0x2e, 0x27, 0x24, 0xa3,
-	0xff, 0x13, 0xc1, 0xa9, 0x58, 0x10, 0xa0, 0x7b, 0xd8, 0x94, 0xa8, 0x9f, 0x1b, 0xcb, 0xdf, 0x39,
-	0x43, 0xc6, 0xd4, 0x0c, 0x1d, 0x38, 0xeb, 0xa4, 0x64, 0xbe, 0x60, 0x6e, 0xa8, 0xdf, 0x86, 0x66,
-	0xd6, 0xbc, 0xe5, 0x78, 0xc5, 0x63, 0x32, 0x2c, 0x41, 0x83, 0xab, 0x37, 0xb5, 0x6b, 0xac, 0xa4,
-	0x06, 0x96, 0x63, 0x51, 0x57, 0xe3, 0xbb, 0x87, 0xf2, 0x31, 0x4f, 0xda, 0x32, 0xf4, 0x0f, 0x11,
-	0x68, 0xe9, 0xfd, 0x64, 0x2a, 0x4b, 0x8a, 0x12, 0xe4, 0x4a, 0x2c, 0x41, 0x6e, 0x41, 0x95, 0x3e,
-	0x09, 0xdc, 0xa1, 0xf0, 0xde, 0xc6, 0x88, 0xe9, 0xaf, 0x24, 0x2c, 0x9e, 0xb3, 0x59, 0x8e, 0x09,
-	0x7c, 0x8f, 0x67, 0xca, 0xca, 0x36, 0x50, 0xd2, 0xb6, 0xae, 0xbf, 0x81, 0x60, 0x25, 0xc5, 0x4f,
-	0x39, 0xa6, 0xa5, 0x41, 0xdd, 0x60, 0x5a, 0xe4, 0x6b, 0x68, 0x18, 0x41, 0x53, 0x6f, 0xc1, 0xa9,
-	0xf8, 0xae, 0x34, 0xbd, 0x58, 0x34, 0xa8, 0xbb, 0x71, 0xa2, 0xa2, 0x49, 0x3d, 0x3b, 0x8b, 0x68,
-	0x39, 0x6a, 0x7d, 0x14, 0x96, 0x23, 0x07, 0xa5, 0xd9, 0xc6, 0x74, 0x8e, 0xfd, 0xef, 0x18, 0x50,
-	0xc9, 0xc7, 0x95, 0x23, 0xfc, 0xaf, 0x88, 0xf4, 0x8d, 0x5b, 0xcf, 0xf6, 0xd4, 0xa4, 0xb2, 0xb9,
-	0x4b, 0x26, 0x70, 0xf9, 0x73, 0xac, 0x97, 0x61, 0x25, 0x66, 0x9b, 0x3b, 0x66, 0x77, 0x3a, 0xc5,
-	0x8b, 0x49, 0x2a, 0x19, 0x93, 0xcc, 0x48, 0x93, 0xe8, 0x56, 0x22, 0x06, 0xb1, 0x09, 0xca, 0x31,
-	0x82, 0xbf, 0x20, 0x58, 0x8e, 0x7c, 0x69, 0x6a, 0x2b, 0xc0, 0x5f, 0x8e, 0xe9, 0xe6, 0x8a, 0x8a,
-	0x67, 0xa7, 0xe7, 0x3a, 0x3c, 0xd5, 0x74, 0xe5, 0x48, 0x55, 0xa2, 0x6d, 0xea, 0x4f, 0x83, 0x16,
-	0xf3, 0xd4, 0xe9, 0x25, 0x87, 0xa1, 0x7a, 0x9b, 0x8c, 0x03, 0xd7, 0x67, 0xcf, 0x34, 0x9a, 0x67,
-	0x50, 0x2b, 0x87, 0xf3, 0x31, 0xcc, 0x5f, 0x21, 0x66, 0xdf, 0xef, 0x6d, 0xf6, 0x48, 0xfb, 0x36,
-	0x65, 0x67, 0x10, 0x1c, 0xd4, 0x1b, 0x06, 0x7b, 0x66, 0xc8, 0x83, 0xe3, 0x72, 0xac, 0xba, 0x66,
-	0xb0, 0x67, 0x7a, 0x84, 0xb4, 0x6c, 0x9f, 0xb8, 0xfb, 0x66, 0x9f, 0x19, 0x6b, 0xcd, 0x08, 0xdb,
-	0x54, 0x1f, 0x0c, 0x7b, 0x61, 0x07, 0xc8, 0x9a, 0xc1, 0x1b, 0x54, 0x6f, 0x23, 0xb7, 0x2f, 0x0e,
-	0xd4, 0xf4, 0x51, 0xff, 0x6b, 0x15, 0x96, 0xb2, 0x4e, 0x3e, 0x89, 0xab, 0x2b, 0x94, 0xba, 0xba,
-	0x9a, 0x7c, 0xba, 0xbd, 0x17, 0x1a, 0xc4, 0xee, 0x0c, 0x1d, 0xcb, 0xf6, 0xf9, 0x59, 0xaf, 0x61,
-	0x44, 0x1d, 0x94, 0xf1, 0x9e, 0xe3, 0xf9, 0x12, 0x90, 0x1e, 0xb6, 0x25, 0x50, 0xb7, 0x16, 0x03,
-	0x75, 0x07, 0xb1, 0xa4, 0x70, 0x96, 0xd9, 0xf8, 0xf5, 0x42, 0x87, 0xbb, 0x89, 0xe0, 0xee, 0xf3,
-	0x30, 0xdf, 0x8b, 0x54, 0xc2, 0x60, 0x04, 0x95, 0x34, 0x46, 0x52, 0xa7, 0x21, 0x13, 0x8a, 0x83,
-	0x64, 0x73, 0x49, 0x90, 0xec, 0x65, 0x38, 0xda, 0x31, 0x7d, 0x73, 0x93, 0x50, 0x35, 0x6e, 0xdb,
-	0x7b, 0x8e, 0xd6, 0x60, 0x13, 0x3f, 0x3e, 0x3d, 0x72, 0x1c, 0x1b, 0x6e, 0x24, 0xc8, 0xa5, 0x50,
-	0x38, 0x48, 0xa3, 0x70, 0x45, 0x53, 0xe1, 0x5d, 0x38, 0x1a, 0x67, 0x22, 0x13, 0xe4, 0xa4, 0x99,
-	0x19, 0xe9, 0x46, 0x18, 0xa7, 0x68, 0xe1, 0xfb, 0x61, 0xc1, 0xdc, 0x37, 0xad, 0xbe, 0xb9, 0xdb,
-	0x27, 0x2f, 0x3a, 0x76, 0x10, 0x85, 0xe3, 0x9d, 0xfa, 0x2d, 0x58, 0xc9, 0xd2, 0xe8, 0x35, 0x32,
-	0x2e, 0x66, 0xb7, 0xba, 0x0f, 0x2b, 0x86, 0x80, 0xa2, 0x43, 0x0c, 0x40, 0x84, 0x90, 0x17, 0xa8,
-	0xb7, 0xf1, 0x2e, 0xe1, 0xf3, 0x05, 0xb1, 0x85, 0x90, 0x9c, 0xfe, 0x6d, 0x04, 0x5a, 0x7a, 0xda,
-	0x72, 0x76, 0xf0, 0xbb, 0xdd, 0xcf, 0xbf, 0x00, 0xa7, 0x9e, 0xb3, 0xdd, 0x03, 0x64, 0x50, 0xec,
-	0xea, 0x9f, 0x1e, 0x92, 0x32, 0x48, 0x97, 0x13, 0x53, 0x6f, 0xc2, 0xf1, 0xb0, 0xcc, 0xe0, 0x70,
-	0xd8, 0xdf, 0x85, 0x45, 0x89, 0x62, 0x39, 0x5c, 0xff, 0x1a, 0xc1, 0xd2, 0x53, 0x96, 0xdd, 0x09,
-	0xa4, 0x13, 0x6e, 0x60, 0x0f, 0xc2, 0x62, 0xdb, 0xb1, 0xbd, 0xd1, 0x80, 0xb8, 0xad, 0xc4, 0x12,
-	0xd2, 0x2f, 0x72, 0x03, 0xb2, 0xa7, 0x61, 0x5e, 0x20, 0xb0, 0x34, 0xcd, 0x0d, 0x10, 0x71, 0xa9,
-	0x8b, 0xc1, 0xbf, 0x34, 0xc9, 0xa8, 0xf1, 0xad, 0x92, 0x3e, 0xeb, 0x7f, 0x44, 0xb0, 0x9c, 0x60,
-	0xba, 0x1c, 0xdb, 0x7d, 0x29, 0x5d, 0xd3, 0x71, 0x68, 0xf8, 0x9e, 0xfe, 0x11, 0x62, 0xc9, 0xf7,
-	0x0d, 0x9b, 0x24, 0xad, 0x5e, 0x4d, 0xf6, 0x0f, 0xc2, 0x62, 0x70, 0x5f, 0xd7, 0x4a, 0x04, 0x9a,
-	0xf4, 0x0b, 0xbc, 0x0a, 0x38, 0xe8, 0xdc, 0x8e, 0x8c, 0x8f, 0xab, 0x26, 0xe3, 0x4d, 0x28, 0xff,
-	0xaa, 0x24, 0xff, 0x3f, 0xf0, 0xf4, 0x3f, 0xc6, 0x79, 0x39, 0x0a, 0x90, 0x63, 0x60, 0xe5, 0x70,
-	0x63, 0xe0, 0x5b, 0x1c, 0xea, 0x2a, 0x68, 0xf8, 0x6a, 0xc2, 0xc7, 0x12, 0x18, 0x2d, 0x09, 0x73,
-	0x29, 0xce, 0xc7, 0x7f, 0xa1, 0x2d, 0x7b, 0x70, 0x0f, 0x3f, 0xad, 0x04, 0x2f, 0x5b, 0x2c, 0x89,
-	0x3a, 0x94, 0x38, 0x28, 0x65, 0x68, 0x33, 0x72, 0x86, 0xa6, 0x0f, 0xe0, 0xde, 0xec, 0x49, 0xcb,
-	0x09, 0x95, 0xef, 0x56, 0x02, 0xcc, 0x2d, 0x98, 0x4f, 0x01, 0x62, 0xbc, 0xdb, 0x1a, 0xbd, 0x58,
-	0xb6, 0xc9, 0x2f, 0x2b, 0x5a, 0x8a, 0x10, 0x64, 0x16, 0x5b, 0x65, 0x62, 0x90, 0xfd, 0xa4, 0xd2,
-	0x4b, 0x05, 0x21, 0xcf, 0xc3, 0xd2, 0x2d, 0xd3, 0x6f, 0xf7, 0x92, 0xc1, 0xf2, 0x7e, 0x58, 0xf0,
-	0x48, 0x7f, 0x2f, 0xe9, 0xab, 0xf1, 0x4e, 0xfd, 0xc3, 0x0a, 0x2c, 0x27, 0x86, 0x97, 0xe3, 0x66,
-	0x27, 0x61, 0xd6, 0x6c, 0xfb, 0x52, 0x9e, 0xc9, 0x5b, 0xf8, 0x2a, 0x17, 0x2c, 0x07, 0x00, 0xcf,
-	0xe4, 0x72, 0xbc, 0x6b, 0x64, 0xcc, 0x55, 0x22, 0x47, 0xc5, 0xea, 0xe1, 0x46, 0xc5, 0xa7, 0xe1,
-	0xf8, 0x16, 0xf1, 0x45, 0x2d, 0xeb, 0x54, 0x96, 0x2d, 0xdf, 0x2b, 0x56, 0xe2, 0xf7, 0x8a, 0x7a,
-	0x8b, 0x85, 0xd8, 0xf5, 0x7e, 0x5f, 0x85, 0xe0, 0x7d, 0x00, 0x77, 0x2c, 0xbf, 0xc7, 0x87, 0x88,
-	0x6b, 0x20, 0xa9, 0x47, 0xff, 0x09, 0xe2, 0x97, 0x34, 0x82, 0x64, 0x69, 0x6a, 0xf4, 0x22, 0x06,
-	0xc2, 0xea, 0x5b, 0x66, 0x6d, 0xec, 0xa9, 0x25, 0xee, 0x4b, 0xc5, 0x71, 0x21, 0xd6, 0xa9, 0xff,
-	0x92, 0xc7, 0x74, 0x69, 0xe1, 0xe5, 0x70, 0xb9, 0x25, 0x71, 0x99, 0xab, 0x5a, 0x39, 0x28, 0x2a,
-	0xbe, 0x01, 0x27, 0x04, 0xf8, 0x70, 0x48, 0x9a, 0x27, 0xe1, 0xe5, 0x5f, 0x99, 0x02, 0xd0, 0x5f,
-	0x47, 0x70, 0x42, 0xae, 0x86, 0x2e, 0xcc, 0xf8, 0x41, 0x65, 0xd7, 0x13, 0xae, 0xc8, 0x49, 0xbc,
-	0xd2, 0xbc, 0x3c, 0xcc, 0xe6, 0xe4, 0x7a, 0xa7, 0x13, 0x16, 0x6a, 0x59, 0x51, 0xc6, 0xf2, 0x32,
-	0x1c, 0xe9, 0x48, 0xdd, 0xa2, 0x2a, 0xfb, 0xdc, 0xf4, 0x57, 0xdd, 0x22, 0xab, 0x89, 0x8a, 0xc0,
-	0x8c, 0x18, 0x41, 0xbd, 0xc7, 0xb0, 0xf6, 0xf8, 0xd4, 0xe5, 0x2c, 0xf2, 0x6b, 0x70, 0x8a, 0xdf,
-	0x5c, 0x7f, 0x2e, 0xeb, 0xfc, 0x06, 0x82, 0x85, 0x58, 0x25, 0x5c, 0x74, 0xae, 0x41, 0x13, 0xce,
-	0x35, 0x95, 0x89, 0x85, 0x26, 0x33, 0x13, 0x4b, 0x33, 0xab, 0xe9, 0x72, 0x91, 0x4f, 0x10, 0xe0,
-	0x34, 0xab, 0xd8, 0x80, 0xb9, 0x20, 0xfd, 0x14, 0x92, 0xce, 0x5b, 0xde, 0x17, 0xd2, 0x89, 0xd7,
-	0x0c, 0x56, 0x0e, 0xa9, 0x66, 0x90, 0x1e, 0xbb, 0xb3, 0x94, 0x58, 0xe6, 0xdd, 0x64, 0x96, 0xb9,
-	0x4c, 0xbe, 0xc2, 0xf8, 0x3d, 0x82, 0xe6, 0x16, 0xf1, 0x37, 0x1d, 0xfb, 0x33, 0xe0, 0x12, 0xb7,
-	0xd2, 0x82, 0xce, 0x79, 0xe3, 0x2d, 0xc9, 0x59, 0x2c, 0xe1, 0xa6, 0xeb, 0x7c, 0x46, 0x4b, 0x08,
-	0xec, 0xa6, 0xe8, 0x12, 0x42, 0x3a, 0xfa, 0x4f, 0x67, 0x61, 0x21, 0x56, 0xba, 0x8d, 0x5f, 0x80,
-	0x23, 0x03, 0xe9, 0x9f, 0x8b, 0x15, 0x17, 0xc5, 0x48, 0x95, 0x7a, 0x02, 0xc2, 0xcf, 0xc2, 0xbc,
-	0xd8, 0x43, 0xec, 0x3d, 0x27, 0xc8, 0xe0, 0x95, 0xf7, 0x63, 0x99, 0x46, 0x74, 0xa7, 0x5d, 0x2d,
-	0x7c, 0xa7, 0x1d, 0x37, 0xc0, 0xda, 0xe1, 0x18, 0x60, 0xdc, 0x24, 0x66, 0x0f, 0xc7, 0x24, 0xf0,
-	0x8e, 0x38, 0x23, 0xd7, 0x19, 0xbd, 0x27, 0xf3, 0xfd, 0x02, 0x20, 0x55, 0xa9, 0xb5, 0x06, 0x4b,
-	0xb2, 0x2d, 0x3c, 0xcf, 0xa3, 0xb1, 0xa7, 0xcd, 0xb1, 0x93, 0x78, 0xe6, 0x3b, 0x7c, 0x1d, 0xea,
-	0xac, 0xd6, 0xbf, 0xed, 0x09, 0x54, 0x3c, 0xd7, 0xef, 0x05, 0x02, 0x1a, 0xf9, 0x2f, 0xb4, 0x3e,
-	0x46, 0xa0, 0x45, 0xf7, 0x99, 0xe2, 0x27, 0x0e, 0x25, 0x79, 0xf9, 0xcd, 0x64, 0x9d, 0x51, 0xde,
-	0x9f, 0x60, 0x84, 0x85, 0x46, 0x57, 0x01, 0x5f, 0x22, 0xfd, 0x44, 0xa1, 0x11, 0x4d, 0xf2, 0xc3,
-	0x58, 0x1c, 0xfc, 0xa4, 0x45, 0xea, 0x39, 0xa0, 0x0c, 0xcc, 0x88, 0xd3, 0xf2, 0x86, 0x0c, 0xee,
-	0x8f, 0xff, 0xa8, 0x09, 0x25, 0x7f, 0xd4, 0x74, 0x17, 0x04, 0xfe, 0x77, 0x88, 0xe5, 0xbe, 0x65,
-	0x97, 0x3c, 0xdd, 0x4a, 0x95, 0x3c, 0x9d, 0x53, 0xd8, 0x69, 0x93, 0x6b, 0x96, 0x0a, 0x9f, 0xd6,
-	0xe0, 0x28, 0x3d, 0x6a, 0x0c, 0x23, 0x24, 0x22, 0x91, 0x62, 0xa0, 0x74, 0x8a, 0xf1, 0x1a, 0x1c,
-	0x0b, 0xc7, 0x94, 0x77, 0x0c, 0xa6, 0xb9, 0x52, 0x70, 0xc7, 0x29, 0x5a, 0x6b, 0x7f, 0xbb, 0x27,
-	0x2c, 0x70, 0xde, 0xf4, 0xdd, 0x3e, 0x7e, 0x13, 0x41, 0x8d, 0xbc, 0x66, 0x79, 0x3e, 0x3e, 0xaf,
-	0x72, 0xb7, 0x9f, 0xac, 0x12, 0x6e, 0x5e, 0xc8, 0x39, 0x5a, 0xb0, 0xfb, 0x2d, 0x04, 0xb3, 0x6d,
-	0x96, 0xb3, 0xe0, 0x0b, 0x85, 0x4a, 0x44, 0x9b, 0x4f, 0xe4, 0x1d, 0x2e, 0x71, 0xd2, 0x61, 0x27,
-	0x27, 0x05, 0x4e, 0xb2, 0xea, 0x2c, 0x15, 0x38, 0xc9, 0x2e, 0xad, 0x7c, 0x1d, 0xc1, 0x6c, 0x97,
-	0xa1, 0xbc, 0xf8, 0x6c, 0x8e, 0xba, 0x8b, 0x80, 0x8d, 0x73, 0xb9, 0xc6, 0x0a, 0x1e, 0xde, 0x46,
-	0x30, 0xdf, 0x8d, 0xea, 0x11, 0x71, 0x1e, 0x62, 0x81, 0x5f, 0x34, 0xcf, 0xe7, 0x1b, 0x2c, 0x58,
-	0xf9, 0x00, 0xc1, 0xf1, 0x11, 0x83, 0xbb, 0x22, 0xcc, 0x0c, 0x6f, 0x14, 0xaf, 0x12, 0x6c, 0x6e,
-	0x16, 0xa2, 0x21, 0xb8, 0xfb, 0x2e, 0x82, 0xba, 0xd9, 0xe9, 0xb0, 0x2b, 0x93, 0x8b, 0x39, 0x2a,
-	0x31, 0xe4, 0xd2, 0xa5, 0xe6, 0x93, 0xf9, 0x09, 0x48, 0xec, 0x74, 0x89, 0xaf, 0xc8, 0x4e, 0x76,
-	0x91, 0xa1, 0x02, 0x3b, 0x07, 0x15, 0x1b, 0xfe, 0x00, 0x01, 0x70, 0xdd, 0x31, 0x8e, 0xd6, 0xf3,
-	0x49, 0x5c, 0x2a, 0x03, 0x6c, 0x6e, 0x14, 0x21, 0x21, 0xb8, 0xfa, 0x11, 0x02, 0xe0, 0xae, 0xce,
-	0xb8, 0xda, 0xc8, 0xe9, 0xaf, 0xb2, 0xa8, 0x36, 0x0b, 0xd1, 0x10, 0x7c, 0x7d, 0x87, 0xdb, 0x12,
-	0x4d, 0x56, 0xf0, 0x13, 0xc5, 0xaa, 0x7a, 0x9a, 0x17, 0x73, 0x8f, 0x97, 0x98, 0xe9, 0x12, 0x5f,
-	0x91, 0x99, 0xcc, 0xa2, 0xb6, 0xe6, 0xc5, 0x82, 0xe5, 0x63, 0xf8, 0xfb, 0x08, 0x1a, 0xdc, 0x8e,
-	0x76, 0xcc, 0x2e, 0x7e, 0x32, 0x9f, 0x0d, 0x44, 0xa5, 0x62, 0xcd, 0xf5, 0x02, 0x14, 0x24, 0xd3,
-	0xe6, 0x46, 0xc4, 0x44, 0xb4, 0x9e, 0xcf, 0x00, 0x64, 0x29, 0x6d, 0x14, 0x21, 0x21, 0xb8, 0xfa,
-	0x26, 0x82, 0x85, 0x6e, 0x80, 0xd1, 0xb2, 0x24, 0xed, 0x8b, 0x4a, 0xb2, 0x97, 0xc1, 0xbc, 0xe6,
-	0xd9, 0x3c, 0x43, 0x05, 0x23, 0xef, 0x21, 0x38, 0xde, 0x95, 0x90, 0x58, 0xc6, 0x8b, 0xd2, 0x46,
-	0x90, 0x44, 0xaf, 0xd5, 0x52, 0x8d, 0x34, 0x04, 0xfc, 0x0e, 0x82, 0x23, 0x1d, 0x09, 0x1a, 0x55,
-	0xe0, 0x26, 0x03, 0xa2, 0x6d, 0x5e, 0xc8, 0x39, 0x5a, 0xe2, 0x66, 0x20, 0xa1, 0x97, 0x0a, 0xdc,
-	0x64, 0xe0, 0xae, 0x0a, 0xdc, 0x64, 0x42, 0xa6, 0xef, 0x22, 0x58, 0x90, 0xb9, 0xf1, 0x70, 0x3e,
-	0x82, 0x9e, 0x7a, 0x0e, 0x94, 0xfd, 0x4d, 0x8d, 0x9f, 0x23, 0xf8, 0x5f, 0x33, 0x0e, 0x7d, 0x3e,
-	0xe5, 0xb8, 0xf2, 0xd1, 0xd5, 0x53, 0xdb, 0x6e, 0x33, 0x80, 0x2a, 0xb5, 0xed, 0x36, 0x13, 0xea,
-	0xf9, 0x05, 0x02, 0xbd, 0x9d, 0x82, 0xdc, 0x52, 0x9c, 0x6e, 0x28, 0xe6, 0xa6, 0x59, 0xcc, 0x6e,
-	0x16, 0xa2, 0x21, 0xf8, 0xfd, 0x31, 0x82, 0x95, 0x2e, 0x43, 0xae, 0x18, 0x92, 0x20, 0xff, 0x8f,
-	0x5a, 0xba, 0x50, 0x8c, 0xc3, 0x09, 0xe0, 0x99, 0xe0, 0x30, 0x85, 0xc3, 0x7e, 0xf6, 0x1c, 0x1e,
-	0x84, 0x50, 0xbe, 0x83, 0xe0, 0x68, 0x47, 0x0e, 0xc0, 0x2a, 0xd9, 0x71, 0xfa, 0x44, 0xde, 0x3c,
-	0x9f, 0x6f, 0x30, 0xe7, 0x66, 0xed, 0xd3, 0x79, 0x38, 0x91, 0x40, 0xc7, 0xd8, 0xf9, 0xee, 0x3d,
-	0x44, 0xcf, 0x95, 0xbc, 0x02, 0x4b, 0x61, 0xc3, 0x3c, 0xa0, 0x26, 0x4e, 0x61, 0xc3, 0x3c, 0xb0,
-	0xbc, 0x8d, 0x66, 0x5d, 0xa3, 0xb0, 0x2a, 0x4c, 0x25, 0x83, 0x3f, 0xa8, 0x4a, 0x4d, 0x25, 0x83,
-	0x3f, 0xb8, 0x1c, 0xed, 0x0d, 0x04, 0x8d, 0x5e, 0x50, 0xee, 0xa5, 0xb0, 0x5d, 0x26, 0x8b, 0xce,
-	0x14, 0xb6, 0xcb, 0x74, 0x75, 0xd9, 0x5b, 0x08, 0xaa, 0x7b, 0x96, 0xdd, 0x51, 0x88, 0xbb, 0x59,
-	0xd5, 0x63, 0x0a, 0x71, 0x37, 0xbb, 0x8e, 0x8b, 0x6e, 0x4b, 0x5d, 0xa9, 0x28, 0x46, 0x6d, 0xcb,
-	0x4e, 0xb1, 0x73, 0x21, 0xe7, 0x68, 0xc1, 0xcd, 0xfb, 0x08, 0x8e, 0x76, 0x63, 0xf5, 0x4e, 0x6a,
-	0xa9, 0x68, 0xba, 0xc4, 0x4b, 0x2d, 0x15, 0xcd, 0x2a, 0xb4, 0xfa, 0x00, 0xc1, 0x11, 0x9e, 0x8a,
-	0xf2, 0xaa, 0x17, 0x7c, 0x29, 0x67, 0xb5, 0x48, 0xac, 0x52, 0xa7, 0x79, 0xb9, 0x20, 0x15, 0xc1,
-	0xdd, 0x87, 0x08, 0xb4, 0x51, 0xaa, 0x36, 0x44, 0x1c, 0x9a, 0x37, 0x0f, 0xa1, 0xae, 0xa5, 0x79,
-	0xa9, 0x18, 0x91, 0x08, 0x5f, 0xa8, 0xdd, 0x31, 0xfd, 0x76, 0x4f, 0xc1, 0xe0, 0xb3, 0xaa, 0x50,
-	0x14, 0x0c, 0x3e, 0xb3, 0x0a, 0xe5, 0x21, 0xc4, 0x4c, 0xbe, 0x27, 0x7d, 0xa7, 0x0a, 0xe7, 0xfb,
-	0xac, 0x96, 0xba, 0xc9, 0x67, 0x7d, 0x1c, 0x6b, 0xed, 0x4f, 0x33, 0xb0, 0xb8, 0xe5, 0xec, 0x13,
-	0xd7, 0x96, 0xd1, 0xba, 0xf7, 0x79, 0x36, 0x1d, 0xbf, 0xb1, 0x29, 0x02, 0x0e, 0xad, 0xe7, 0x18,
-	0x9b, 0x00, 0xc0, 0x7f, 0x88, 0xe0, 0x58, 0x37, 0xfe, 0xa5, 0xa2, 0x5c, 0x90, 0x83, 0xfc, 0xb9,
-	0xa5, 0x5c, 0x90, 0x43, 0xfc, 0x23, 0x49, 0x6f, 0x72, 0xb6, 0xd6, 0x87, 0xc3, 0xbe, 0xd5, 0x36,
-	0xf9, 0xa7, 0x9a, 0x1e, 0x57, 0x3a, 0x39, 0x44, 0x88, 0x6e, 0xf3, 0x8c, 0xfa, 0x40, 0xce, 0xc6,
-	0xc6, 0x43, 0x30, 0xed, 0x17, 0xf3, 0x5e, 0xac, 0xb1, 0x2f, 0xec, 0xed, 0xce, 0xb2, 0x3f, 0x8f,
-	0xfc, 0x27, 0x00, 0x00, 0xff, 0xff, 0xc4, 0x56, 0xf4, 0x2b, 0x7a, 0x4f, 0x00, 0x00,
+	// 3405 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5c, 0xdb, 0x8f, 0x1c, 0xc5,
+	0xb9, 0x57, 0xcd, 0xce, 0xec, 0xec, 0x7c, 0x7b, 0xb1, 0xb7, 0xbc, 0xeb, 0x6d, 0x0f, 0x1c, 0x8e,
+	0xd5, 0x42, 0x3a, 0x3c, 0xa0, 0x3d, 0xb0, 0x1c, 0xc0, 0xc7, 0xd8, 0x98, 0xbd, 0x98, 0xf5, 0x1a,
+	0x8c, 0x4d, 0xcf, 0x62, 0x07, 0x48, 0x82, 0x7a, 0x67, 0x6a, 0x67, 0x1a, 0xcf, 0x74, 0x37, 0xdd,
+	0x3d, 0x6b, 0x46, 0x8a, 0x14, 0x81, 0x20, 0x21, 0x21, 0x81, 0xa0, 0x24, 0x4f, 0x3c, 0x24, 0x4a,
+	0xc2, 0x63, 0x22, 0x25, 0x8a, 0x84, 0x22, 0x94, 0x28, 0x4a, 0x94, 0x37, 0x50, 0x9e, 0xa2, 0x3c,
+	0x25, 0x7f, 0x41, 0xde, 0xf2, 0x07, 0x24, 0xaa, 0x4b, 0x77, 0x57, 0x5f, 0x76, 0xdd, 0x97, 0x6d,
+	0x50, 0x9e, 0xb6, 0xab, 0x7a, 0xea, 0xab, 0xaf, 0xbe, 0x5b, 0x7d, 0xf5, 0xab, 0x6f, 0x1b, 0x16,
+	0x5c, 0xe2, 0x1c, 0x18, 0x5d, 0xe2, 0xae, 0xda, 0x8e, 0xe5, 0x59, 0xf8, 0x7f, 0xba, 0xd6, 0x68,
+	0x75, 0x30, 0xd6, 0xef, 0x10, 0x63, 0xd5, 0xd6, 0x75, 0x77, 0xb5, 0xeb, 0x92, 0x55, 0xf1, 0x1b,
+	0x87, 0xf4, 0x0d, 0xd7, 0x73, 0x26, 0xab, 0xba, 0x6d, 0xa8, 0x5f, 0x87, 0xa5, 0x6b, 0x56, 0xcf,
+	0xd8, 0x9f, 0x74, 0xba, 0x03, 0x32, 0xd2, 0x5d, 0x8d, 0xbc, 0x36, 0x26, 0xae, 0x87, 0xef, 0x85,
+	0x96, 0xf8, 0xf9, 0x4e, 0x4f, 0x41, 0x67, 0xd1, 0x03, 0x2d, 0x2d, 0xec, 0xc0, 0x3b, 0xd0, 0x74,
+	0xf9, 0xef, 0x95, 0xda, 0xd9, 0xa9, 0x07, 0x66, 0xd7, 0xfe, 0x77, 0x35, 0xe3, 0x84, 0xab, 0x7c,
+	0x1e, 0xcd, 0x1f, 0xaf, 0xde, 0x84, 0x69, 0xde, 0x85, 0xdb, 0x30, 0xc3, 0x3b, 0x83, 0x19, 0x83,
+	0x36, 0x56, 0xa0, 0xe9, 0x8e, 0x47, 0x23, 0xdd, 0x99, 0x28, 0x35, 0xf6, 0xca, 0x6f, 0xe2, 0xd3,
+	0x30, 0xcd, 0x7f, 0xa5, 0x4c, 0xb1, 0x17, 0xa2, 0xa5, 0xee, 0xc3, 0x72, 0x6c, 0x61, 0xae, 0x6d,
+	0x99, 0x2e, 0xc1, 0xd7, 0x60, 0xc6, 0x11, 0xcf, 0x6c, 0x9a, 0xd9, 0xb5, 0x87, 0x33, 0x33, 0xef,
+	0x13, 0xd1, 0x02, 0x12, 0xea, 0x6b, 0x70, 0xea, 0x0a, 0xd1, 0x1d, 0x6f, 0x8f, 0xe8, 0x5e, 0x87,
+	0x78, 0xbe, 0xfc, 0x5e, 0x82, 0x96, 0x61, 0xba, 0x9e, 0x6e, 0x76, 0x89, 0xab, 0x20, 0x26, 0xa3,
+	0x0b, 0x99, 0xa7, 0x91, 0x09, 0x5e, 0x1e, 0x92, 0x11, 0x31, 0x3d, 0x2d, 0x24, 0xa7, 0x76, 0xa2,
+	0x53, 0x8a, 0x5f, 0xdc, 0x45, 0x65, 0xf7, 0x01, 0xf8, 0x14, 0x76, 0x7a, 0x42, 0x88, 0x52, 0x8f,
+	0xfa, 0x09, 0x82, 0xa5, 0xe8, 0x42, 0x2a, 0x91, 0x17, 0xde, 0x95, 0x05, 0xc3, 0x8d, 0xe7, 0xb1,
+	0xcc, 0xf4, 0x76, 0xc4, 0xc8, 0x2b, 0x7b, 0x9a, 0x1b, 0x11, 0xc9, 0x08, 0xe6, 0x23, 0xef, 0xca,
+	0x09, 0x83, 0xbe, 0x27, 0x8e, 0x73, 0x8d, 0xb8, 0xae, 0xde, 0x27, 0xc2, 0xb0, 0xa4, 0x1e, 0x75,
+	0x13, 0x5a, 0x1d, 0xaf, 0xc3, 0xc9, 0xe1, 0x25, 0x68, 0x74, 0xad, 0xb1, 0xe9, 0xb1, 0x69, 0xa6,
+	0x34, 0xde, 0xc0, 0x67, 0x61, 0xd6, 0x32, 0x87, 0x86, 0x49, 0x36, 0xd9, 0xbb, 0x1a, 0x7b, 0x27,
+	0x77, 0xa9, 0x2a, 0x40, 0xc7, 0xf3, 0xb9, 0x4e, 0xa7, 0xa2, 0xfe, 0x17, 0x34, 0x3a, 0xde, 0xba,
+	0x6d, 0x1f, 0xf2, 0xfa, 0x9f, 0x88, 0xd2, 0xd0, 0x3d, 0xc3, 0xf5, 0x8c, 0xae, 0x8b, 0x9f, 0x83,
+	0x19, 0x3f, 0x0e, 0x08, 0x55, 0xad, 0x65, 0xf7, 0x4b, 0x7f, 0x3d, 0x5a, 0x40, 0x03, 0x3f, 0x1f,
+	0xd5, 0x15, 0x25, 0xf8, 0x48, 0x0e, 0x82, 0xfe, 0xda, 0x24, 0x45, 0xe1, 0x0d, 0xa8, 0xeb, 0xb6,
+	0xed, 0x32, 0x99, 0xce, 0xae, 0xad, 0xe6, 0xa0, 0xb6, 0x6e, 0xdb, 0x1a, 0x1b, 0xab, 0xbe, 0x83,
+	0xe0, 0xf4, 0x36, 0xf1, 0xf9, 0x75, 0x77, 0xcc, 0x7d, 0xcb, 0x77, 0x3b, 0x05, 0x9a, 0x96, 0xed,
+	0x19, 0x96, 0xc9, 0x9d, 0xae, 0xa5, 0xf9, 0x4d, 0x2a, 0x40, 0xdd, 0xb6, 0x03, 0x6d, 0xf3, 0x06,
+	0xd5, 0x92, 0x98, 0xed, 0x39, 0x7d, 0xe4, 0x6b, 0x5a, 0xee, 0xa2, 0x86, 0xc4, 0x64, 0x7d, 0xdd,
+	0x1c, 0x4e, 0x94, 0xfa, 0x59, 0xf4, 0xc0, 0x8c, 0x16, 0x76, 0xa8, 0x3f, 0xad, 0xc1, 0x4a, 0x82,
+	0x95, 0x6a, 0x1c, 0xa7, 0x07, 0x8b, 0xfa, 0x70, 0xe8, 0xcf, 0xb4, 0x45, 0x3c, 0xdd, 0x18, 0xe6,
+	0x76, 0x20, 0x31, 0x9c, 0x8f, 0xd6, 0x92, 0x04, 0x71, 0x07, 0xc0, 0x0d, 0x0c, 0x4a, 0x68, 0x29,
+	0x8f, 0xce, 0xfd, 0xa1, 0x9a, 0x44, 0x46, 0xfd, 0x0c, 0xc1, 0x89, 0x6b, 0x46, 0xd7, 0xb1, 0xc4,
+	0x64, 0xcf, 0x10, 0x16, 0xb7, 0x3d, 0x62, 0xea, 0xc2, 0xa2, 0x5b, 0x9a, 0x68, 0x51, 0x0d, 0xda,
+	0x8e, 0xf5, 0x2a, 0xe9, 0x7a, 0x7e, 0xa4, 0x17, 0xcd, 0x50, 0x83, 0x53, 0x47, 0x68, 0xb0, 0x9e,
+	0xd4, 0xa0, 0x02, 0xcd, 0x03, 0xe2, 0xb8, 0x86, 0x65, 0x2a, 0x0d, 0x4e, 0x51, 0x34, 0xe9, 0x58,
+	0x62, 0x1e, 0x18, 0x8e, 0x65, 0xd2, 0x00, 0xaa, 0x4c, 0xf3, 0xb1, 0x52, 0x17, 0x9b, 0x73, 0x68,
+	0xe8, 0xae, 0xd2, 0x14, 0x73, 0xd2, 0x86, 0xfa, 0x69, 0x13, 0xe6, 0xe4, 0xf5, 0xdc, 0x25, 0xda,
+	0x14, 0x35, 0x3d, 0x89, 0xf1, 0x7a, 0x82, 0xf1, 0x1e, 0x71, 0xbb, 0x8e, 0xc1, 0x8c, 0x5b, 0x2c,
+	0x4b, 0xee, 0xa2, 0x73, 0x0e, 0xc9, 0x01, 0x19, 0x8a, 0x45, 0xf1, 0x06, 0xdb, 0x46, 0xc5, 0xbe,
+	0xdd, 0xe4, 0xee, 0x21, 0x9a, 0xf8, 0x2a, 0x34, 0x6c, 0xdd, 0x1b, 0xb8, 0x0a, 0x30, 0x8b, 0xfa,
+	0xbf, 0xbc, 0x16, 0x75, 0x43, 0xf7, 0x06, 0x1a, 0x27, 0xc1, 0xb6, 0x64, 0x4f, 0xf7, 0xc6, 0xae,
+	0x32, 0x23, 0xb6, 0x64, 0xd6, 0xc2, 0x04, 0xc0, 0x76, 0x2c, 0x9b, 0x38, 0x9e, 0x41, 0x5c, 0xa5,
+	0xc5, 0x26, 0xba, 0x9c, 0x79, 0x22, 0x59, 0xe0, 0xab, 0x37, 0x02, 0x3a, 0x97, 0x4d, 0xcf, 0x99,
+	0x68, 0x12, 0x61, 0xaa, 0x0c, 0xcf, 0x18, 0x11, 0xd7, 0xd3, 0x47, 0xb6, 0x32, 0xcb, 0x95, 0x11,
+	0x74, 0xe0, 0x9b, 0xd0, 0xb2, 0x1d, 0xeb, 0xc0, 0xe8, 0x11, 0xc7, 0x55, 0xe6, 0x18, 0x0f, 0xe7,
+	0x0a, 0xf1, 0xf0, 0x0c, 0x99, 0x68, 0x21, 0xa9, 0xd0, 0x52, 0xe6, 0x25, 0x4b, 0xa1, 0x4b, 0x7e,
+	0x76, 0xa3, 0xe3, 0x39, 0xba, 0x47, 0xfa, 0x13, 0x65, 0xa1, 0xcc, 0x92, 0x43, 0x3a, 0x62, 0xc9,
+	0x61, 0x07, 0x56, 0x61, 0x6e, 0x64, 0xf5, 0x76, 0x83, 0x55, 0x9f, 0x60, 0x3c, 0x44, 0xfa, 0xe2,
+	0xc6, 0x7e, 0x32, 0x69, 0xec, 0xf7, 0x01, 0xf0, 0xe9, 0x89, 0xb3, 0x31, 0x51, 0x16, 0xf9, 0xae,
+	0x17, 0xf6, 0xe0, 0x2f, 0x41, 0x6b, 0xdf, 0xd1, 0x47, 0xe4, 0x8e, 0xe5, 0xdc, 0x56, 0x30, 0x0b,
+	0x0d, 0xe7, 0x33, 0xaf, 0xe5, 0x69, 0x3a, 0xf2, 0x96, 0xe5, 0xdc, 0x16, 0xaa, 0x9b, 0x68, 0x21,
+	0xb1, 0xf6, 0x45, 0x38, 0x11, 0xd3, 0x28, 0x3e, 0x09, 0x53, 0xb7, 0xc9, 0x44, 0x38, 0x13, 0x7d,
+	0xa4, 0x12, 0x3e, 0xd0, 0x87, 0x63, 0xe2, 0xbb, 0x11, 0x6b, 0x9c, 0xaf, 0x9d, 0x43, 0x74, 0x78,
+	0x4c, 0x3a, 0x79, 0x86, 0xab, 0xeb, 0xb0, 0x98, 0xe0, 0x0e, 0x63, 0xa8, 0x9b, 0xd4, 0x2f, 0x39,
+	0x05, 0xf6, 0x2c, 0x3b, 0x64, 0x2d, 0xe2, 0x90, 0xea, 0xdf, 0x10, 0xcc, 0xfa, 0xfb, 0xe7, 0x78,
+	0x48, 0xa8, 0x0b, 0x38, 0xe3, 0x61, 0x18, 0x0d, 0x44, 0x8b, 0xe6, 0xb8, 0xf4, 0x69, 0x77, 0x62,
+	0xfb, 0x7c, 0x04, 0x6d, 0x6a, 0xb7, 0xba, 0xe7, 0x39, 0xc6, 0xde, 0xd8, 0xf3, 0xc3, 0x41, 0xd8,
+	0xc1, 0xe2, 0xa2, 0xee, 0x79, 0xc4, 0x09, 0x82, 0x81, 0x68, 0x66, 0x08, 0x06, 0x11, 0x8f, 0x98,
+	0x8e, 0x7b, 0x44, 0xdc, 0x78, 0x9a, 0x49, 0xe3, 0x51, 0xdf, 0x43, 0x70, 0x7a, 0xbd, 0xd7, 0xbb,
+	0xee, 0xbc, 0x60, 0xf7, 0x74, 0x8f, 0xc8, 0x4b, 0x95, 0x97, 0x84, 0x8e, 0x5a, 0x52, 0xed, 0x88,
+	0x25, 0x4d, 0x1d, 0xb9, 0xa4, 0x7a, 0x62, 0x49, 0xea, 0xef, 0x42, 0x81, 0xd3, 0xd0, 0x43, 0xd5,
+	0x45, 0x83, 0x8f, 0xaf, 0x2e, 0xfa, 0x8c, 0xbf, 0x0a, 0x33, 0x22, 0x2c, 0x4c, 0xc4, 0x46, 0xb9,
+	0x51, 0x24, 0xac, 0xf9, 0xc1, 0x46, 0xf8, 0x5d, 0x40, 0xb3, 0xfd, 0x04, 0xcc, 0x47, 0x5e, 0xe5,
+	0x32, 0xba, 0x73, 0x30, 0x13, 0x64, 0x0a, 0x18, 0xea, 0x5d, 0xab, 0xc7, 0xc5, 0xd7, 0xd0, 0xd8,
+	0x33, 0x15, 0xce, 0x48, 0xe4, 0x9f, 0xc2, 0xd6, 0x44, 0x53, 0xfd, 0x2b, 0x82, 0x53, 0xdb, 0xc4,
+	0xbb, 0xfc, 0x3a, 0xf5, 0x4b, 0x9a, 0x5e, 0x89, 0xdc, 0x07, 0x43, 0xdd, 0x0b, 0x95, 0xc0, 0x9e,
+	0x2b, 0xd8, 0x7a, 0x22, 0x5b, 0x5d, 0x23, 0xbe, 0xd5, 0xc9, 0x67, 0xb8, 0xe9, 0xd8, 0x19, 0x2e,
+	0x16, 0x80, 0x9a, 0x89, 0x00, 0xa4, 0xfe, 0x06, 0xc1, 0x52, 0x74, 0x65, 0xd5, 0xa4, 0x52, 0x91,
+	0x35, 0xd4, 0x8e, 0x5a, 0xc3, 0xd4, 0xe1, 0xe7, 0xd0, 0x7a, 0xe4, 0x1c, 0xaa, 0xfe, 0x72, 0x0a,
+	0x96, 0x36, 0x1d, 0x22, 0x39, 0x87, 0x50, 0xcb, 0x75, 0x68, 0x0a, 0xda, 0x82, 0xf5, 0x47, 0x0b,
+	0xc5, 0x7f, 0xcd, 0xa7, 0x82, 0x5f, 0x80, 0x06, 0x75, 0x30, 0xff, 0xf4, 0x74, 0x29, 0x33, 0xb9,
+	0x74, 0x07, 0xd6, 0x38, 0x35, 0xfc, 0x32, 0xd4, 0x3d, 0xbd, 0x4f, 0x73, 0x3e, 0x4a, 0x75, 0x3b,
+	0x33, 0xd5, 0xb4, 0x45, 0xaf, 0xee, 0xea, 0x7d, 0xb1, 0x33, 0x33, 0xa2, 0xf8, 0x65, 0xf9, 0x24,
+	0x51, 0x67, 0x33, 0x5c, 0x2c, 0x24, 0x86, 0x94, 0x33, 0x45, 0xfb, 0x71, 0x68, 0x05, 0xf3, 0xe5,
+	0xf2, 0xc1, 0xb7, 0x10, 0x2c, 0xc7, 0xd8, 0xff, 0x02, 0x0c, 0x4e, 0xbd, 0x0a, 0x4b, 0x5b, 0x64,
+	0x48, 0x12, 0x96, 0x73, 0xd7, 0xac, 0x72, 0xdf, 0x72, 0xba, 0x7c, 0x59, 0x33, 0x1a, 0x6f, 0xa8,
+	0xfb, 0xb0, 0x1c, 0xa3, 0x55, 0x0d, 0xec, 0xf1, 0x30, 0x2c, 0x86, 0xe7, 0x9e, 0x4c, 0x0c, 0xab,
+	0xbf, 0x46, 0x80, 0xe5, 0x31, 0xd5, 0x88, 0x5a, 0x72, 0xb7, 0xda, 0x71, 0xb8, 0x9b, 0xba, 0x24,
+	0x73, 0xed, 0xe3, 0x63, 0xea, 0xc7, 0x3c, 0x08, 0x87, 0xdd, 0xd5, 0xac, 0xe6, 0x79, 0xe9, 0x44,
+	0xcf, 0xdd, 0xbd, 0xe0, 0x72, 0x02, 0x32, 0xea, 0x3f, 0x10, 0x9c, 0x89, 0x04, 0x01, 0xba, 0x87,
+	0x65, 0xc4, 0xfd, 0x9c, 0x48, 0x06, 0xcf, 0x19, 0xd2, 0x32, 0x33, 0x74, 0xe8, 0xac, 0x47, 0xa5,
+	0xf3, 0x25, 0x73, 0x43, 0xf5, 0x36, 0xb4, 0xd3, 0xe6, 0xad, 0xc6, 0x2b, 0x1e, 0x93, 0x81, 0x09,
+	0x1a, 0x5c, 0xdd, 0xcc, 0xae, 0xb1, 0x92, 0x18, 0x58, 0x8d, 0x45, 0x5d, 0x8d, 0xee, 0x1e, 0xb9,
+	0x0f, 0x7a, 0xd2, 0x96, 0xa1, 0x7e, 0x84, 0x40, 0x49, 0xee, 0x27, 0x99, 0x2c, 0x29, 0x4c, 0x90,
+	0x6b, 0x91, 0x04, 0xb9, 0x03, 0x75, 0xfa, 0x24, 0x90, 0x87, 0xd2, 0x7b, 0x1b, 0x23, 0xa6, 0xbe,
+	0x1a, 0xb3, 0x78, 0xce, 0x66, 0x35, 0x26, 0xf0, 0x5d, 0x9e, 0x29, 0xe7, 0xb6, 0x81, 0x8a, 0xb6,
+	0x75, 0xf5, 0x4d, 0x04, 0x2b, 0x09, 0x7e, 0xaa, 0x31, 0x2d, 0x05, 0x9a, 0x1a, 0xd3, 0x22, 0x5f,
+	0x43, 0x4b, 0xf3, 0x9b, 0x6a, 0x07, 0xce, 0x44, 0x77, 0xa5, 0xec, 0x62, 0x51, 0xa0, 0xe9, 0x44,
+	0x89, 0x8a, 0x26, 0xf5, 0xec, 0x34, 0xa2, 0xd5, 0xa8, 0xf5, 0x51, 0x58, 0x0e, 0x1d, 0x94, 0x66,
+	0x1b, 0xd9, 0x1c, 0xfb, 0x5f, 0x11, 0xa8, 0x92, 0x8f, 0xab, 0x46, 0xf8, 0x5f, 0x11, 0xe9, 0x1b,
+	0xb7, 0x9e, 0x9d, 0xcc, 0xa4, 0xd2, 0xb9, 0x8b, 0x27, 0x70, 0xc5, 0x73, 0xac, 0x57, 0x60, 0x25,
+	0x62, 0x9b, 0xbb, 0x7a, 0x3f, 0x9b, 0xe2, 0xc5, 0x24, 0xb5, 0x94, 0x49, 0xa6, 0xa4, 0x49, 0x54,
+	0x23, 0x16, 0x83, 0xd8, 0x04, 0xd5, 0x18, 0xc1, 0xa7, 0x08, 0x96, 0x43, 0x5f, 0xca, 0x6c, 0x05,
+	0xf8, 0xcb, 0x11, 0xdd, 0x5c, 0xc9, 0xe3, 0xd9, 0xc9, 0xb9, 0x8e, 0x4f, 0x35, 0x7d, 0x39, 0x52,
+	0x55, 0x68, 0x9b, 0xea, 0xb3, 0xa0, 0x44, 0x3c, 0x35, 0xbb, 0xe4, 0x30, 0xd4, 0x6f, 0x93, 0x89,
+	0xef, 0xfa, 0xec, 0x99, 0x46, 0xf3, 0x14, 0x6a, 0xd5, 0x70, 0x3e, 0x81, 0xd9, 0x2b, 0x44, 0x1f,
+	0x7a, 0x83, 0xcd, 0x01, 0xe9, 0xde, 0xa6, 0xec, 0x8c, 0xfc, 0x83, 0x7a, 0x4b, 0x63, 0xcf, 0x0c,
+	0x79, 0xb0, 0x1c, 0x8e, 0x56, 0x37, 0x34, 0xf6, 0x4c, 0x8f, 0x90, 0x86, 0xe9, 0x11, 0xe7, 0x40,
+	0x1f, 0x32, 0x63, 0x6d, 0x68, 0x41, 0x9b, 0xea, 0x83, 0x61, 0x2f, 0xec, 0x00, 0xd9, 0xd0, 0x78,
+	0x83, 0xea, 0x6d, 0xec, 0x0c, 0xc5, 0x81, 0x9a, 0x3e, 0xaa, 0x7f, 0xae, 0xc3, 0x52, 0xda, 0xc9,
+	0x27, 0x76, 0x79, 0x85, 0x12, 0x97, 0x57, 0x47, 0x9f, 0x6e, 0xef, 0x85, 0x16, 0x31, 0x7b, 0xb6,
+	0x65, 0x98, 0x1e, 0x3f, 0xeb, 0xb5, 0xb4, 0xb0, 0x83, 0x32, 0x3e, 0xb0, 0x5c, 0x4f, 0x82, 0xd2,
+	0x83, 0xb6, 0x04, 0xeb, 0x36, 0x22, 0xb0, 0xee, 0x28, 0x92, 0x14, 0x4e, 0x33, 0x1b, 0xbf, 0x56,
+	0xea, 0x70, 0x77, 0x24, 0xbc, 0x7b, 0x13, 0x66, 0x07, 0xa1, 0x4a, 0x18, 0x8c, 0x90, 0x27, 0x8d,
+	0x91, 0xd4, 0xa9, 0xc9, 0x84, 0xa2, 0x20, 0xd9, 0x4c, 0x1c, 0x24, 0x7b, 0x05, 0x16, 0x7a, 0xba,
+	0xa7, 0x6f, 0x12, 0xaa, 0xc6, 0x1d, 0x73, 0xdf, 0x52, 0x5a, 0x6c, 0xe2, 0xc7, 0x33, 0x4f, 0xbc,
+	0x15, 0x19, 0xae, 0xc5, 0xc8, 0x25, 0x50, 0x38, 0x48, 0xa2, 0x70, 0x65, 0x53, 0xe1, 0x3d, 0x58,
+	0x88, 0x32, 0x91, 0x0a, 0x72, 0xd2, 0xcc, 0x8c, 0xf4, 0x43, 0x8c, 0x53, 0xb4, 0xf0, 0xfd, 0x30,
+	0xaf, 0x1f, 0xe8, 0xc6, 0x50, 0xdf, 0x1b, 0x92, 0x97, 0x2c, 0xd3, 0x8f, 0xc2, 0xd1, 0x4e, 0xf5,
+	0x16, 0xac, 0xa4, 0x69, 0xf4, 0x19, 0x32, 0x29, 0x67, 0xb7, 0xaa, 0x07, 0x2b, 0x9a, 0x80, 0xa2,
+	0x03, 0x0c, 0x40, 0x84, 0x90, 0x17, 0xa9, 0xb7, 0xf1, 0x2e, 0xe1, 0xf3, 0x25, 0xb1, 0x85, 0x80,
+	0x9c, 0xfa, 0x2d, 0x04, 0x4a, 0x72, 0xda, 0x6a, 0x76, 0xf0, 0xbb, 0xdd, 0xd0, 0xbf, 0x08, 0x67,
+	0x5e, 0x30, 0x9d, 0x43, 0x64, 0x50, 0xee, 0xf2, 0x9f, 0x1e, 0x92, 0x52, 0x48, 0x57, 0x13, 0x53,
+	0x6f, 0xc0, 0xc9, 0xa0, 0xd0, 0xe0, 0x78, 0xd8, 0xdf, 0x83, 0x45, 0x89, 0x62, 0x35, 0x5c, 0xff,
+	0x0a, 0xc1, 0xd2, 0xd3, 0x86, 0xd9, 0xf3, 0xa5, 0x13, 0x6c, 0x60, 0x0f, 0xc2, 0x62, 0xd7, 0x32,
+	0xdd, 0xf1, 0x88, 0x38, 0x9d, 0xd8, 0x12, 0x92, 0x2f, 0x0a, 0x03, 0xb2, 0x67, 0x61, 0x56, 0x20,
+	0xb0, 0x34, 0xcd, 0xf5, 0x11, 0x71, 0xa9, 0x8b, 0xc1, 0xbf, 0x34, 0xc9, 0x68, 0xf0, 0xad, 0x92,
+	0x3e, 0xab, 0x7f, 0x44, 0xb0, 0x1c, 0x63, 0xba, 0x1a, 0xdb, 0x7d, 0x39, 0x59, 0xd5, 0x71, 0x6c,
+	0xf8, 0x9e, 0xfa, 0x31, 0x62, 0xc9, 0xf7, 0x75, 0x93, 0xc4, 0xad, 0x3e, 0x9f, 0xec, 0x1f, 0x84,
+	0x45, 0xff, 0xbe, 0xae, 0x13, 0x0b, 0x34, 0xc9, 0x17, 0x78, 0x15, 0xb0, 0xdf, 0xb9, 0x13, 0x1a,
+	0x1f, 0x57, 0x4d, 0xca, 0x9b, 0x40, 0xfe, 0x75, 0x49, 0xfe, 0x7f, 0xe0, 0xe9, 0x7f, 0x84, 0xf3,
+	0x6a, 0x14, 0x20, 0xc7, 0xc0, 0xda, 0xf1, 0xc6, 0xc0, 0xb7, 0x39, 0xd4, 0x55, 0xd2, 0xf0, 0xf3,
+	0x09, 0x1f, 0x4b, 0x60, 0xb4, 0x24, 0xcc, 0xa5, 0x28, 0x1f, 0xff, 0x81, 0xb6, 0xec, 0xc2, 0x3d,
+	0xfc, 0xb4, 0xe2, 0xbf, 0xec, 0xb0, 0x24, 0xea, 0x58, 0xe2, 0xa0, 0x94, 0xa1, 0x4d, 0xc9, 0x19,
+	0x9a, 0x3a, 0x82, 0x7b, 0xd3, 0x27, 0xad, 0x26, 0x54, 0xbe, 0x57, 0xf3, 0x31, 0x37, 0x7f, 0xbe,
+	0x1c, 0x10, 0xe3, 0xdd, 0xd6, 0xe8, 0x46, 0xb2, 0x4d, 0x7e, 0x59, 0xd1, 0xc9, 0x09, 0x41, 0xa6,
+	0xb1, 0x55, 0x25, 0x06, 0x39, 0x8c, 0x2b, 0xbd, 0x52, 0x10, 0xf2, 0x02, 0x2c, 0xdd, 0xd2, 0xbd,
+	0xee, 0x20, 0x1e, 0x2c, 0xef, 0x87, 0x79, 0x97, 0x0c, 0xf7, 0xe3, 0xbe, 0x1a, 0xed, 0x54, 0x3f,
+	0xaa, 0xc1, 0x72, 0x6c, 0x78, 0x35, 0x6e, 0x76, 0x1a, 0xa6, 0xf5, 0xae, 0x27, 0xe5, 0x99, 0xbc,
+	0x85, 0xaf, 0x72, 0xc1, 0x72, 0x00, 0xb0, 0x78, 0x69, 0x06, 0x53, 0x89, 0x1c, 0x15, 0xeb, 0xc7,
+	0x1b, 0x15, 0x9f, 0x85, 0x93, 0xdb, 0xc4, 0x13, 0xd5, 0xac, 0x99, 0x2c, 0x5b, 0xbe, 0x57, 0xac,
+	0x45, 0xef, 0x15, 0xd5, 0x0e, 0x0b, 0xb1, 0xeb, 0xc3, 0x61, 0x1e, 0x82, 0xf7, 0x01, 0xdc, 0x31,
+	0xbc, 0x01, 0x1f, 0x22, 0xae, 0x81, 0xa4, 0x1e, 0xf5, 0xc7, 0x88, 0x5f, 0xd2, 0x08, 0x92, 0x95,
+	0xa9, 0xd1, 0x0d, 0x19, 0x08, 0xea, 0x6f, 0x99, 0xb5, 0xb1, 0xa7, 0x8e, 0xb8, 0x2f, 0x15, 0xc7,
+	0x85, 0x48, 0xa7, 0xfa, 0x0b, 0x1e, 0xd3, 0xa5, 0x85, 0x57, 0xc3, 0xe5, 0xb6, 0xc4, 0x65, 0xa1,
+	0x7a, 0x65, 0xbf, 0xac, 0xf8, 0x3a, 0x9c, 0x12, 0xe0, 0xc3, 0x31, 0x69, 0x9e, 0x04, 0x97, 0x7f,
+	0x55, 0x0a, 0x40, 0x7d, 0x03, 0xc1, 0x29, 0xb9, 0x1e, 0xba, 0x34, 0xe3, 0x87, 0x15, 0x5e, 0x1f,
+	0x71, 0x45, 0x4e, 0xa2, 0xb5, 0xe6, 0xd5, 0x61, 0x36, 0xa7, 0xd7, 0x7b, 0xbd, 0x2d, 0x62, 0x13,
+	0xb3, 0x47, 0xcc, 0xae, 0x11, 0x66, 0x2c, 0xaf, 0xc0, 0x5c, 0x4f, 0xea, 0x16, 0x75, 0xd9, 0x4f,
+	0x64, 0xbf, 0xea, 0x16, 0x59, 0x4d, 0x40, 0x7b, 0xa2, 0x45, 0x08, 0xaa, 0x03, 0x86, 0xb5, 0x47,
+	0xa7, 0xae, 0x66, 0x91, 0x5f, 0x83, 0x33, 0xfc, 0xe6, 0xfa, 0x0b, 0x59, 0xe7, 0xdf, 0x11, 0xe0,
+	0xe4, 0x8f, 0xf0, 0x2e, 0xcc, 0xf8, 0x89, 0x9f, 0x58, 0x63, 0xf1, 0xf8, 0x1d, 0x50, 0x8a, 0x56,
+	0xec, 0xd5, 0x8e, 0xaf, 0x62, 0xaf, 0x0d, 0x33, 0xd6, 0x01, 0x71, 0x1c, 0xa3, 0xc7, 0x4f, 0x5c,
+	0x33, 0x5a, 0xd0, 0xa6, 0x07, 0xe2, 0x34, 0xf1, 0x56, 0x79, 0x6b, 0x98, 0xa6, 0xc8, 0xa3, 0x2f,
+	0x17, 0x7e, 0x8f, 0xa0, 0xbd, 0x4d, 0xbc, 0x4d, 0xcb, 0xfc, 0x1c, 0xb8, 0xc4, 0x9d, 0xa4, 0x1a,
+	0x0a, 0xde, 0x45, 0x87, 0x74, 0xfc, 0x25, 0xdc, 0x70, 0xac, 0xcf, 0x69, 0x09, 0xbe, 0x55, 0x95,
+	0x5d, 0x42, 0x40, 0x47, 0xfd, 0xc9, 0x34, 0xcc, 0x47, 0xca, 0xaa, 0xf1, 0x8b, 0x30, 0x37, 0x92,
+	0x7e, 0x5c, 0xae, 0xec, 0x27, 0x42, 0xaa, 0xd2, 0xb3, 0x09, 0x7e, 0x1e, 0x66, 0x45, 0x74, 0x37,
+	0xf7, 0x2d, 0x3f, 0xb7, 0xce, 0xbd, 0x53, 0xca, 0x34, 0xc2, 0xdb, 0xe6, 0x7a, 0xe9, 0xdb, 0xe6,
+	0xa8, 0x01, 0x36, 0x8e, 0xc7, 0x00, 0xa3, 0x26, 0x31, 0x7d, 0x3c, 0x26, 0x81, 0x77, 0xc5, 0xe9,
+	0xb5, 0xc9, 0xe8, 0x3d, 0x55, 0xac, 0x3a, 0x3f, 0x51, 0x43, 0xb5, 0x06, 0x4b, 0xb2, 0x2d, 0xdc,
+	0xe4, 0xd8, 0x8f, 0xab, 0xcc, 0xb0, 0x33, 0x72, 0xea, 0x3b, 0x7c, 0x0d, 0x9a, 0xac, 0x0e, 0xbf,
+	0xeb, 0x0a, 0xbc, 0xba, 0x50, 0x2d, 0xbf, 0x4f, 0xa3, 0xf8, 0x55, 0xd3, 0x27, 0x08, 0x94, 0xf0,
+	0xa6, 0x51, 0xfc, 0xfb, 0x41, 0x45, 0x5e, 0x7e, 0x23, 0x5e, 0x01, 0x54, 0xf4, 0xdf, 0x23, 0x82,
+	0x12, 0xa0, 0xab, 0x80, 0xb7, 0xc8, 0x30, 0x56, 0x02, 0x44, 0xd3, 0xef, 0x20, 0x16, 0xfb, 0xff,
+	0x6e, 0x22, 0xf5, 0x1c, 0x52, 0xa0, 0xa5, 0x45, 0x69, 0xb9, 0x36, 0x03, 0xe2, 0xa3, 0xff, 0x70,
+	0x84, 0xe2, 0xff, 0x70, 0x74, 0x17, 0x6c, 0xfc, 0xb7, 0x88, 0x65, 0xa5, 0x55, 0x17, 0x23, 0xdd,
+	0x4a, 0x14, 0x23, 0x65, 0x4f, 0x29, 0x92, 0x6b, 0x96, 0x4a, 0x92, 0xd6, 0x60, 0x81, 0x1e, 0x02,
+	0xec, 0x10, 0x23, 0x88, 0xd5, 0x8a, 0xa2, 0x64, 0xad, 0xe8, 0xeb, 0x70, 0x22, 0x18, 0x53, 0xdd,
+	0x01, 0xd5, 0xb6, 0xc3, 0xc2, 0x03, 0xd1, 0x5a, 0xfb, 0xcb, 0x3d, 0x41, 0xe9, 0xf1, 0xa6, 0xe7,
+	0x0c, 0xf1, 0x5b, 0x08, 0x1a, 0xe4, 0x75, 0xc3, 0xf5, 0xf0, 0x85, 0x3c, 0xb7, 0xee, 0xf1, 0xfa,
+	0xdd, 0xf6, 0xc5, 0x82, 0xa3, 0x05, 0xbb, 0xdf, 0x44, 0x30, 0xdd, 0x65, 0x39, 0x0b, 0xbe, 0x58,
+	0xaa, 0x78, 0xb3, 0xfd, 0x64, 0xd1, 0xe1, 0x12, 0x27, 0x3d, 0x76, 0xa6, 0xc9, 0xc1, 0x49, 0x5a,
+	0x05, 0x64, 0x0e, 0x4e, 0xd2, 0x8b, 0x1e, 0xdf, 0x40, 0x30, 0xdd, 0x67, 0xf8, 0x2b, 0x3e, 0x5f,
+	0xa0, 0x22, 0xc2, 0x67, 0xe3, 0x89, 0x42, 0x63, 0x05, 0x0f, 0xef, 0x20, 0x98, 0xed, 0x87, 0x95,
+	0x82, 0xb8, 0x08, 0x31, 0xdf, 0x2f, 0xda, 0x17, 0x8a, 0x0d, 0x16, 0xac, 0x7c, 0x88, 0xe0, 0xe4,
+	0x98, 0x01, 0x51, 0x21, 0x9a, 0x85, 0x37, 0xca, 0xd7, 0xef, 0xb5, 0x37, 0x4b, 0xd1, 0x10, 0xdc,
+	0x7d, 0x07, 0x41, 0x53, 0xef, 0xf5, 0xd8, 0x65, 0xc6, 0xa5, 0x02, 0x35, 0x12, 0x72, 0x51, 0x51,
+	0xfb, 0xa9, 0xe2, 0x04, 0x24, 0x76, 0xfa, 0xc4, 0xcb, 0xc9, 0x4e, 0x7a, 0xf9, 0x5f, 0x0e, 0x76,
+	0x0e, 0x2b, 0x03, 0xfc, 0x3e, 0x02, 0xe0, 0xba, 0x63, 0x1c, 0xad, 0x17, 0x93, 0xb8, 0x54, 0xa0,
+	0xd7, 0xde, 0x28, 0x43, 0x42, 0x70, 0xf5, 0x43, 0x04, 0xc0, 0x5d, 0x9d, 0x71, 0xb5, 0x51, 0xd0,
+	0x5f, 0x65, 0x51, 0x6d, 0x96, 0xa2, 0x21, 0xf8, 0xfa, 0x36, 0xb7, 0x25, 0x9a, 0xac, 0xe0, 0x27,
+	0xcb, 0xd5, 0xdb, 0xb4, 0x2f, 0x15, 0x1e, 0x2f, 0x31, 0xd3, 0x27, 0x5e, 0x4e, 0x66, 0x52, 0xcb,
+	0xcd, 0xda, 0x97, 0x4a, 0x16, 0x76, 0xe1, 0xef, 0x21, 0x68, 0x71, 0x3b, 0xda, 0xd5, 0xfb, 0xf8,
+	0xa9, 0x62, 0x36, 0x10, 0x16, 0x71, 0xb5, 0xd7, 0x4b, 0x50, 0x90, 0x4c, 0x9b, 0x1b, 0x11, 0x13,
+	0xd1, 0x7a, 0x31, 0x03, 0x90, 0xa5, 0xb4, 0x51, 0x86, 0x84, 0xe0, 0xea, 0x1b, 0x08, 0xe6, 0xfb,
+	0x3e, 0x7a, 0xca, 0x92, 0xb4, 0xff, 0xcf, 0x25, 0x7b, 0x19, 0x66, 0x6b, 0x9f, 0x2f, 0x32, 0x54,
+	0x30, 0xf2, 0x3e, 0x82, 0x93, 0x7d, 0x09, 0x23, 0x65, 0xbc, 0xe4, 0xda, 0x08, 0xe2, 0xb8, 0x72,
+	0xbe, 0x54, 0x23, 0x09, 0xce, 0xbe, 0x8b, 0x60, 0xae, 0x27, 0x81, 0x96, 0x39, 0xb8, 0x49, 0x01,
+	0x4f, 0xdb, 0x17, 0x0b, 0x8e, 0x96, 0xb8, 0x19, 0x49, 0xb8, 0x62, 0x0e, 0x6e, 0x52, 0x10, 0xd1,
+	0x1c, 0xdc, 0xa4, 0x82, 0x99, 0xef, 0x21, 0x98, 0x97, 0xb9, 0x71, 0x71, 0x31, 0x82, 0x6e, 0xfe,
+	0x1c, 0x28, 0xfd, 0x7b, 0x17, 0x3f, 0x43, 0xf0, 0xdf, 0x7a, 0x14, 0x94, 0x7c, 0xda, 0x72, 0xe4,
+	0xa3, 0xab, 0x9b, 0x6f, 0xbb, 0x4d, 0x01, 0xaa, 0xf2, 0x6d, 0xb7, 0xa9, 0x50, 0xcf, 0xcf, 0x11,
+	0xa8, 0xdd, 0x04, 0xe4, 0x96, 0xe0, 0x74, 0x23, 0x67, 0x6e, 0x9a, 0xc6, 0xec, 0x66, 0x29, 0x1a,
+	0x82, 0xdf, 0x1f, 0x21, 0x58, 0xe9, 0x33, 0xe4, 0x8a, 0x21, 0x09, 0xf2, 0x6f, 0xf2, 0xa5, 0x0b,
+	0xe5, 0x38, 0x3c, 0x02, 0x3c, 0x13, 0x1c, 0x26, 0x70, 0xda, 0xcf, 0x9f, 0xc3, 0xc3, 0x10, 0xca,
+	0x77, 0x11, 0x2c, 0xf4, 0xe4, 0x00, 0x9c, 0x27, 0x3b, 0x4e, 0x9e, 0xc8, 0xdb, 0x17, 0x8a, 0x0d,
+	0xe6, 0xdc, 0xac, 0x7d, 0x36, 0x0b, 0xa7, 0x62, 0xe8, 0x18, 0x3b, 0xdf, 0xbd, 0x8f, 0xe8, 0xb9,
+	0x92, 0xd7, 0x46, 0xe5, 0xd8, 0x30, 0x0f, 0xa9, 0x56, 0xcb, 0xb1, 0x61, 0x1e, 0x5a, 0x78, 0x46,
+	0xb3, 0xae, 0x71, 0x50, 0xaf, 0x95, 0x27, 0x83, 0x3f, 0xac, 0x7e, 0x2c, 0x4f, 0x06, 0x7f, 0x78,
+	0xa1, 0xd8, 0x9b, 0x08, 0x5a, 0x03, 0xbf, 0x10, 0x2b, 0xc7, 0x76, 0x19, 0x2f, 0x07, 0xcb, 0xb1,
+	0x5d, 0x26, 0xeb, 0xbe, 0xde, 0x46, 0x50, 0xdf, 0x37, 0xcc, 0x5e, 0x8e, 0xb8, 0x9b, 0x56, 0xd7,
+	0x95, 0x23, 0xee, 0xa6, 0x57, 0x58, 0xd1, 0x6d, 0xa9, 0x2f, 0x95, 0xab, 0xe4, 0xdb, 0xb2, 0x13,
+	0xec, 0x5c, 0x2c, 0x38, 0x5a, 0x70, 0xf3, 0x01, 0x82, 0x85, 0x7e, 0xa4, 0x12, 0x29, 0x5f, 0x2a,
+	0x9a, 0x2c, 0xbe, 0xca, 0x97, 0x8a, 0xa6, 0x95, 0x40, 0x7d, 0x88, 0x60, 0x8e, 0xa7, 0xa2, 0xbc,
+	0x1e, 0x05, 0x6f, 0x15, 0xac, 0xe3, 0x88, 0xd4, 0xd0, 0xb4, 0x2f, 0x97, 0xa4, 0x22, 0xb8, 0xfb,
+	0x08, 0x81, 0x32, 0x4e, 0x54, 0x6d, 0x88, 0x43, 0xf3, 0xe6, 0x31, 0x54, 0x9c, 0xb4, 0xb7, 0xca,
+	0x11, 0x09, 0xf1, 0x85, 0xc6, 0x1d, 0xdd, 0xeb, 0x0e, 0x72, 0x18, 0x7c, 0x5a, 0x7d, 0x48, 0x0e,
+	0x83, 0x4f, 0xad, 0x0f, 0x79, 0x08, 0x31, 0x93, 0x1f, 0x48, 0xdf, 0x90, 0xc2, 0xc5, 0x3e, 0x79,
+	0x95, 0xdf, 0xe4, 0xd3, 0x3e, 0x5c, 0xb5, 0xf6, 0xa7, 0x29, 0x58, 0xdc, 0xb6, 0x0e, 0x88, 0x63,
+	0xca, 0x68, 0xdd, 0x07, 0x3c, 0x9b, 0x8e, 0xde, 0xd8, 0x94, 0x01, 0x87, 0xd6, 0x0b, 0x8c, 0x8d,
+	0x01, 0xe0, 0x3f, 0x40, 0x70, 0xa2, 0x1f, 0xfd, 0x8a, 0x50, 0x21, 0xc8, 0x41, 0xfe, 0x14, 0x52,
+	0x21, 0xc8, 0x21, 0xfa, 0x01, 0xa3, 0xb7, 0x38, 0x5b, 0xeb, 0xb6, 0x3d, 0x34, 0xba, 0x3a, 0xff,
+	0x8c, 0xd2, 0xe3, 0xb9, 0x4e, 0x0e, 0x21, 0xa2, 0xdb, 0x3e, 0x97, 0x7f, 0x20, 0x67, 0x63, 0xe3,
+	0x21, 0xc8, 0xfa, 0x35, 0xbb, 0x97, 0x1a, 0xec, 0xeb, 0x77, 0x7b, 0xd3, 0xec, 0xcf, 0x23, 0xff,
+	0x0e, 0x00, 0x00, 0xff, 0xff, 0x35, 0xc6, 0x35, 0x3f, 0x16, 0x4f, 0x00, 0x00,
 }
diff --git a/server/core/proto/services.proto b/server/core/proto/services.proto
index 330d08b..64ac5e7 100644
--- a/server/core/proto/services.proto
+++ b/server/core/proto/services.proto
@@ -149,7 +149,7 @@ message MicroService {
     string status = 8; // UP|DOWN
     map<string, string> properties = 9;
     string timestamp = 11;
-    repeated DependencyKey providers = 12;
+    repeated MicroServiceKey providers = 12;
     string alias = 13;
     map<string, string> LBStrategy = 14;
     string modTimestamp = 15;
@@ -518,16 +518,10 @@ message CreateDependenciesRequest {
     repeated ConsumerDependency dependencies = 1;
 }
 
-message DependencyKey {
-    string appId = 1;
-    string serviceName = 2;
-    string version = 3;
-    string environment = 4;
-}
-
 message ConsumerDependency {
-    DependencyKey consumer = 1;
-    repeated DependencyKey providers = 2;
+    MicroServiceKey consumer = 1;
+    repeated MicroServiceKey providers = 2;
+    bool override = 3;
 }
 
 message CreateDependenciesResponse {
diff --git a/server/govern/service.go b/server/govern/service.go
index f3c0840..eea638f 100644
--- a/server/govern/service.go
+++ b/server/govern/service.go
@@ -324,7 +324,7 @@ func getServiceDetailUtil(ctx context.Context, serviceDetailOpt ServiceDetailOpt
 			serviceDetail.SchemaInfos = schemas
 		case "dependencies":
 			service := serviceDetailOpt.service
-			dr := serviceUtil.NewDependencyRelation(ctx, domainProject, serviceId, service, serviceId, service)
+			dr := serviceUtil.NewDependencyRelation(ctx, domainProject, service, service)
 			consumers, err := dr.GetDependencyConsumers()
 			if err != nil {
 				util.Logger().Errorf(err, "Get service's all consumers for govern service failed.")
diff --git a/server/handler/context/context.go b/server/handler/context/context.go
index 7fd42fa..85e52b9 100644
--- a/server/handler/context/context.go
+++ b/server/handler/context/context.go
@@ -40,6 +40,8 @@ func (c *ContextHandler) Handle(i *chain.Invocation) {
 	case v3.IsMatch(r):
 		err = v3.Do(r)
 	case v4.IsMatch(r):
+		util.SetRequestContext(r, "target-domain", "default")
+		util.SetRequestContext(r, "target-project", "default")
 		err = v4.Do(r)
 	}
 
diff --git a/server/handler/context/v3.go b/server/handler/context/v3.go
index c259265..d782684 100644
--- a/server/handler/context/v3.go
+++ b/server/handler/context/v3.go
@@ -34,12 +34,13 @@ func (v *v3Context) IsMatch(r *http.Request) bool {
 func (v *v3Context) Do(r *http.Request) error {
 	ctx := r.Context()
 
-	if len(util.ParseDomain(ctx)) == 0 {
-		domain := r.Header.Get("X-Tenant-Name")
-		if len(domain) == 0 {
-			domain = r.Header.Get("X-Domain-Name")
-		}
+	domain := r.Header.Get("X-Tenant-Name")
+	if len(domain) == 0 {
+		domain = r.Header.Get("X-Domain-Name")
+	}
 
+	// self domain
+	if len(util.ParseDomain(ctx)) == 0 {
 		if len(domain) == 0 {
 			err := errors.New("Header does not contain domain.")
 			util.Logger().Errorf(err, "Invalid Request URI %s", r.RequestURI)
@@ -51,6 +52,12 @@ func (v *v3Context) Do(r *http.Request) error {
 	if len(util.ParseProject(ctx)) == 0 {
 		util.SetRequestContext(r, "project", core.REGISTRY_PROJECT)
 	}
-
+	// target domain
+	if len(util.ParseTargetDomain(ctx)) == 0 {
+		util.SetRequestContext(r, "target-domain", domain)
+	}
+	if len(util.ParseTargetProject(ctx)) == 0 {
+		util.SetRequestContext(r, "target-project", core.REGISTRY_PROJECT)
+	}
 	return nil
 }
diff --git a/server/handler/context/v4.go b/server/handler/context/v4.go
index 8d7531d..0a22e30 100644
--- a/server/handler/context/v4.go
+++ b/server/handler/context/v4.go
@@ -34,25 +34,16 @@ func (v *v4Context) IsMatch(r *http.Request) bool {
 
 func (v *v4Context) Do(r *http.Request) error {
 	ctx := r.Context()
-	if len(util.ParseProject(ctx)) == 0 {
-		path, err := url.PathUnescape(r.RequestURI)
-		if err != nil {
-			util.Logger().Errorf(err, "Invalid Request URI %s", r.RequestURI)
-			return err
-		}
 
-		start := len("/v4/")
-		end := start + strings.Index(path[start:], "/")
-
-		project := strings.TrimSpace(path[start:end])
-		if len(project) == 0 {
-			project = core.REGISTRY_PROJECT
-		}
-		util.SetRequestContext(r, "project", project)
+	domain := r.Header.Get("X-Domain-Name")
+	path, err := url.PathUnescape(r.RequestURI)
+	if err != nil {
+		util.Logger().Errorf(err, "Invalid Request URI %s", r.RequestURI)
+		return err
 	}
 
+	// self domain
 	if len(util.ParseDomain(ctx)) == 0 {
-		domain := r.Header.Get("X-Domain-Name")
 		if len(domain) == 0 {
 			err := errors.New("Header does not contain domain.")
 			util.Logger().Errorf(err, "Invalid Request URI %s", r.RequestURI)
@@ -60,5 +51,26 @@ func (v *v4Context) Do(r *http.Request) error {
 		}
 		util.SetRequestContext(r, "domain", domain)
 	}
+	if len(util.ParseProject(ctx)) == 0 {
+		util.SetRequestContext(r, "project", v.parseProjectFromPath(path))
+	}
+	// target domain
+	if len(util.ParseTargetDomain(ctx)) == 0 {
+		util.SetRequestContext(r, "target-domain", domain)
+	}
+	if len(util.ParseTargetProject(ctx)) == 0 {
+		util.SetRequestContext(r, "target-project", v.parseProjectFromPath(path))
+	}
 	return nil
 }
+
+func (v *v4Context) parseProjectFromPath(path string) string {
+	start := len("/v4/")
+	end := start + strings.Index(path[start:], "/")
+
+	project := strings.TrimSpace(path[start:end])
+	if len(project) == 0 {
+		project = core.REGISTRY_PROJECT
+	}
+	return project
+}
diff --git a/server/infra/registry/registry.go b/server/infra/registry/registry.go
index 407f90f..d331c8e 100644
--- a/server/infra/registry/registry.go
+++ b/server/infra/registry/registry.go
@@ -165,6 +165,7 @@ type Registry interface {
 	// 3. response.Err()
 	// 4. time out to watch, but return nil
 	Watch(ctx context.Context, opts ...PluginOpOption) error
+	Compact(ctx context.Context, reserve int64) error
 	Close()
 }
 
@@ -290,15 +291,28 @@ func (op CompareOp) String() string {
 	)
 }
 
-func CmpVer(key []byte) CompareOp          { return CompareOp{Key: key, Type: CMP_VERSION} }
-func CmpCreateRev(key []byte) CompareOp    { return CompareOp{Key: key, Type: CMP_CREATE} }
-func CmpModRev(key []byte) CompareOp       { return CompareOp{Key: key, Type: CMP_MOD} }
-func CmpVal(key []byte) CompareOp          { return CompareOp{Key: key, Type: CMP_VALUE} }
-func CmpStrVer(key string) CompareOp       { return CmpVer(util.StringToBytesWithNoCopy(key)) }
-func CmpStrCreateRev(key string) CompareOp { return CmpCreateRev(util.StringToBytesWithNoCopy(key)) }
-func CmpStrModRev(key string) CompareOp    { return CmpModRev(util.StringToBytesWithNoCopy(key)) }
-func CmpStrVal(key string) CompareOp       { return CmpVal(util.StringToBytesWithNoCopy(key)) }
-func OpCmp(cmp CompareOp, result CompareResult, v interface{}) CompareOp {
+type CompareOperation func(op *CompareOp)
+
+func CmpVer(key []byte) CompareOperation {
+	return func(op *CompareOp) { op.Key = key; op.Type = CMP_VERSION }
+}
+func CmpCreateRev(key []byte) CompareOperation {
+	return func(op *CompareOp) { op.Key = key; op.Type = CMP_CREATE }
+}
+func CmpModRev(key []byte) CompareOperation {
+	return func(op *CompareOp) { op.Key = key; op.Type = CMP_MOD }
+}
+func CmpVal(key []byte) CompareOperation {
+	return func(op *CompareOp) { op.Key = key; op.Type = CMP_VALUE }
+}
+func CmpStrVer(key string) CompareOperation { return CmpVer(util.StringToBytesWithNoCopy(key)) }
+func CmpStrCreateRev(key string) CompareOperation {
+	return CmpCreateRev(util.StringToBytesWithNoCopy(key))
+}
+func CmpStrModRev(key string) CompareOperation { return CmpModRev(util.StringToBytesWithNoCopy(key)) }
+func CmpStrVal(key string) CompareOperation    { return CmpVal(util.StringToBytesWithNoCopy(key)) }
+func OpCmp(opt CompareOperation, result CompareResult, v interface{}) (cmp CompareOp) {
+	opt(&cmp)
 	cmp.Result = result
 	cmp.Value = v
 	return cmp
diff --git a/server/mux/mux.go b/server/mux/mux.go
index 4be7295..85f816b 100644
--- a/server/mux/mux.go
+++ b/server/mux/mux.go
@@ -33,9 +33,14 @@ func (m *MuxType) String() (s string) {
 }
 
 const (
-	GLOBAL_LOCK MuxType = "/global"
+	GLOBAL_LOCK    MuxType = "/cse-sr/lock/global"
+	DEP_QUEUE_LOCK MuxType = "/cse-sr/lock/dep-queue"
 )
 
-func Lock(t MuxType) (*etcdsync.Locker, error) {
-	return etcdsync.Lock(t.String())
+func Lock(t MuxType) (*etcdsync.DLock, error) {
+	return etcdsync.Lock(t.String(), true)
+}
+
+func Try(t MuxType) (*etcdsync.DLock, error) {
+	return etcdsync.Lock(t.String(), false)
 }
diff --git a/server/plugin/infra/registry/buildin/buildin.go b/server/plugin/infra/registry/buildin/buildin.go
index ab68c72..302dd56 100644
--- a/server/plugin/infra/registry/buildin/buildin.go
+++ b/server/plugin/infra/registry/buildin/buildin.go
@@ -69,6 +69,9 @@ func (ec *BuildinRegistry) LeaseRevoke(ctx context.Context, leaseID int64) error
 func (ec *BuildinRegistry) Watch(ctx context.Context, opts ...registry.PluginOpOption) error {
 	return noPluginErr
 }
+func (c *BuildinRegistry) Compact(ctx context.Context, reserve int64) error {
+	return noPluginErr
+}
 func (ec *BuildinRegistry) Close() {
 	ec.safeClose(ec.ready)
 }
diff --git a/server/plugin/infra/registry/embededetcd/embededetcd.go b/server/plugin/infra/registry/embededetcd/embededetcd.go
index fb488ff..d5eb876 100644
--- a/server/plugin/infra/registry/embededetcd/embededetcd.go
+++ b/server/plugin/infra/registry/embededetcd/embededetcd.go
@@ -223,24 +223,39 @@ func (s *EtcdEmbed) toCompares(cmps []registry.CompareOp) []*etcdserverpb.Compar
 	return etcdCmps
 }
 
-func (s *EtcdEmbed) CompactCluster(ctx context.Context) {
-}
-
-func (s *EtcdEmbed) Compact(ctx context.Context, revision int64) error {
+func (s *EtcdEmbed) Compact(ctx context.Context, reserve int64) error {
 	otCtx, cancel := registry.WithTimeout(ctx)
 	defer cancel()
-	revToCompact := max(0, revision-core.ServerInfo.Config.CompactIndexDelta)
-	util.Logger().Debug(fmt.Sprintf("Compacting %d", revToCompact))
-	resp, err := s.Server.Server.Compact(otCtx, &etcdserverpb.CompactionRequest{
+
+	curRev := s.getLeaderCurrentRevision(otCtx)
+	revToCompact := max(0, curRev-reserve)
+	if revToCompact <= 0 {
+		util.Logger().Infof("revision is %d, <=%d, no nead to compact", curRev, reserve)
+		return nil
+	}
+
+	util.Logger().Infof("Compacting... revision is %d(current: %d, reserve %d)", revToCompact, curRev, reserve)
+	_, err := s.Server.Server.Compact(otCtx, &etcdserverpb.CompactionRequest{
 		Revision: revToCompact,
+		Physical: true,
 	})
 	if err != nil {
+		util.Logger().Errorf(err, "Compact locally failed, revision is %d(current: %d, reserve %d)",
+			revToCompact, curRev, reserve)
 		return err
 	}
-	util.Logger().Info(fmt.Sprintf("Compacted %v", resp))
+	util.Logger().Infof("Compacted locally, revision is %d(current: %d, reserve %d)", revToCompact, curRev, reserve)
+
+	// TODO defragment
+	util.Logger().Infof("Defraged locally")
+
 	return nil
 }
 
+func (s *EtcdEmbed) getLeaderCurrentRevision(ctx context.Context) int64 {
+	return s.Server.Server.KV().Rev()
+}
+
 func (s *EtcdEmbed) PutNoOverride(ctx context.Context, opts ...registry.PluginOpOption) (bool, error) {
 	op := registry.OpPut(opts...)
 	resp, err := s.TxnWithCmp(ctx, []registry.PluginOp{op}, []registry.CompareOp{
diff --git a/server/plugin/infra/registry/etcd/etcd.go b/server/plugin/infra/registry/etcd/etcd.go
index 1ab43ac..f6796fc 100644
--- a/server/plugin/infra/registry/etcd/etcd.go
+++ b/server/plugin/infra/registry/etcd/etcd.go
@@ -66,40 +66,62 @@ func (s *EtcdClient) Close() {
 	util.Logger().Debugf("etcd client stopped.")
 }
 
-func (c *EtcdClient) CompactCluster(ctx context.Context) {
-	for _, ep := range c.Client.Endpoints() {
-		otCtx, cancel := registry.WithTimeout(ctx)
-		defer cancel()
-		mapi := clientv3.NewMaintenance(c.Client)
-		resp, err := mapi.Status(otCtx, ep)
-		if err != nil {
-			util.Logger().Error(fmt.Sprintf("Compact error ,can not get status from %s", ep), err)
-			continue
-		}
-		curRev := resp.Header.Revision
-		util.Logger().Debug(fmt.Sprintf("Compacting.... endpoint: %s / IsLeader: %v\n / revision is %d", ep, resp.Header.MemberId == resp.Leader, curRev))
-		c.Compact(ctx, curRev)
-	}
-
-}
+func (c *EtcdClient) Compact(ctx context.Context, reserve int64) error {
+	eps := c.Client.Endpoints()
+	curRev := c.getLeaderCurrentRevision(ctx)
 
-func (c *EtcdClient) Compact(ctx context.Context, revision int64) error {
-	otCtx, cancel := registry.WithTimeout(ctx)
-	defer cancel()
-	revToCompact := max(0, revision-core.ServerInfo.Config.CompactIndexDelta)
+	revToCompact := max(0, curRev-reserve)
 	if revToCompact <= 0 {
-		util.Logger().Warnf(nil, "revToCompact is %d, <=0, no nead to compact.", revToCompact)
+		util.Logger().Infof("revision is %d, <=%d, no nead to compact %s", curRev, reserve, eps)
 		return nil
 	}
-	util.Logger().Debug(fmt.Sprintf("Compacting %d", revToCompact))
-	resp, err := c.Client.KV.Compact(otCtx, revToCompact)
+
+	otCtx, cancel := registry.WithTimeout(ctx)
+	defer cancel()
+
+	_, err := c.Client.Compact(otCtx, revToCompact, clientv3.WithCompactPhysical())
 	if err != nil {
+		util.Logger().Errorf(err, "Compact %s failed, revision is %d(current: %d, reserve %d)",
+			eps, revToCompact, curRev, reserve)
 		return err
 	}
-	util.Logger().Debugf(fmt.Sprintf("Compacted %v", resp))
+	util.Logger().Infof("Compacted %s, revision is %d(current: %d, reserve %d)", eps, revToCompact, curRev, reserve)
+
+	for _, ep := range eps {
+		_, err := c.Client.Defragment(otCtx, ep)
+		if err != nil {
+			util.Logger().Errorf(err, "Defrag %s failed", ep)
+			continue
+		}
+		util.Logger().Infof("Defraged %s", ep)
+	}
+
 	return nil
 }
 
+func (c *EtcdClient) getLeaderCurrentRevision(ctx context.Context) int64 {
+	eps := c.Client.Endpoints()
+	curRev := int64(0)
+	for _, ep := range eps {
+		otCtx, cancel := registry.WithTimeout(ctx)
+
+		resp, err := c.Client.Status(otCtx, ep)
+		if err != nil {
+			util.Logger().Error(fmt.Sprintf("Compact error ,can not get status from %s", ep), err)
+			cancel()
+			continue
+		}
+		curRev = resp.Header.Revision
+		if resp.Leader == resp.Header.MemberId {
+			util.Logger().Infof("Get leader endpoint: %s, revision is %d", ep, curRev)
+			break
+		}
+
+		cancel()
+	}
+	return curRev
+}
+
 func max(n1, n2 int64) int64 {
 	if n1 > n2 {
 		return n1
@@ -276,8 +298,12 @@ func (c *EtcdClient) paging(ctx context.Context, op registry.PluginOp) (*clientv
 		l := int64(len(recordResp.Kvs))
 		nextKey = clientv3.GetPrefixRangeEnd(util.BytesToStringWithNoCopy(recordResp.Kvs[l-1].Key))
 
-		if op.Offset >= 0 && (op.Offset < i*op.Limit || op.Offset >= (i+1)*op.Limit) {
-			continue
+		if op.Offset >= 0 {
+			if op.Offset < i*op.Limit {
+				continue
+			} else if op.Offset >= (i+1)*op.Limit {
+				break
+			}
 		}
 		etcdResp.Kvs = append(etcdResp.Kvs, recordResp.Kvs...)
 	}
@@ -290,14 +316,14 @@ func (c *EtcdClient) paging(ctx context.Context, op registry.PluginOp) (*clientv
 	// too slow
 	if op.SortOrder == registry.SORT_DESCEND {
 		t := time.Now()
-		for i := int64(0); i < recordCount; i++ {
-			last := recordCount - i - 1
+		for i, l := 0, len(etcdResp.Kvs); i < l; i++ {
+			last := l - i - 1
 			if last <= i {
 				break
 			}
 			etcdResp.Kvs[i], etcdResp.Kvs[last] = etcdResp.Kvs[last], etcdResp.Kvs[i]
 		}
-		util.LogNilOrWarnf(t, "sorted %d KeyValues(%s)", recordCount, key)
+		util.LogNilOrWarnf(t, "sorted descend %d KeyValues(%s)", recordCount, key)
 	}
 	return etcdResp, nil
 }
@@ -585,12 +611,12 @@ func NewRegistry() mgr.PluginInstance {
 	inv, _ := time.ParseDuration(core.ServerInfo.Config.AutoSyncInterval)
 	client, err := newClient(endpoints, inv)
 	if err != nil {
-		util.Logger().Errorf(err, "get etcd client %+v failed.", endpoints)
+		util.Logger().Errorf(err, "get etcd client %v failed.", endpoints)
 		inst.err <- err
 		return inst
 	}
 
-	util.Logger().Warnf(nil, "get etcd client %+v completed, auto sync endpoints interval is %s.",
+	util.Logger().Warnf(nil, "get etcd client %v completed, auto sync endpoints interval is %s.",
 		endpoints, core.ServerInfo.Config.AutoSyncInterval)
 	inst.Client = client
 	close(inst.ready)
diff --git a/server/server.go b/server/server.go
index cb6cb34..2f95922 100644
--- a/server/server.go
+++ b/server/server.go
@@ -28,6 +28,7 @@ import (
 	serviceUtil "github.com/apache/incubator-servicecomb-service-center/server/service/util"
 	"github.com/apache/incubator-servicecomb-service-center/version"
 	"github.com/astaxie/beego"
+	"golang.org/x/net/context"
 	"os"
 	"strings"
 	"time"
@@ -54,8 +55,6 @@ type ServiceCenterServer struct {
 func (s *ServiceCenterServer) Run() {
 	s.initialize()
 
-	s.waitForReady()
-
 	s.startNotifyService()
 
 	s.startApiServer()
@@ -63,9 +62,6 @@ func (s *ServiceCenterServer) Run() {
 	s.waitForQuit()
 }
 
-func (s *ServiceCenterServer) initialize() {
-}
-
 func (s *ServiceCenterServer) waitForQuit() {
 	var err error
 	select {
@@ -93,8 +89,10 @@ func (s *ServiceCenterServer) needUpgrade() bool {
 		fmt.Sprintf("%s+", version.Ver().Version))
 }
 
-func (s *ServiceCenterServer) waitForReady() {
+func (s *ServiceCenterServer) initialize() {
+	// check version
 	lock, err := mux.Lock(mux.GLOBAL_LOCK)
+	defer lock.Unlock()
 	if err != nil {
 		util.Logger().Errorf(err, "wait for server ready failed")
 		os.Exit(1)
@@ -102,10 +100,39 @@ func (s *ServiceCenterServer) waitForReady() {
 	if s.needUpgrade() {
 		core.UpgradeServerVersion()
 	}
-	lock.Unlock()
 
+	// cache mechanism
 	s.store.Run()
 	<-s.store.Ready()
+
+	// auto compact backend
+	s.autoCompactBackend()
+}
+
+func (s *ServiceCenterServer) autoCompactBackend() {
+	delta := core.ServerInfo.Config.CompactIndexDelta
+	if delta <= 0 {
+		return
+	}
+	util.Go(func(stopCh <-chan struct{}) {
+		util.Logger().Infof("start the automatic compact mechanism, compact once every 12h")
+		for {
+			select {
+			case <-stopCh:
+				return
+			case <-time.After(12 * time.Hour):
+				lock, err := mux.Try(mux.GLOBAL_LOCK)
+				if lock == nil {
+					util.Logger().Warnf(err, "can not compact backend by this service center instance now")
+					continue
+				}
+
+				backend.Registry().Compact(context.Background(), delta)
+
+				lock.Unlock()
+			}
+		}
+	})
 }
 
 func (s *ServiceCenterServer) startNotifyService() {
diff --git a/server/service/concurrent_test.go b/server/service/concurrent_test.go
index 8a10ab1..12b09dd 100644
--- a/server/service/concurrent_test.go
+++ b/server/service/concurrent_test.go
@@ -39,7 +39,7 @@ func init() {
 	etcdsync.IsDebug = true
 }
 
-func TestServiceController_CreateDependenciesForMicroServices(t *testing.T) {
+func testServiceController_CreateDependenciesForMicroServices(t *testing.T) {
 	tryTimes := 3
 	testCount := 10
 	serviceResource, _ := service.AssembleResources()
@@ -65,12 +65,12 @@ func TestServiceController_CreateDependenciesForMicroServices(t *testing.T) {
 			_, err := serviceResource.CreateDependenciesForMicroServices(getContext(), &pb.CreateDependenciesRequest{
 				Dependencies: []*pb.ConsumerDependency{
 					{
-						Consumer: &pb.DependencyKey{
+						Consumer: &pb.MicroServiceKey{
 							AppId:       "test_deps",
 							ServiceName: serviceName,
 							Version:     "1.0.0",
 						},
-						Providers: []*pb.DependencyKey{
+						Providers: []*pb.MicroServiceKey{
 							{
 								AppId:       "test_deps",
 								ServiceName: "service0",
diff --git a/server/service/event/dependency_event_handler.go b/server/service/event/dependency_event_handler.go
new file mode 100644
index 0000000..fb367e2
--- /dev/null
+++ b/server/service/event/dependency_event_handler.go
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package event
+
+import (
+	"encoding/json"
+	"fmt"
+	"github.com/apache/incubator-servicecomb-service-center/pkg/util"
+	"github.com/apache/incubator-servicecomb-service-center/server/core"
+	"github.com/apache/incubator-servicecomb-service-center/server/core/backend"
+	"github.com/apache/incubator-servicecomb-service-center/server/core/backend/store"
+	pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto"
+	"github.com/apache/incubator-servicecomb-service-center/server/infra/registry"
+	"github.com/apache/incubator-servicecomb-service-center/server/mux"
+	serviceUtil "github.com/apache/incubator-servicecomb-service-center/server/service/util"
+	"github.com/coreos/etcd/mvcc/mvccpb"
+	"golang.org/x/net/context"
+	"time"
+)
+
+type DependencyEventHandler struct {
+	signals *util.UniQueue
+}
+
+func (h *DependencyEventHandler) Type() store.StoreType {
+	return store.DEPENDENCY_QUEUE
+}
+
+func (h *DependencyEventHandler) OnEvent(evt *store.KvEvent) {
+	action := evt.Action
+	if action != pb.EVT_CREATE && action != pb.EVT_UPDATE && action != pb.EVT_INIT {
+		return
+	}
+
+	h.signals.Put(context.Background(), struct{}{})
+}
+
+func (h *DependencyEventHandler) loop() {
+	util.Go(func(stopCh <-chan struct{}) {
+		waitDelayIndex := 0
+		waitDelay := []int{1, 1, 5, 10, 20, 30, 60}
+		retry := func() {
+			if waitDelayIndex >= len(waitDelay) {
+				waitDelayIndex = 0
+			}
+			<-time.After(time.Duration(waitDelay[waitDelayIndex]) * time.Second)
+			waitDelayIndex++
+
+			h.signals.Put(context.Background(), struct{}{})
+		}
+		for {
+			select {
+			case <-stopCh:
+				return
+			case <-h.signals.Chan():
+				lock, err := mux.Try(mux.DEP_QUEUE_LOCK)
+				if err != nil {
+					util.Logger().Errorf(err, "try to lock %s failed", mux.DEP_QUEUE_LOCK)
+					retry()
+					continue
+				}
+
+				if lock == nil {
+					continue
+				}
+
+				err = h.Handle()
+				lock.Unlock()
+				if err != nil {
+					util.Logger().Errorf(err, "handle dependency event failed")
+					retry()
+					continue
+				}
+			case <-time.After(10 * time.Second):
+				key := core.GetServiceDependencyQueueRootKey("")
+				resp, _ := store.Store().DependencyQueue().Search(context.Background(),
+					registry.WithStrKey(key),
+					registry.WithPrefix(),
+					registry.WithCountOnly(),
+					registry.WithCacheOnly())
+				if resp != nil && resp.Count > 0 {
+					util.Logger().Infof("wait for dependency event timed out(10s) and found %d items still in queue",
+						resp.Count)
+					h.signals.Put(context.Background(), struct{}{})
+				}
+			}
+		}
+	})
+}
+
+func (h *DependencyEventHandler) Handle() error {
+	key := core.GetServiceDependencyQueueRootKey("")
+	resp, err := store.Store().DependencyQueue().Search(context.Background(),
+		registry.WithStrKey(key),
+		registry.WithPrefix())
+	if err != nil {
+		return err
+	}
+
+	// maintain dependency rules.
+	l := len(resp.Kvs)
+	if l == 0 {
+		return nil
+	}
+
+	var (
+		r   *pb.ConsumerDependency = &pb.ConsumerDependency{}
+		ctx context.Context        = context.Background()
+	)
+
+	for _, kv := range resp.Kvs {
+		consumerId, domainProject, data := pb.GetInfoFromDependencyQueueKV(kv)
+
+		err := json.Unmarshal(data, r)
+		if err != nil {
+			util.Logger().Errorf(err, "maintain dependency failed, unmarshal failed, consumer %s dependency: %s",
+				consumerId, util.BytesToStringWithNoCopy(data))
+
+			if err = h.removeKV(ctx, kv); err != nil {
+				return err
+			}
+			continue
+		}
+
+		serviceUtil.SetDependencyDefaultValue(r)
+
+		consumerFlag := util.StringJoin([]string{r.Consumer.AppId, r.Consumer.ServiceName, r.Consumer.Version}, "/")
+		consumerInfo := pb.DependenciesToKeys([]*pb.MicroServiceKey{r.Consumer}, domainProject)[0]
+		providersInfo := pb.DependenciesToKeys(r.Providers, domainProject)
+
+		consumerId, err = serviceUtil.GetServiceId(ctx, consumerInfo)
+		if err != nil {
+			return fmt.Errorf("get consumer %s id failed, override: %t, %s", consumerFlag, r.Override, err.Error())
+		}
+		if len(consumerId) == 0 {
+			util.Logger().Errorf(nil, "maintain dependency failed, override: %t, consumer %s does not exist",
+				r.Override, consumerFlag)
+
+			if err = h.removeKV(ctx, kv); err != nil {
+				return err
+			}
+			continue
+		}
+
+		var dep serviceUtil.Dependency
+		dep.DomainProject = domainProject
+		dep.Consumer = consumerInfo
+		dep.ProvidersRule = providersInfo
+		dep.ConsumerId = consumerId
+		if r.Override {
+			err = serviceUtil.CreateDependencyRule(ctx, &dep)
+		} else {
+			err = serviceUtil.AddDependencyRule(ctx, &dep)
+		}
+
+		if err != nil {
+			return fmt.Errorf("override: %t, consumer is %s, %s", r.Override, consumerFlag, err.Error())
+		}
+
+		if err = h.removeKV(ctx, kv); err != nil {
+			return err
+		}
+
+		util.Logger().Infof("maintain dependency %v successfully, override: %t", r, r.Override)
+	}
+	return nil
+}
+
+func (h *DependencyEventHandler) removeKV(ctx context.Context, kv *mvccpb.KeyValue) error {
+	dresp, err := backend.Registry().TxnWithCmp(ctx, []registry.PluginOp{registry.OpDel(registry.WithKey(kv.Key))},
+		[]registry.CompareOp{registry.OpCmp(registry.CmpVer(kv.Key), registry.CMP_EQUAL, kv.Version)},
+		nil)
+	if err != nil {
+		return fmt.Errorf("can not remove the dependency %s request, %s", util.BytesToStringWithNoCopy(kv.Key), err.Error())
+	}
+	if !dresp.Succeeded {
+		util.Logger().Infof("the dependency %s request is changed", util.BytesToStringWithNoCopy(kv.Key))
+	}
+	return nil
+}
+
+func NewDependencyEventHandler() *DependencyEventHandler {
+	h := &DependencyEventHandler{
+		signals: util.NewUniQueue(),
+	}
+	h.loop()
+	return h
+}
diff --git a/server/service/event/event.go b/server/service/event/event.go
index ef4179f..53fe882 100644
--- a/server/service/event/event.go
+++ b/server/service/event/event.go
@@ -25,4 +25,5 @@ func init() {
 	store.AddEventHandler(NewInstanceEventHandler())
 	store.AddEventHandler(NewRuleEventHandler())
 	store.AddEventHandler(NewTagEventHandler())
+	store.AddEventHandler(NewDependencyEventHandler())
 }
diff --git a/server/service/event/instance_event_handler.go b/server/service/event/instance_event_handler.go
index 76f78ae..4d44e7c 100644
--- a/server/service/event/instance_event_handler.go
+++ b/server/service/event/instance_event_handler.go
@@ -84,7 +84,7 @@ func (h *InstanceEventHandler) OnEvent(evt *store.KvEvent) {
 	}
 
 	// 查询所有consumer
-	consumerIds, _, err := serviceUtil.GetConsumerIds(context.Background(), domainProject, ms)
+	consumerIds, _, err := serviceUtil.GetConsumerIdsByProvider(context.Background(), domainProject, ms)
 	if err != nil {
 		util.Logger().Errorf(err, "query service %s consumers failed", providerId)
 		return
diff --git a/server/service/event/rule_event_handler.go b/server/service/event/rule_event_handler.go
index f25d4cf..42c956c 100644
--- a/server/service/event/rule_event_handler.go
+++ b/server/service/event/rule_event_handler.go
@@ -65,7 +65,7 @@ func (apt *RulesChangedAsyncTask) publish(ctx context.Context, domainProject, pr
 		provider = tmpProvider.(*pb.MicroService)
 	}
 
-	consumerIds, err := serviceUtil.GetConsumersInCache(ctx, domainProject, providerId, provider)
+	consumerIds, err := serviceUtil.GetConsumersInCache(ctx, domainProject, provider)
 	if err != nil {
 		util.Logger().Errorf(err, "get consumer services by provider %s failed", providerId)
 		return err
diff --git a/server/service/event/service_event_handler.go b/server/service/event/service_event_handler.go
index 08d6aeb..2aa6f4d 100644
--- a/server/service/event/service_event_handler.go
+++ b/server/service/event/service_event_handler.go
@@ -47,15 +47,12 @@ func (h *ServiceEventHandler) OnEvent(evt *store.KvEvent) {
 		return
 	}
 
-	switch action {
-	case pb.EVT_CREATE, pb.EVT_INIT:
-		newDomain := domainProject[:strings.Index(domainProject, "/")]
-		newProject := domainProject[strings.Index(domainProject, "/")+1:]
-		err := serviceUtil.NewDomainProject(context.Background(), newDomain, newProject)
-		if err != nil {
-			util.Logger().Errorf(err, "new domain(%s) or project(%s) failed", newDomain, newProject)
-			return
-		}
+	newDomain := domainProject[:strings.Index(domainProject, "/")]
+	newProject := domainProject[strings.Index(domainProject, "/")+1:]
+	err := serviceUtil.NewDomainProject(context.Background(), newDomain, newProject)
+	if err != nil {
+		util.Logger().Errorf(err, "new domain(%s) or project(%s) failed", newDomain, newProject)
+		return
 	}
 }
 
diff --git a/server/service/event/tag_event_handler.go b/server/service/event/tag_event_handler.go
index 104e503..42ea494 100644
--- a/server/service/event/tag_event_handler.go
+++ b/server/service/event/tag_event_handler.go
@@ -64,7 +64,7 @@ func (apt *TagsChangedAsyncTask) publish(ctx context.Context, domainProject, con
 		}
 		consumer = consumerTmp.(*pb.MicroService)
 	}
-	providerIds, err := serviceUtil.GetProvidersInCache(ctx, domainProject, consumerId, consumer)
+	providerIds, err := serviceUtil.GetProvidersInCache(ctx, domainProject, consumer)
 	if err != nil {
 		util.Logger().Errorf(err, "get provider services by consumer %s failed", consumerId)
 		return err
diff --git a/server/service/instances.go b/server/service/instances.go
index ad96a3c..8edde82 100644
--- a/server/service/instances.go
+++ b/server/service/instances.go
@@ -434,11 +434,11 @@ func (s *InstanceService) GetOneInstance(ctx context.Context, in *pb.GetOneInsta
 	}
 	conPro := util.StringJoin([]string{in.ConsumerServiceId, in.ProviderServiceId, in.ProviderInstanceId}, "/")
 
-	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
 
 	serviceId := in.ProviderServiceId
 	instanceId := in.ProviderInstanceId
-	instance, err := serviceUtil.GetInstance(ctx, domainProject, serviceId, instanceId)
+	instance, err := serviceUtil.GetInstance(ctx, targetDomainProject, serviceId, instanceId)
 	if err != nil {
 		util.Logger().Errorf(err, "get instance failed, %s(consumer/provider): get instance failed.", conPro)
 		return &pb.GetOneInstanceResponse{
@@ -463,9 +463,9 @@ func (s *InstanceService) getInstancePreCheck(ctx context.Context, in interface{
 	if err != nil {
 		return scerr.NewError(scerr.ErrInvalidParams, err.Error())
 	}
+	var targetDomainProject = util.ParseTargetDomainProject(ctx)
 	var providerServiceId, consumerServiceId string
 	var tags []string
-	domainProject := util.ParseDomainProject(ctx)
 
 	switch in.(type) {
 	case *pb.GetOneInstanceRequest:
@@ -478,13 +478,13 @@ func (s *InstanceService) getInstancePreCheck(ctx context.Context, in interface{
 		tags = in.(*pb.GetInstancesRequest).Tags
 	}
 
-	if !serviceUtil.ServiceExist(ctx, domainProject, providerServiceId) {
+	if !serviceUtil.ServiceExist(ctx, targetDomainProject, providerServiceId) {
 		return scerr.NewError(scerr.ErrServiceNotExists, "Provider serviceId is invalid")
 	}
 
 	// Tag过滤
 	if len(tags) > 0 {
-		tagsFromETCD, err := serviceUtil.GetTagsUtils(ctx, domainProject, providerServiceId)
+		tagsFromETCD, err := serviceUtil.GetTagsUtils(ctx, targetDomainProject, providerServiceId)
 		if err != nil {
 			return scerr.NewError(scerr.ErrInternal, fmt.Sprintf("An error occurred in query provider tags(%s)", err.Error()))
 		}
@@ -499,7 +499,7 @@ func (s *InstanceService) getInstancePreCheck(ctx context.Context, in interface{
 	}
 	// 黑白名单
 	// 跨应用调用
-	forbid := serviceUtil.Accessible(ctx, domainProject, consumerServiceId, providerServiceId)
+	forbid := serviceUtil.Accessible(ctx, consumerServiceId, providerServiceId)
 	if forbid != nil {
 		util.Logger().Errorf(forbid,
 			"consumer %s can't access provider %s", consumerServiceId, providerServiceId)
@@ -522,9 +522,9 @@ func (s *InstanceService) GetInstances(ctx context.Context, in *pb.GetInstancesR
 	}
 	conPro := util.StringJoin([]string{in.ConsumerServiceId, in.ProviderServiceId}, "/")
 
-	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
 
-	instances, err := serviceUtil.GetAllInstancesOfOneService(ctx, domainProject, in.ProviderServiceId)
+	instances, err := serviceUtil.GetAllInstancesOfOneService(ctx, targetDomainProject, in.ProviderServiceId)
 	if err != nil {
 		util.Logger().Errorf(err, "get instances failed, %s(consumer/provider): get instances from etcd failed.", conPro)
 		return &pb.GetInstancesResponse{
@@ -547,6 +547,7 @@ func (s *InstanceService) Find(ctx context.Context, in *pb.FindInstancesRequest)
 	}
 
 	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
 
 	findFlag := fmt.Sprintf("consumer %s --> provider %s/%s/%s", in.ConsumerServiceId, in.AppId, in.ServiceName, in.VersionRule)
 	service, err := serviceUtil.GetService(ctx, domainProject, in.ConsumerServiceId)
@@ -563,14 +564,21 @@ func (s *InstanceService) Find(ctx context.Context, in *pb.FindInstancesRequest)
 		}, nil
 	}
 
-	// 版本规则
-	ids, err := serviceUtil.FindServiceIds(ctx, in.VersionRule, &pb.MicroServiceKey{
-		Tenant:      domainProject,
+	provider := &pb.MicroServiceKey{
+		Tenant:      targetDomainProject,
 		Environment: service.Environment,
 		AppId:       in.AppId,
 		ServiceName: in.ServiceName,
 		Alias:       in.ServiceName,
-	})
+	}
+
+	if apt.IsShared(provider) {
+		// it means the shared micro-services must be the same env with SC.
+		provider.Environment = apt.Service.Environment
+	}
+
+	// 版本规则
+	ids, err := serviceUtil.FindServiceIds(ctx, in.VersionRule, provider)
 	if err != nil {
 		util.Logger().Errorf(err, "find instance failed, %s: get providers failed.", findFlag)
 		return &pb.FindInstancesResponse{
@@ -601,25 +609,20 @@ func (s *InstanceService) Find(ctx context.Context, in *pb.FindInstancesRequest)
 			instances = append(instances, resp.GetInstances()...)
 		}
 	}
-	consumer := pb.MicroServiceToKey(domainProject, service)
+
 	//维护version的规则,servicename 可能是别名,所以重新获取
-	providerService, _ := serviceUtil.GetService(ctx, domainProject, ids[0])
+	providerService, err := serviceUtil.GetService(ctx, targetDomainProject, ids[0])
 	if providerService == nil {
-		util.Logger().Errorf(nil, "find instance failed, %s: no provider matched.", findFlag)
+		util.Logger().Errorf(err, "find instance failed, %s: no provider matched.", findFlag)
 		return &pb.FindInstancesResponse{
 			Response: pb.CreateResponse(scerr.ErrServiceNotExists, "No provider matched."),
 		}, nil
 	}
-	provider := &pb.MicroServiceKey{
-		Tenant:      domainProject,
-		Environment: consumer.Environment,
-		AppId:       in.AppId,
-		ServiceName: providerService.ServiceName,
-		Version:     in.VersionRule,
-	}
 
-	err = serviceUtil.AddServiceVersionRule(ctx, domainProject, provider, consumer)
+	provider = pb.MicroServiceToKey(targetDomainProject, providerService)
+	provider.Version = in.VersionRule
 
+	err = serviceUtil.AddServiceVersionRule(ctx, domainProject, service, provider)
 	if err != nil {
 		util.Logger().Errorf(err, "find instance failed, %s: add service version rule failed.", findFlag)
 		return &pb.FindInstancesResponse{
@@ -806,7 +809,7 @@ func (s *InstanceService) WebSocketListAndWatch(ctx context.Context, in *pb.Watc
 		return
 	}
 	nf.DoWebSocketListAndWatch(ctx, in.SelfServiceId, func() ([]*pb.WatchInstanceResponse, int64) {
-		return serviceUtil.QueryAllProvidersIntances(ctx, in.SelfServiceId)
+		return serviceUtil.QueryAllProvidersInstances(ctx, in.SelfServiceId)
 	}, conn)
 }
 
diff --git a/server/service/microservices.go b/server/service/microservices.go
index 4308ccd..9811471 100644
--- a/server/service/microservices.go
+++ b/server/service/microservices.go
@@ -223,7 +223,7 @@ func (s *MicroServiceService) DeleteServicePri(ctx context.Context, ServiceId st
 
 	// 强制删除,则与该服务相关的信息删除,非强制删除: 如果作为该被依赖(作为provider,提供服务,且不是只存在自依赖)或者存在实例,则不能删除
 	if !force {
-		dr := serviceUtil.NewProviderDependencyRelation(ctx, domainProject, ServiceId, service)
+		dr := serviceUtil.NewProviderDependencyRelation(ctx, domainProject, service)
 		services, err := dr.GetDependencyConsumerIds()
 		if err != nil {
 			util.Logger().Errorf(err, "delete microservice failed, serviceId is %s: inner err, get service dependency failed.", ServiceId)
@@ -260,7 +260,7 @@ func (s *MicroServiceService) DeleteServicePri(ctx context.Context, ServiceId st
 	}
 
 	//refresh msCache consumerCache, ensure that watch can notify consumers when no cache.
-	err = serviceUtil.RefreshDependencyCache(ctx, domainProject, ServiceId, service)
+	err = serviceUtil.RefreshDependencyCache(ctx, domainProject, service)
 	if err != nil {
 		util.Logger().Errorf(err, "%s microservice failed, serviceId is %s: inner err, refresh service dependency cache failed.", title, ServiceId)
 		return pb.CreateResponse(scerr.ErrInternal, "Refresh dependency cache failed."), err
@@ -275,7 +275,7 @@ func (s *MicroServiceService) DeleteServicePri(ctx context.Context, ServiceId st
 	}
 
 	//删除依赖规则
-	lock, err := mux.Lock(mux.GLOBAL_LOCK)
+	lock, err := mux.Lock(mux.DEP_QUEUE_LOCK)
 	if err != nil {
 		util.Logger().Errorf(err, "%s microservice failed, serviceId is %s: inner err, create lock failed.", title, ServiceId)
 		return pb.CreateResponse(scerr.ErrUnavailableBackend, err.Error()), err
diff --git a/server/service/microservices_test.go b/server/service/microservices_test.go
index d9b0491..e4aa9f0 100644
--- a/server/service/microservices_test.go
+++ b/server/service/microservices_test.go
@@ -867,6 +867,8 @@ var _ = Describe("'Micro-service' service", func() {
 			})
 			Expect(err).To(BeNil())
 			Expect(respFind.Response.Code).To(Equal(pb.Response_SUCCESS))
+
+			Expect(deh.Handle()).To(BeNil())
 		})
 
 		Context("when request is invalid", func() {
diff --git a/server/service/service_dependency.go b/server/service/service_dependency.go
index 73d19b2..4dd8c77 100644
--- a/server/service/service_dependency.go
+++ b/server/service/service_dependency.go
@@ -17,11 +17,14 @@
 package service
 
 import (
+	"encoding/json"
 	"github.com/apache/incubator-servicecomb-service-center/pkg/util"
+	"github.com/apache/incubator-servicecomb-service-center/pkg/uuid"
 	apt "github.com/apache/incubator-servicecomb-service-center/server/core"
+	"github.com/apache/incubator-servicecomb-service-center/server/core/backend"
 	pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto"
 	scerr "github.com/apache/incubator-servicecomb-service-center/server/error"
-	"github.com/apache/incubator-servicecomb-service-center/server/mux"
+	"github.com/apache/incubator-servicecomb-service-center/server/infra/registry"
 	serviceUtil "github.com/apache/incubator-servicecomb-service-center/server/service/util"
 	"golang.org/x/net/context"
 )
@@ -44,62 +47,62 @@ func (s *MicroServiceService) AddOrUpdateDependencies(ctx context.Context, depen
 	if len(dependencyInfos) == 0 {
 		return serviceUtil.BadParamsResponse("Invalid request body.").Response, nil
 	}
+	opts := make([]registry.PluginOp, 0, len(dependencyInfos))
 	domainProject := util.ParseDomainProject(ctx)
 	for _, dependencyInfo := range dependencyInfos {
 		if len(dependencyInfo.Providers) == 0 || dependencyInfo.Consumer == nil {
 			return serviceUtil.BadParamsResponse("Provider is invalid").Response, nil
 		}
 
-		util.Logger().Infof("start create dependency, data info %v", dependencyInfo)
-
 		serviceUtil.SetDependencyDefaultValue(dependencyInfo)
 
 		consumerFlag := util.StringJoin([]string{dependencyInfo.Consumer.AppId, dependencyInfo.Consumer.ServiceName, dependencyInfo.Consumer.Version}, "/")
-		consumerInfo := pb.DependenciesToKeys([]*pb.DependencyKey{dependencyInfo.Consumer}, domainProject)[0]
+		consumerInfo := pb.DependenciesToKeys([]*pb.MicroServiceKey{dependencyInfo.Consumer}, domainProject)[0]
 		providersInfo := pb.DependenciesToKeys(dependencyInfo.Providers, domainProject)
 
 		rsp := serviceUtil.ParamsChecker(consumerInfo, providersInfo)
 		if rsp != nil {
-			util.Logger().Errorf(nil, "create dependency failed, conusmer %s: invalid params.%s", consumerFlag, rsp.Response.Message)
+			util.Logger().Errorf(nil, "put request into dependency queue failed, override: %t, consumer is %s, %s",
+				override, consumerFlag, rsp.Response.Message)
 			return rsp.Response, nil
 		}
 
 		consumerId, err := serviceUtil.GetServiceId(ctx, consumerInfo)
-		util.Logger().Debugf("consumerId is %s", consumerId)
 		if err != nil {
-			util.Logger().Errorf(err, "create dependency failed, consumer %s: get consumer failed.", consumerFlag)
+			util.Logger().Errorf(err, "put request into dependency queue failed, override: %t, get consumer %s id failed",
+				override, consumerFlag)
 			return pb.CreateResponse(scerr.ErrInternal, err.Error()), err
 		}
 		if len(consumerId) == 0 {
-			util.Logger().Errorf(nil, "create dependency failed, consumer %s: consumer not exist.", consumerFlag)
+			util.Logger().Errorf(nil, "put request into dependency queue failed, override: %t, consumer %s does not exist.",
+				override, consumerFlag)
 			return pb.CreateResponse(scerr.ErrServiceNotExists, "Get consumer's serviceId is empty."), nil
 		}
 
-		//建立依赖规则,用于维护依赖关系
-		lock, err := mux.Lock(mux.GLOBAL_LOCK)
+		dependencyInfo.Override = override
+		data, err := json.Marshal(dependencyInfo)
 		if err != nil {
-			util.Logger().Errorf(err, "create dependency failed, consumer %s: create lock failed.", consumerFlag)
+			util.Logger().Errorf(err, "put request into dependency queue failed, override: %t, marshal consumer %s dependency failed",
+				override, consumerFlag)
 			return pb.CreateResponse(scerr.ErrInternal, err.Error()), err
 		}
 
-		var dep serviceUtil.Dependency
-		dep.DomainProject = domainProject
-		dep.Consumer = consumerInfo
-		dep.ProvidersRule = providersInfo
-		dep.ConsumerId = consumerId
-		if override {
-			err = serviceUtil.CreateDependencyRule(ctx, &dep)
-		} else {
-			err = serviceUtil.AddDependencyRule(ctx, &dep)
+		id := "0"
+		if !override {
+			id = uuid.GenerateUuid()
 		}
-		lock.Unlock()
+		key := apt.GenerateConsumerDependencyQueueKey(domainProject, consumerId, id)
+		opts = append(opts, registry.OpPut(registry.WithStrKey(key), registry.WithValue(data)))
+	}
 
-		if err != nil {
-			util.Logger().Errorf(err, "create dependency rule failed: consumer %s", consumerFlag)
-			return pb.CreateResponse(scerr.ErrInternal, err.Error()), err
-		}
-		util.Logger().Infof("Create dependency success: consumer %s, %s  from remote %s", consumerFlag, consumerId, util.GetIPFromContext(ctx))
+	_, err := backend.Registry().Txn(ctx, opts)
+	if err != nil {
+		util.Logger().Errorf(err, "put request into dependency queue failed, override: %t, %v", override, dependencyInfos)
+		return pb.CreateResponse(scerr.ErrInternal, err.Error()), err
 	}
+
+	util.Logger().Infof("put request into dependency queue successfully, override: %t, %v, from remote %s",
+		override, dependencyInfos, util.GetIPFromContext(ctx))
 	return pb.CreateResponse(pb.Response_SUCCESS, "Create dependency successfully."), nil
 }
 
@@ -126,7 +129,7 @@ func (s *MicroServiceService) GetProviderDependencies(ctx context.Context, in *p
 		}, nil
 	}
 
-	dr := serviceUtil.NewProviderDependencyRelation(ctx, domainProject, providerServiceId, provider)
+	dr := serviceUtil.NewProviderDependencyRelation(ctx, domainProject, provider)
 	services, err := dr.GetDependencyConsumers()
 	if err != nil {
 		util.Logger().Errorf(err, "GetProviderDependencies failed.")
@@ -166,7 +169,7 @@ func (s *MicroServiceService) GetConsumerDependencies(ctx context.Context, in *p
 		}, nil
 	}
 
-	dr := serviceUtil.NewConsumerDependencyRelation(ctx, domainProject, consumerId, consumer)
+	dr := serviceUtil.NewConsumerDependencyRelation(ctx, domainProject, consumer)
 	services, err := dr.GetDependencyProviders()
 	if err != nil {
 		util.Logger().Errorf(err, "GetConsumerDependencies failed for get providers failed.")
diff --git a/server/service/service_dependency_test.go b/server/service/service_dependency_test.go
index d1370d6..115dc45 100644
--- a/server/service/service_dependency_test.go
+++ b/server/service/service_dependency_test.go
@@ -18,10 +18,13 @@ package service_test
 
 import (
 	pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto"
+	"github.com/apache/incubator-servicecomb-service-center/server/service/event"
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
 )
 
+var deh event.DependencyEventHandler
+
 var _ = Describe("'Dependency' service", func() {
 	Describe("execute 'create' operartion", func() {
 		var (
@@ -90,12 +93,12 @@ var _ = Describe("'Dependency' service", func() {
 				Expect(err).To(BeNil())
 				Expect(respCreateDependency.Response.Code).ToNot(Equal(pb.Response_SUCCESS))
 
-				consumer := &pb.DependencyKey{
+				consumer := &pb.MicroServiceKey{
 					AppId:       "create_dep_group",
 					ServiceName: "create_dep_consumer",
 					Version:     "1.0.0",
 				}
-				providers := []*pb.DependencyKey{
+				providers := []*pb.MicroServiceKey{
 					{
 						AppId:       "create_dep_group",
 						ServiceName: "create_dep_provider",
@@ -107,7 +110,7 @@ var _ = Describe("'Dependency' service", func() {
 				respCreateDependency, err = serviceResource.CreateDependenciesForMicroServices(getContext(), &pb.CreateDependenciesRequest{
 					Dependencies: []*pb.ConsumerDependency{
 						{
-							Consumer: &pb.DependencyKey{
+							Consumer: &pb.MicroServiceKey{
 								AppId:       "noexistapp",
 								ServiceName: "noexistservice",
 								Version:     "1.0.0",
@@ -123,7 +126,7 @@ var _ = Describe("'Dependency' service", func() {
 				respCreateDependency, err = serviceResource.CreateDependenciesForMicroServices(getContext(), &pb.CreateDependenciesRequest{
 					Dependencies: []*pb.ConsumerDependency{
 						{
-							Consumer: &pb.DependencyKey{
+							Consumer: &pb.MicroServiceKey{
 								AppId:       "create_dep_group",
 								ServiceName: "create_dep_consumer",
 								Version:     "1.0.0+",
@@ -139,7 +142,7 @@ var _ = Describe("'Dependency' service", func() {
 				respCreateDependency, err = serviceResource.CreateDependenciesForMicroServices(getContext(), &pb.CreateDependenciesRequest{
 					Dependencies: []*pb.ConsumerDependency{
 						{
-							Consumer: &pb.DependencyKey{
+							Consumer: &pb.MicroServiceKey{
 								AppId:       "create_dep_group",
 								ServiceName: "*",
 								Version:     "1.0.0",
@@ -167,7 +170,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "*",
 									ServiceName: "service_name_provider",
@@ -185,7 +188,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "service_group_provider",
 									ServiceName: "-",
@@ -203,7 +206,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "service_group_provider",
 									ServiceName: "service_name_provider",
@@ -221,7 +224,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									Environment: pb.ENV_PROD,
 									AppId:       "service_group_provider",
@@ -248,7 +251,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "service_group_provider",
 									ServiceName: "service_name_provider",
@@ -272,7 +275,7 @@ var _ = Describe("'Dependency' service", func() {
 
 		Context("when request is valid", func() {
 			It("should be passed", func() {
-				consumer := &pb.DependencyKey{
+				consumer := &pb.MicroServiceKey{
 					ServiceName: "create_dep_consumer",
 					AppId:       "create_dep_group",
 					Version:     "1.0.0",
@@ -283,7 +286,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "create_dep_group",
 									ServiceName: "create_dep_provider",
@@ -301,7 +304,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "create_dep_group",
 									ServiceName: "create_dep_provider",
@@ -319,7 +322,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									ServiceName: "*",
 								},
@@ -335,7 +338,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "create_dep_group",
 									ServiceName: "create_dep_provider",
@@ -356,7 +359,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "create_dep_group",
 									ServiceName: "create_dep_provider",
@@ -374,7 +377,7 @@ var _ = Describe("'Dependency' service", func() {
 					Dependencies: []*pb.ConsumerDependency{
 						{
 							Consumer: consumer,
-							Providers: []*pb.DependencyKey{
+							Providers: []*pb.MicroServiceKey{
 								{
 									AppId:       "create_dep_group",
 									ServiceName: "create_dep_provider",
@@ -500,6 +503,8 @@ var _ = Describe("'Dependency' service", func() {
 				Expect(err).To(BeNil())
 				Expect(resp.Response.Code).To(Equal(pb.Response_SUCCESS))
 
+				Expect(deh.Handle()).To(BeNil())
+
 				By("get provider's deps")
 				respGetP, err := serviceResource.GetProviderDependencies(getContext(), &pb.GetDependenciesRequest{
 					ServiceId: providerId1,
@@ -526,6 +531,8 @@ var _ = Describe("'Dependency' service", func() {
 				Expect(err).To(BeNil())
 				Expect(resp.Response.Code).To(Equal(pb.Response_SUCCESS))
 
+				Expect(deh.Handle()).To(BeNil())
+
 				By("get provider again")
 				respGetP, err = serviceResource.GetProviderDependencies(getContext(), &pb.GetDependenciesRequest{
 					ServiceId: providerId1,
diff --git a/server/service/util/dependency.go b/server/service/util/dependency.go
index 5ad5cc4..3b1a118 100644
--- a/server/service/util/dependency.go
+++ b/server/service/util/dependency.go
@@ -28,7 +28,6 @@ import (
 	pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto"
 	scerr "github.com/apache/incubator-servicecomb-service-center/server/error"
 	"github.com/apache/incubator-servicecomb-service-center/server/infra/registry"
-	"github.com/apache/incubator-servicecomb-service-center/server/mux"
 	"golang.org/x/net/context"
 	"strings"
 	"time"
@@ -50,73 +49,75 @@ func init() {
 	providerCache = cache.New(d, d)
 }
 
-func GetConsumersInCache(ctx context.Context, domainProject string, providerId string, provider *pb.MicroService) ([]string, error) {
+func GetConsumersInCache(ctx context.Context, domainProject string, provider *pb.MicroService) ([]string, error) {
 	// 查询所有consumer
-	dr := NewProviderDependencyRelation(ctx, domainProject, providerId, provider)
+	dr := NewProviderDependencyRelation(ctx, domainProject, provider)
 	consumerIds, err := dr.GetDependencyConsumerIds()
 	if err != nil {
-		util.Logger().Errorf(err, "Get dependency consumerIds failed.%s", providerId)
+		util.Logger().Errorf(err, "Get dependency consumerIds failed.%s", provider.ServiceId)
 		return nil, err
 	}
 
 	if len(consumerIds) == 0 {
-		consumerIds, found := consumerCache.Get(providerId)
+		consumerIds, found := consumerCache.Get(provider.ServiceId)
 		if found && len(consumerIds.([]string)) > 0 {
 			return consumerIds.([]string), nil
 		}
-		util.Logger().Warnf(nil, "Can not find any consumer from local cache and backend. provider is %s", providerId)
+		util.Logger().Warnf(nil, "Can not find any consumer from local cache and backend. provider is %s",
+			provider.ServiceId)
 		return nil, nil
 	}
 
 	return consumerIds, nil
 }
 
-func GetProvidersInCache(ctx context.Context, domainProject string, consumerId string, consumer *pb.MicroService) ([]string, error) {
+func GetProvidersInCache(ctx context.Context, domainProject string, consumer *pb.MicroService) ([]string, error) {
 	// 查询所有provider
-	dr := NewConsumerDependencyRelation(ctx, domainProject, consumerId, consumer)
+	dr := NewConsumerDependencyRelation(ctx, domainProject, consumer)
 	providerIds, err := dr.GetDependencyProviderIds()
 	if err != nil {
-		util.Logger().Errorf(err, "Get dependency providerIds failed.%s", consumerId)
+		util.Logger().Errorf(err, "Get dependency providerIds failed.%s", consumer.ServiceId)
 		return nil, err
 	}
 
 	if len(providerIds) == 0 {
-		providerIds, found := providerCache.Get(consumerId)
+		providerIds, found := providerCache.Get(consumer.ServiceId)
 		if found && len(providerIds.([]string)) > 0 {
 			return providerIds.([]string), nil
 		}
-		util.Logger().Warnf(nil, "Can not find any provider from local cache and backend. consumer is %s", consumerId)
+		util.Logger().Warnf(nil, "Can not find any provider from local cache and backend. consumer is %s",
+			consumer.ServiceId)
 		return nil, nil
 	}
 
 	return providerIds, nil
 }
 
-func RefreshDependencyCache(ctx context.Context, domainProject string, serviceId string, service *pb.MicroService) error {
-	dr := NewDependencyRelation(ctx, domainProject, serviceId, service, serviceId, service)
+func RefreshDependencyCache(ctx context.Context, domainProject string, service *pb.MicroService) error {
+	dr := NewDependencyRelation(ctx, domainProject, service, service)
 	consumerIds, err := dr.GetDependencyConsumerIds()
 	if err != nil {
-		util.Logger().Errorf(err, "%s,refresh dependency cache failed, get consumerIds failed.", serviceId)
+		util.Logger().Errorf(err, "%s,refresh dependency cache failed, get consumerIds failed.", service.ServiceId)
 		return err
 	}
 	providerIds, err := dr.GetDependencyProviderIds()
 	if err != nil {
-		util.Logger().Errorf(err, "%s,refresh dependency cache failed, get providerIds failed.", serviceId)
+		util.Logger().Errorf(err, "%s,refresh dependency cache failed, get providerIds failed.", service.ServiceId)
 		return err
 	}
-	MsCache().Set(serviceId, service, 5*time.Minute)
+	MsCache().Set(service.ServiceId, service, 5*time.Minute)
 	if len(consumerIds) > 0 {
-		util.Logger().Infof("refresh %s dependency cache: cached %d consumerId(s) for 5min.", serviceId, len(consumerIds))
-		consumerCache.Set(serviceId, consumerIds, 5*time.Minute)
+		util.Logger().Infof("refresh %s dependency cache: cached %d consumerId(s) for 5min.", service.ServiceId, len(consumerIds))
+		consumerCache.Set(service.ServiceId, consumerIds, 5*time.Minute)
 	}
 	if len(providerIds) > 0 {
-		util.Logger().Infof("refresh %s dependency cache: cached %d providerId(s) for 5min.", serviceId, len(providerIds))
-		providerCache.Set(serviceId, providerIds, 5*time.Minute)
+		util.Logger().Infof("refresh %s dependency cache: cached %d providerId(s) for 5min.", service.ServiceId, len(providerIds))
+		providerCache.Set(service.ServiceId, providerIds, 5*time.Minute)
 	}
 	return nil
 }
 
-func GetConsumerIds(ctx context.Context, domainProject string, provider *pb.MicroService) (allow []string, deny []string, _ error) {
+func GetConsumerIdsByProvider(ctx context.Context, domainProject string, provider *pb.MicroService) (allow []string, deny []string, _ error) {
 	if provider == nil || len(provider.ServiceId) == 0 {
 		return nil, nil, fmt.Errorf("invalid provider")
 	}
@@ -128,7 +129,7 @@ func GetConsumerIds(ctx context.Context, domainProject string, provider *pb.Micr
 		return nil, nil, err
 	}
 	if len(providerRules) == 0 {
-		return getConsumerIdsWithFilter(ctx, domainProject, provider.ServiceId, provider, noFilter)
+		return getConsumerIdsWithFilter(ctx, domainProject, provider, noFilter)
 	}
 
 	rf := RuleFilter{
@@ -137,16 +138,16 @@ func GetConsumerIds(ctx context.Context, domainProject string, provider *pb.Micr
 		ProviderRules: providerRules,
 	}
 
-	allow, deny, err = getConsumerIdsWithFilter(ctx, domainProject, provider.ServiceId, provider, rf.Filter)
+	allow, deny, err = getConsumerIdsWithFilter(ctx, domainProject, provider, rf.Filter)
 	if err != nil {
 		return nil, nil, err
 	}
 	return allow, deny, nil
 }
 
-func getConsumerIdsWithFilter(ctx context.Context, domainProject, providerId string, provider *pb.MicroService,
+func getConsumerIdsWithFilter(ctx context.Context, domainProject string, provider *pb.MicroService,
 	filter func(ctx context.Context, consumerId string) (bool, error)) (allow []string, deny []string, err error) {
-	consumerIds, err := GetConsumersInCache(ctx, domainProject, providerId, provider)
+	consumerIds, err := GetConsumersInCache(ctx, domainProject, provider)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -181,8 +182,8 @@ func noFilter(_ context.Context, _ string) (bool, error) {
 	return true, nil
 }
 
-func GetProviderIdsByConsumerId(ctx context.Context, domainProject, consumerId string, service *pb.MicroService) (allow []string, deny []string, _ error) {
-	providerIdsInCache, err := GetProvidersInCache(ctx, domainProject, consumerId, service)
+func GetProviderIdsByConsumer(ctx context.Context, domainProject string, service *pb.MicroService) (allow []string, deny []string, _ error) {
+	providerIdsInCache, err := GetProvidersInCache(ctx, domainProject, service)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -209,7 +210,7 @@ func GetProviderIdsByConsumerId(ctx context.Context, domainProject, consumerId s
 		}
 		rf.Provider = provider
 		rf.ProviderRules = providerRules
-		ok, err := rf.Filter(ctx, consumerId)
+		ok, err := rf.Filter(ctx, service.ServiceId)
 		if err != nil {
 			return nil, nil, err
 		}
@@ -224,8 +225,12 @@ func GetProviderIdsByConsumerId(ctx context.Context, domainProject, consumerId s
 	return providerIds[:allowIdx], providerIds[denyIdx:], nil
 }
 
-func ProviderDependencyRuleExist(ctx context.Context, domainProject string, provider *pb.MicroServiceKey, consumer *pb.MicroServiceKey) (bool, error) {
-	providerKey := apt.GenerateProviderDependencyRuleKey(domainProject, provider)
+func ProviderDependencyRuleExist(ctx context.Context, provider *pb.MicroServiceKey, consumer *pb.MicroServiceKey) (bool, error) {
+	targetDomainProject := provider.Tenant
+	if len(targetDomainProject) == 0 {
+		targetDomainProject = consumer.Tenant
+	}
+	providerKey := apt.GenerateProviderDependencyRuleKey(targetDomainProject, provider)
 	consumers, err := TransferToMicroServiceDependency(ctx, providerKey)
 	if err != nil {
 		return false, err
@@ -243,20 +248,33 @@ func ProviderDependencyRuleExist(ctx context.Context, domainProject string, prov
 	return false, nil
 }
 
-func AddServiceVersionRule(ctx context.Context, domainProject string, provider *pb.MicroServiceKey, consumer *pb.MicroServiceKey) error {
+func AddServiceVersionRule(ctx context.Context, domainProject string, consumer *pb.MicroService, provider *pb.MicroServiceKey) error {
 	//创建依赖一致
-	exist, err := ProviderDependencyRuleExist(ctx, domainProject, provider, consumer)
+	consumerKey := pb.MicroServiceToKey(domainProject, consumer)
+	exist, err := ProviderDependencyRuleExist(ctx, provider, consumerKey)
 	if exist || err != nil {
 		return err
 	}
 
-	lock, err := mux.Lock(mux.GLOBAL_LOCK)
+	r := &pb.ConsumerDependency{
+		Consumer:  consumerKey,
+		Providers: []*pb.MicroServiceKey{provider},
+		Override:  false,
+	}
+	data, err := json.Marshal(r)
+	if err != nil {
+		return err
+	}
+
+	id := util.StringJoin([]string{provider.AppId, provider.ServiceName}, "_")
+	key := apt.GenerateConsumerDependencyQueueKey(domainProject, consumer.ServiceId, id)
+	_, err = backend.Registry().Do(ctx, registry.PUT, registry.WithStrKey(key), registry.WithValue(data))
 	if err != nil {
 		return err
 	}
-	err = CreateDependencyRuleForFind(ctx, domainProject, provider, consumer)
-	lock.Unlock()
-	return err
+
+	util.Logger().Infof("find request into dependency queue successfully, %s: %v", key, r)
+	return nil
 }
 
 func DeleteDependencyForService(ctx context.Context, consumer *pb.MicroServiceKey, serviceId string) ([]registry.PluginOp, error) {
@@ -545,97 +563,6 @@ func CreateDependencyRule(ctx context.Context, dep *Dependency) error {
 	return syncDependencyRule(ctx, dep, parseOverrideRules)
 }
 
-func CreateDependencyRuleForFind(ctx context.Context, domainProject string, provider *pb.MicroServiceKey, consumer *pb.MicroServiceKey) error {
-	//更新consumer的providers的值,consumer的版本是确定的
-	consumerFlag := strings.Join([]string{consumer.AppId, consumer.ServiceName, consumer.Version}, "/")
-	conKey := apt.GenerateConsumerDependencyRuleKey(domainProject, consumer)
-
-	oldProviderRules, err := TransferToMicroServiceDependency(ctx, conKey)
-	if err != nil {
-		util.Logger().Errorf(err, "get dependency rule failed, consumer %s: get consumer depedency rule failed.", consumerFlag)
-		return err
-	}
-	if isDependencyAll(oldProviderRules) {
-		util.Logger().Infof("find update dep rule, exist * for %v", consumer)
-		return nil
-	}
-	opts := make([]registry.PluginOp, 0)
-	if oldProviderRule := isNeedUpdate(oldProviderRules.Dependency, provider); oldProviderRule != nil {
-		opt, err := deleteConsumerDepOfProviderRule(ctx, domainProject, oldProviderRule, consumer)
-		if err != nil {
-			util.Logger().Errorf(err, "marshal consumerDepRules failed for delete consumer rule from provider rule's dep.%s", consumerFlag)
-			return err
-		}
-		util.Logger().Infof("delete consumer %v from provider dep %v", consumer, oldProviderRule)
-		opts = append(opts, opt)
-
-		oldRule, opt, err := updateDepRuleUtil(conKey, oldProviderRules, provider)
-		if err != nil {
-			util.Logger().Errorf(err, "update provider rule into consumer's dep rule failed, %s", consumerFlag)
-			return err
-		}
-		util.Logger().Infof("update provider %v(from version '%s') into consumer dep %s", provider, oldRule, consumerFlag)
-		opts = append(opts, opt)
-
-		opt, err = updateProviderRuleDep(ctx, domainProject, provider, consumer)
-		if err != nil {
-			return err
-		}
-		opts = append(opts, opt)
-	} else {
-		if !isExist(oldProviderRules.Dependency, provider) {
-			opt, err := addDepRuleUtil(conKey, oldProviderRules, provider)
-			if err != nil {
-				util.Logger().Errorf(err, "add provider rule into consumer's dep rule failed, %s", consumerFlag)
-				return err
-			}
-			util.Logger().Infof("add consumer dep, %s, add %v", consumerFlag, provider)
-			opts = append(opts, opt)
-		}
-
-		proKey := apt.GenerateProviderDependencyRuleKey(domainProject, provider)
-		consumerDepRules, err := TransferToMicroServiceDependency(ctx, proKey)
-		if err != nil {
-			util.Logger().Errorf(err, "get consumer rule of provider failed,%v", provider)
-			return err
-		}
-		if !isExist(consumerDepRules.Dependency, consumer) {
-			opt, err := addDepRuleUtil(proKey, consumerDepRules, consumer)
-			if err != nil {
-				util.Logger().Errorf(err, "add consumer rule into provider's dep rule failed,%s", consumerFlag)
-				return err
-			}
-			util.Logger().Infof("add provider dep, %s, add %v", consumerFlag, provider)
-			opts = append(opts, opt)
-		}
-	}
-
-	if len(opts) != 0 {
-		_, err = backend.Registry().Txn(ctx, opts)
-		if err != nil {
-			util.Logger().Errorf(err, "update dep rule for consumer failed, %s", consumerFlag)
-			return err
-		}
-	}
-	return nil
-}
-
-func updateProviderRuleDep(ctx context.Context, domainProject string, providerRule, consumer *pb.MicroServiceKey) (registry.PluginOp, error) {
-	proKey := apt.GenerateProviderDependencyRuleKey(domainProject, providerRule)
-	consumerDepRules, err := TransferToMicroServiceDependency(ctx, proKey)
-	opt := registry.PluginOp{}
-	if err != nil {
-		util.Logger().Errorf(err, "get provider rule's dep failed, providerRule %v, consumer %v", providerRule, consumer)
-		return opt, err
-	}
-	opt, err = addDepRuleUtil(proKey, consumerDepRules, consumer)
-	if err != nil {
-		util.Logger().Errorf(err, "add consumer into provider's dep rule failed, providerRule %v, consumer %v", providerRule, consumer)
-		return opt, err
-	}
-	return opt, nil
-}
-
 func isDependencyAll(dep *pb.MicroServiceDependency) bool {
 	for _, servicedep := range dep.Dependency {
 		if servicedep.ServiceName == "*" {
@@ -798,7 +725,7 @@ func (dep *Dependency) removeConsumerOfProviderRule() {
 	ctx := context.TODO()
 	opts := make([]registry.PluginOp, 0, len(dep.removedDependencyRuleList))
 	for _, providerRule := range dep.removedDependencyRuleList {
-		proProkey := apt.GenerateProviderDependencyRuleKey(dep.DomainProject, providerRule)
+		proProkey := apt.GenerateProviderDependencyRuleKey(providerRule.Tenant, providerRule)
 		util.Logger().Debugf("This proProkey is %s.", proProkey)
 		consumerValue, err := TransferToMicroServiceDependency(ctx, proProkey)
 		if err != nil {
@@ -845,8 +772,8 @@ func (dep *Dependency) AddConsumerOfProviderRule() {
 func (dep *Dependency) addConsumerOfProviderRule() {
 	ctx := context.TODO()
 	opts := []registry.PluginOp{}
-	for _, prividerRule := range dep.NewDependencyRuleList {
-		proProkey := apt.GenerateProviderDependencyRuleKey(dep.DomainProject, prividerRule)
+	for _, providerRule := range dep.NewDependencyRuleList {
+		proProkey := apt.GenerateProviderDependencyRuleKey(providerRule.Tenant, providerRule)
 		tmpValue, err := TransferToMicroServiceDependency(ctx, proProkey)
 		if err != nil {
 			dep.err <- err
@@ -863,7 +790,7 @@ func (dep *Dependency) addConsumerOfProviderRule() {
 		opts = append(opts, registry.OpPut(
 			registry.WithStrKey(proProkey),
 			registry.WithValue(data)))
-		if prividerRule.ServiceName == "*" {
+		if providerRule.ServiceName == "*" {
 			break
 		}
 	}
@@ -900,52 +827,69 @@ func (dep *Dependency) UpdateProvidersRuleOfConsumer(conKey string) error {
 type DependencyRelation struct {
 	ctx           context.Context
 	domainProject string
-	consumerId    string
 	consumer      *pb.MicroService
-	providerId    string
 	provider      *pb.MicroService
 }
 
-func NewProviderDependencyRelation(ctx context.Context, domainProject string, providerId string, provider *pb.MicroService) *DependencyRelation {
-	return NewDependencyRelation(ctx, domainProject, "", nil, providerId, provider)
+func NewProviderDependencyRelation(ctx context.Context, domainProject string, provider *pb.MicroService) *DependencyRelation {
+	return NewDependencyRelation(ctx, domainProject, nil, provider)
 }
 
-func NewConsumerDependencyRelation(ctx context.Context, domainProject string, consumerId string, consumer *pb.MicroService) *DependencyRelation {
-	return NewDependencyRelation(ctx, domainProject, consumerId, consumer, "", nil)
+func NewConsumerDependencyRelation(ctx context.Context, domainProject string, consumer *pb.MicroService) *DependencyRelation {
+	return NewDependencyRelation(ctx, domainProject, consumer, nil)
 }
 
-func NewDependencyRelation(ctx context.Context, domainProject string, consumerId string, consumer *pb.MicroService, providerId string, provider *pb.MicroService) *DependencyRelation {
+func NewDependencyRelation(ctx context.Context, domainProject string, consumer *pb.MicroService, provider *pb.MicroService) *DependencyRelation {
 	return &DependencyRelation{
 		ctx:           ctx,
 		domainProject: domainProject,
-		consumerId:    consumerId,
 		consumer:      consumer,
-		providerId:    providerId,
 		provider:      provider,
 	}
 }
 
 func (dr *DependencyRelation) GetDependencyProviders() ([]*pb.MicroService, error) {
-	providerIds, err := dr.GetDependencyProviderIds()
+	keys, err := dr.getProviderKeys()
 	if err != nil {
 		return nil, err
 	}
-	services := make([]*pb.MicroService, 0)
-	for _, providerId := range providerIds {
-		provider, err := GetService(dr.ctx, dr.domainProject, providerId)
+	services := make([]*pb.MicroService, 0, len(keys))
+	for _, key := range keys {
+		providerIds, err := dr.parseDependencyRule(key)
 		if err != nil {
 			return nil, err
 		}
-		if provider == nil {
-			util.Logger().Warnf(nil, "Provider not exist, %s", providerId)
-			continue
+
+		if key.ServiceName == "*" {
+			services = services[:0]
+		}
+
+		for _, providerId := range providerIds {
+			provider, err := GetService(dr.ctx, key.Tenant, providerId)
+			if err != nil {
+				util.Logger().Warnf(nil, "Provider does not exist, %s/%s/%s",
+					key.AppId, key.ServiceName, key.Version)
+				continue
+			}
+			services = append(services, provider)
+		}
+
+		if key.ServiceName == "*" {
+			break
 		}
-		services = append(services, provider)
 	}
 	return services, nil
 }
 
 func (dr *DependencyRelation) GetDependencyProviderIds() ([]string, error) {
+	keys, err := dr.getProviderKeys()
+	if err != nil {
+		return nil, err
+	}
+	return dr.getDependencyProviderIds(keys)
+}
+
+func (dr *DependencyRelation) getProviderKeys() ([]*pb.MicroServiceKey, error) {
 	if dr.consumer == nil {
 		util.LOGGER.Infof("dr.consumer is nil ------->")
 		return nil, fmt.Errorf("Invalid consumer")
@@ -957,33 +901,21 @@ func (dr *DependencyRelation) GetDependencyProviderIds() ([]string, error) {
 	if err != nil {
 		return nil, err
 	}
-	return dr.getDependencyProviderIds(consumerDependency.Dependency)
+	return consumerDependency.Dependency, nil
 }
 
 func (dr *DependencyRelation) getDependencyProviderIds(providerRules []*pb.MicroServiceKey) ([]string, error) {
-	provideServiceIds := make([]string, 0)
-	opts := FromContext(dr.ctx)
+	provideServiceIds := make([]string, 0, len(providerRules))
 	for _, provider := range providerRules {
+		serviceIds, err := dr.parseDependencyRule(provider)
 		switch {
 		case provider.ServiceName == "*":
-			util.Logger().Infof("Rely all service,* type, consumerId %s", dr.consumerId)
-			splited := strings.Split(apt.GenerateServiceIndexKey(provider), "/")
-			allServiceKey := util.StringJoin(splited[:len(splited)-3], "/") + "/"
-			sopts := append(opts,
-				registry.WithStrKey(allServiceKey),
-				registry.WithPrefix())
-			resp, err := store.Store().Service().Search(dr.ctx, sopts...)
 			if err != nil {
 				util.Logger().Errorf(err, "Add dependency failed, rely all service: get all services failed.")
 				return provideServiceIds, err
 			}
-
-			for _, kv := range resp.Kvs {
-				provideServiceIds = append(provideServiceIds, util.BytesToStringWithNoCopy(kv.Value))
-			}
-			return provideServiceIds, nil
+			return serviceIds, nil
 		default:
-			serviceIds, err := FindServiceIds(dr.ctx, provider.Version, provider)
 			if err != nil {
 				util.Logger().Errorf(err, "Get providerIds failed, service: %s/%s/%s",
 					provider.AppId, provider.ServiceName, provider.Version)
@@ -1000,21 +932,45 @@ func (dr *DependencyRelation) getDependencyProviderIds(providerRules []*pb.Micro
 	return provideServiceIds, nil
 }
 
+func (dr *DependencyRelation) parseDependencyRule(dependencyRule *pb.MicroServiceKey) (serviceIds []string, err error) {
+	opts := FromContext(dr.ctx)
+	switch {
+	case dependencyRule.ServiceName == "*":
+		util.Logger().Infof("Rely all service, * type, consumerId %s", dr.consumer.ServiceId)
+		splited := strings.Split(apt.GenerateServiceIndexKey(dependencyRule), "/")
+		allServiceKey := util.StringJoin(splited[:len(splited)-3], "/") + "/"
+		sopts := append(opts,
+			registry.WithStrKey(allServiceKey),
+			registry.WithPrefix())
+		resp, err := store.Store().Service().Search(dr.ctx, sopts...)
+		if err != nil {
+			return nil, err
+		}
+
+		for _, kv := range resp.Kvs {
+			serviceIds = append(serviceIds, util.BytesToStringWithNoCopy(kv.Value))
+		}
+	default:
+		serviceIds, err = FindServiceIds(dr.ctx, dependencyRule.Version, dependencyRule)
+	}
+	return
+}
+
 func (dr *DependencyRelation) GetDependencyConsumers() ([]*pb.MicroService, error) {
 	consumerDependAllList, err := dr.getDependencyConsumersOfProvider()
 	if err != nil {
-		util.Logger().Errorf(err, "Get consumers of provider rule failed, %s", dr.providerId)
+		util.Logger().Errorf(err, "Get consumers of provider rule failed, %s", dr.provider.ServiceId)
 		return nil, err
 	}
 	consumers := make([]*pb.MicroService, 0)
 
 	for _, consumer := range consumerDependAllList {
-		service, err := dr.getServiceByMicroServiceKey(dr.domainProject, consumer)
+		service, err := dr.getServiceByMicroServiceKey(consumer)
 		if err != nil {
 			return nil, err
 		}
 		if service == nil {
-			util.Logger().Warnf(nil, "Consumer not exist,%v", service)
+			util.Logger().Warnf(nil, "Consumer does not exist, %v", consumer)
 			continue
 		}
 		consumers = append(consumers, service)
@@ -1022,7 +978,7 @@ func (dr *DependencyRelation) GetDependencyConsumers() ([]*pb.MicroService, erro
 	return consumers, nil
 }
 
-func (dr *DependencyRelation) getServiceByMicroServiceKey(domainProject string, service *pb.MicroServiceKey) (*pb.MicroService, error) {
+func (dr *DependencyRelation) getServiceByMicroServiceKey(service *pb.MicroServiceKey) (*pb.MicroService, error) {
 	serviceId, err := GetServiceId(dr.ctx, service)
 	if err != nil {
 		return nil, err
@@ -1031,7 +987,7 @@ func (dr *DependencyRelation) getServiceByMicroServiceKey(domainProject string,
 		util.Logger().Warnf(nil, "Service not exist,%v", service)
 		return nil, nil
 	}
-	return GetService(dr.ctx, domainProject, serviceId)
+	return GetService(dr.ctx, service.Tenant, serviceId)
 }
 
 func (dr *DependencyRelation) GetDependencyConsumerIds() ([]string, error) {
@@ -1039,9 +995,9 @@ func (dr *DependencyRelation) GetDependencyConsumerIds() ([]string, error) {
 	if err != nil {
 		return nil, err
 	}
-	consumerIds := make([]string, 0)
+	consumerIds := make([]string, 0, len(consumerDependAllList))
 	for _, consumer := range consumerDependAllList {
-		consumerId, err := GetServiceId(context.TODO(), consumer)
+		consumerId, err := GetServiceId(dr.ctx, consumer)
 		if err != nil {
 			util.Logger().Errorf(err, "Get consumer failed, %v", consumer)
 			return nil, err
@@ -1064,13 +1020,14 @@ func (dr *DependencyRelation) getDependencyConsumersOfProvider() ([]*pb.MicroSer
 	providerService := pb.MicroServiceToKey(dr.domainProject, dr.provider)
 	consumerDependAllList, err := dr.getConsumerOfDependAllServices()
 	if err != nil {
-		util.Logger().Errorf(err, "Get consumer that depend on all services failed, %s", dr.providerId)
+		util.Logger().Errorf(err, "Get consumer that depend on all services failed, %s", dr.provider.ServiceId)
 		return nil, err
 	}
 
 	consumerDependList, err := dr.getConsumerOfSameServiceNameAndAppId(providerService)
 	if err != nil {
-		util.Logger().Errorf(err, "Get consumer that depend on same serviceName and appid rule failed, %s", dr.providerId)
+		util.Logger().Errorf(err, "Get consumer that depend on same serviceName and appid rule failed, %s",
+			dr.provider.ServiceId)
 		return nil, err
 	}
 	consumerDependAllList = append(consumerDependAllList, consumerDependList...)
@@ -1135,7 +1092,7 @@ func (dr *DependencyRelation) getConsumerOfSameServiceNameAndAppId(provider *pb.
 				util.Logger().Infof("%s 's providerId is empty,no this service.", provider.ServiceName)
 				continue
 			}
-			if dr.providerId != latestServiceId[0] {
+			if dr.provider.ServiceId != latestServiceId[0] {
 				continue
 			}
 
diff --git a/server/service/util/dependency_test.go b/server/service/util/dependency_test.go
index d420891..6695945 100644
--- a/server/service/util/dependency_test.go
+++ b/server/service/util/dependency_test.go
@@ -25,7 +25,7 @@ import (
 )
 
 func TestRefreshDependencyCache(t *testing.T) {
-	err := RefreshDependencyCache(context.Background(), "", "", &proto.MicroService{})
+	err := RefreshDependencyCache(context.Background(), "", &proto.MicroService{})
 	if err == nil {
 		fmt.Printf(`RefreshDependencyCache failed`)
 		t.FailNow()
@@ -135,18 +135,12 @@ func TestCreateDependencyRule(t *testing.T) {
 		t.FailNow()
 	}
 
-	err = AddServiceVersionRule(context.Background(), "", &proto.MicroServiceKey{}, &proto.MicroServiceKey{})
+	err = AddServiceVersionRule(context.Background(), "", &proto.MicroService{}, &proto.MicroServiceKey{})
 	if err == nil {
 		fmt.Printf(`AddServiceVersionRule failed`)
 		t.FailNow()
 	}
 
-	err = CreateDependencyRuleForFind(context.Background(), "", &proto.MicroServiceKey{}, &proto.MicroServiceKey{})
-	if err == nil {
-		fmt.Printf(`CreateDependencyRuleForFind failed`)
-		t.FailNow()
-	}
-
 	_, err = addDepRuleUtil("", &proto.MicroServiceDependency{}, &proto.MicroServiceKey{})
 	if err != nil {
 		fmt.Printf(`addDepRuleUtil failed`)
@@ -320,13 +314,13 @@ func TestParamsChecker(t *testing.T) {
 }
 
 func TestServiceDependencyRuleExist(t *testing.T) {
-	_, err := ProviderDependencyRuleExist(util.SetContext(context.Background(), "cacheOnly", "1"), "", &proto.MicroServiceKey{}, &proto.MicroServiceKey{})
+	_, err := ProviderDependencyRuleExist(util.SetContext(context.Background(), "cacheOnly", "1"), &proto.MicroServiceKey{}, &proto.MicroServiceKey{})
 	if err != nil {
 		fmt.Printf(`ServiceDependencyRuleExist WithCacheOnly failed`)
 		t.FailNow()
 	}
 
-	_, err = ProviderDependencyRuleExist(context.Background(), "", &proto.MicroServiceKey{}, &proto.MicroServiceKey{})
+	_, err = ProviderDependencyRuleExist(context.Background(), &proto.MicroServiceKey{}, &proto.MicroServiceKey{})
 	if err == nil {
 		fmt.Printf(`ServiceDependencyRuleExist failed`)
 		t.FailNow()
@@ -358,7 +352,7 @@ func TestUpdateServiceForAddDependency(t *testing.T) {
 }
 
 func TestFilter(t *testing.T) {
-	_, _, err := getConsumerIdsWithFilter(context.Background(), "", "", &proto.MicroService{}, noFilter)
+	_, _, err := getConsumerIdsWithFilter(context.Background(), "", &proto.MicroService{}, noFilter)
 	if err == nil {
 		fmt.Printf(`getConsumerIdsWithFilter failed`)
 		t.FailNow()
@@ -440,7 +434,7 @@ func TestDependency(t *testing.T) {
 		t.FailNow()
 	}
 
-	_, err = dr.getServiceByMicroServiceKey("", &proto.MicroServiceKey{})
+	_, err = dr.getServiceByMicroServiceKey(&proto.MicroServiceKey{})
 	if err != nil {
 		fmt.Printf(`DependencyRelation_getServiceByMicroServiceKey WithCacheOnly failed`)
 		t.FailNow()
@@ -479,7 +473,7 @@ func TestDependency(t *testing.T) {
 		t.FailNow()
 	}
 
-	_, err = dr.getServiceByMicroServiceKey("", &proto.MicroServiceKey{})
+	_, err = dr.getServiceByMicroServiceKey(&proto.MicroServiceKey{})
 	if err == nil {
 		fmt.Printf(`DependencyRelation_getServiceByMicroServiceKey failed`)
 		t.FailNow()
diff --git a/server/service/util/instance_util.go b/server/service/util/instance_util.go
index c63496f..eb5351f 100644
--- a/server/service/util/instance_util.go
+++ b/server/service/util/instance_util.go
@@ -191,7 +191,7 @@ func DeleteServiceAllInstances(ctx context.Context, serviceId string) error {
 	return nil
 }
 
-func QueryAllProvidersIntances(ctx context.Context, selfServiceId string) (results []*pb.WatchInstanceResponse, rev int64) {
+func QueryAllProvidersInstances(ctx context.Context, selfServiceId string) (results []*pb.WatchInstanceResponse, rev int64) {
 	results = []*pb.WatchInstanceResponse{}
 
 	domainProject := util.ParseDomainProject(ctx)
@@ -205,7 +205,7 @@ func QueryAllProvidersIntances(ctx context.Context, selfServiceId string) (resul
 		util.Logger().Errorf(nil, "service not exist, %s", selfServiceId)
 		return
 	}
-	providerIds, _, err := GetProviderIdsByConsumerId(ctx, domainProject, selfServiceId, service)
+	providerIds, _, err := GetProviderIdsByConsumer(ctx, domainProject, service)
 	if err != nil {
 		util.Logger().Errorf(err, "get service %s providers id set failed.", selfServiceId)
 		return
diff --git a/server/service/util/instance_util_test.go b/server/service/util/instance_util_test.go
index 4bc955e..5bba56c 100644
--- a/server/service/util/instance_util_test.go
+++ b/server/service/util/instance_util_test.go
@@ -64,7 +64,7 @@ func TestGetInstance(t *testing.T) {
 		t.FailNow()
 	}
 
-	QueryAllProvidersIntances(context.Background(), "")
+	QueryAllProvidersInstances(context.Background(), "")
 
 	_, err = queryServiceInstancesKvs(context.Background(), "", 0)
 	if err == nil {
diff --git a/server/service/util/rule_util.go b/server/service/util/rule_util.go
index f2614b8..50041b9 100644
--- a/server/service/util/rule_util.go
+++ b/server/service/util/rule_util.go
@@ -143,7 +143,7 @@ func GetOneRule(ctx context.Context, domainProject, serviceId, ruleId string) (*
 	return rule, nil
 }
 
-func AllowAcrossDimension(providerService *pb.MicroService, consumerService *pb.MicroService) error {
+func AllowAcrossDimension(ctx context.Context, providerService *pb.MicroService, consumerService *pb.MicroService) error {
 	if providerService.AppId != consumerService.AppId {
 		if len(providerService.Properties) == 0 {
 			return fmt.Errorf("not allow across app access")
@@ -154,7 +154,9 @@ func AllowAcrossDimension(providerService *pb.MicroService, consumerService *pb.
 		}
 	}
 
-	if providerService.Environment != consumerService.Environment {
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
+	if !apt.IsShared(pb.MicroServiceToKey(targetDomainProject, providerService)) &&
+		providerService.Environment != consumerService.Environment {
 		return fmt.Errorf("not allow across environment access")
 	}
 
@@ -213,7 +215,10 @@ func MatchRules(rules []*pb.ServiceRule, service *pb.MicroService, serviceTags m
 	return nil
 }
 
-func Accessible(ctx context.Context, domainProject string, consumerId string, providerId string) *scerr.Error {
+func Accessible(ctx context.Context, consumerId string, providerId string) *scerr.Error {
+	domainProject := util.ParseDomainProject(ctx)
+	targetDomainProject := util.ParseTargetDomainProject(ctx)
+
 	consumerService, err := GetService(ctx, domainProject, consumerId)
 	if err != nil {
 		return scerr.NewError(scerr.ErrInternal, fmt.Sprintf("An error occurred in query consumer(%s)", err.Error()))
@@ -223,7 +228,7 @@ func Accessible(ctx context.Context, domainProject string, consumerId string, pr
 	}
 
 	// 跨应用权限
-	providerService, err := GetService(ctx, domainProject, providerId)
+	providerService, err := GetService(ctx, targetDomainProject, providerId)
 	if err != nil {
 		return scerr.NewError(scerr.ErrInternal, fmt.Sprintf("An error occurred in query provider(%s)", err.Error()))
 	}
@@ -231,7 +236,7 @@ func Accessible(ctx context.Context, domainProject string, consumerId string, pr
 		return scerr.NewError(scerr.ErrServiceNotExists, "provider serviceId is invalid")
 	}
 
-	err = AllowAcrossDimension(providerService, consumerService)
+	err = AllowAcrossDimension(ctx, providerService, consumerService)
 	if err != nil {
 		return scerr.NewError(scerr.ErrPermissionDeny, err.Error())
 	}
@@ -239,7 +244,7 @@ func Accessible(ctx context.Context, domainProject string, consumerId string, pr
 	ctx = util.SetContext(util.CloneContext(ctx), "cacheOnly", "1")
 
 	// 黑白名单
-	rules, err := GetRulesUtil(ctx, domainProject, providerId)
+	rules, err := GetRulesUtil(ctx, targetDomainProject, providerId)
 	if err != nil {
 		return scerr.NewError(scerr.ErrInternal, fmt.Sprintf("An error occurred in query provider rules(%s)", err.Error()))
 	}
diff --git a/server/service/util/rule_util_test.go b/server/service/util/rule_util_test.go
index 4175aea..5cf142a 100644
--- a/server/service/util/rule_util_test.go
+++ b/server/service/util/rule_util_test.go
@@ -91,7 +91,7 @@ func TestGetServiceRuleType(t *testing.T) {
 }
 
 func TestAllowAcrossApp(t *testing.T) {
-	err := serviceUtil.AllowAcrossDimension(&proto.MicroService{
+	err := serviceUtil.AllowAcrossDimension(context.Background(), &proto.MicroService{
 		AppId: "a",
 	}, &proto.MicroService{
 		AppId: "a",
@@ -101,7 +101,7 @@ func TestAllowAcrossApp(t *testing.T) {
 		t.FailNow()
 	}
 
-	err = serviceUtil.AllowAcrossDimension(&proto.MicroService{
+	err = serviceUtil.AllowAcrossDimension(context.Background(), &proto.MicroService{
 		AppId: "a",
 	}, &proto.MicroService{
 		AppId: "c",
@@ -111,7 +111,7 @@ func TestAllowAcrossApp(t *testing.T) {
 		t.FailNow()
 	}
 
-	err = serviceUtil.AllowAcrossDimension(&proto.MicroService{
+	err = serviceUtil.AllowAcrossDimension(context.Background(), &proto.MicroService{
 		AppId: "a",
 		Properties: map[string]string{
 			proto.PROP_ALLOW_CROSS_APP: "true",
@@ -124,7 +124,7 @@ func TestAllowAcrossApp(t *testing.T) {
 		t.FailNow()
 	}
 
-	err = serviceUtil.AllowAcrossDimension(&proto.MicroService{
+	err = serviceUtil.AllowAcrossDimension(context.Background(), &proto.MicroService{
 		AppId: "a",
 		Properties: map[string]string{
 			proto.PROP_ALLOW_CROSS_APP: "true",
@@ -137,7 +137,7 @@ func TestAllowAcrossApp(t *testing.T) {
 		t.FailNow()
 	}
 
-	err = serviceUtil.AllowAcrossDimension(&proto.MicroService{
+	err = serviceUtil.AllowAcrossDimension(context.Background(), &proto.MicroService{
 		AppId: "a",
 		Properties: map[string]string{
 			proto.PROP_ALLOW_CROSS_APP: "false",
@@ -150,7 +150,7 @@ func TestAllowAcrossApp(t *testing.T) {
 		t.FailNow()
 	}
 
-	err = serviceUtil.AllowAcrossDimension(&proto.MicroService{
+	err = serviceUtil.AllowAcrossDimension(context.Background(), &proto.MicroService{
 		AppId: "a",
 		Properties: map[string]string{
 			proto.PROP_ALLOW_CROSS_APP: "",
@@ -289,21 +289,21 @@ func TestMatchRules(t *testing.T) {
 }
 
 func TestGetConsumer(t *testing.T) {
-	_, _, err := serviceUtil.GetConsumerIds(context.Background(), "", &proto.MicroService{})
+	_, _, err := serviceUtil.GetConsumerIdsByProvider(context.Background(), "", &proto.MicroService{})
 	if err == nil {
-		fmt.Printf("GetConsumerIds invalid failed")
+		fmt.Printf("GetConsumerIdsByProvider invalid failed")
 		t.FailNow()
 	}
 
-	_, _, err = serviceUtil.GetConsumerIds(context.Background(), "", &proto.MicroService{
+	_, _, err = serviceUtil.GetConsumerIdsByProvider(context.Background(), "", &proto.MicroService{
 		ServiceId: "a",
 	})
 	if err == nil {
-		fmt.Printf("GetConsumerIds not exist service failed")
+		fmt.Printf("GetConsumerIdsByProvider not exist service failed")
 		t.FailNow()
 	}
 
-	_, err = serviceUtil.GetConsumersInCache(util.SetContext(context.Background(), "cacheOnly", "1"), "", "",
+	_, err = serviceUtil.GetConsumersInCache(util.SetContext(context.Background(), "cacheOnly", "1"), "",
 		&proto.MicroService{
 			ServiceId: "a",
 		})
@@ -314,7 +314,7 @@ func TestGetConsumer(t *testing.T) {
 }
 
 func TestGetProvider(t *testing.T) {
-	_, err := serviceUtil.GetProvidersInCache(util.SetContext(context.Background(), "cacheOnly", "1"), "", "",
+	_, err := serviceUtil.GetProvidersInCache(util.SetContext(context.Background(), "cacheOnly", "1"), "",
 		&proto.MicroService{
 			ServiceId: "a",
 		})
@@ -323,28 +323,28 @@ func TestGetProvider(t *testing.T) {
 		t.FailNow()
 	}
 
-	_, _, err = serviceUtil.GetProviderIdsByConsumerId(context.Background(), "", "", &proto.MicroService{})
+	_, _, err = serviceUtil.GetProviderIdsByConsumer(context.Background(), "", &proto.MicroService{})
 	if err == nil {
-		fmt.Printf("GetProviderIdsByConsumerId invalid failed")
+		fmt.Printf("GetProviderIdsByConsumer invalid failed")
 		t.FailNow()
 	}
 
-	_, _, err = serviceUtil.GetProviderIdsByConsumerId(util.SetContext(context.Background(), "cacheOnly", "1"),
-		"", "", &proto.MicroService{})
+	_, _, err = serviceUtil.GetProviderIdsByConsumer(util.SetContext(context.Background(), "cacheOnly", "1"),
+		"", &proto.MicroService{})
 	if err != nil {
-		fmt.Printf("GetProviderIdsByConsumerId WithCacheOnly failed")
+		fmt.Printf("GetProviderIdsByConsumer WithCacheOnly failed")
 		t.FailNow()
 	}
 }
 
 func TestAccessible(t *testing.T) {
-	err := serviceUtil.Accessible(context.Background(), "", "", "")
+	err := serviceUtil.Accessible(context.Background(), "", "")
 	if err.StatusCode() != http.StatusInternalServerError {
 		fmt.Printf("Accessible invalid failed")
 		t.FailNow()
 	}
 
-	err = serviceUtil.Accessible(util.SetContext(context.Background(), "cacheOnly", "1"), "", "", "")
+	err = serviceUtil.Accessible(util.SetContext(context.Background(), "cacheOnly", "1"), "", "")
 	if err.StatusCode() == http.StatusInternalServerError {
 		fmt.Printf("Accessible WithCacheOnly failed")
 		t.FailNow()

-- 
To stop receiving notification emails like this one, please contact
['"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>'].