You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2021/09/25 09:28:37 UTC

[dubbo-go] branch config-enhance updated: Config enhance (#1467)

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

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


The following commit(s) were added to refs/heads/config-enhance by this push:
     new 2072171  Config enhance (#1467)
2072171 is described below

commit 20721712985200ead0e256ff46f37de4536d7c31
Author: zhaoyunxing <23...@qq.com>
AuthorDate: Sat Sep 25 17:28:29 2021 +0800

    Config enhance (#1467)
    
    * up:配置优化
    
    * up:修改registryid获取逻辑
    
    * up:修改registryid获取逻辑
    
    * fmt
    
    * fix:测试通过
    
    * 代码结构调整
    
    * 代码结构调整
    
    * 代码结构调整
    
    * 代码结构调整
    
    * fmt
    
    * fix:update get provider instance
    
    * cac -> once
    
    * up:更新初始化方法
    
    * fmt
    
    * 更新默认端口
    
    * 代码优化
    
    * 优化日志打印
    
    * add new root config
    
    * 解决启动问题
    
    * up:处理nil问题
    
    * fmt
    
    * fmt
---
 common/constant/key.go                             |   2 +
 common/extension/registry.go                       |   8 +-
 config/application_config.go                       |  72 ++++++++--
 ...etwork_config.go => application_config_test.go} |  18 ++-
 config/config_center_config.go                     |  29 ++--
 config/config_loader.go                            |  13 +-
 config/config_loader_test.go                       |  75 +++-------
 config/config_utils.go                             |   1 +
 config/consumer_config.go                          |  37 +++--
 config/dubbo_bootstrap.go                          | 112 +++++++++++++++
 config/logger_config.go                            |  41 ++++--
 config/logger_config_test.go                       |   1 -
 config/metadata_report_config.go                   |  49 +++----
 config/protocol_config.go                          |  15 +-
 config/protocol_config_test.go                     |   4 +-
 config/provider_config.go                          | 103 ++++----------
 config/provider_config_test.go                     |  46 +++---
 config/reference_config.go                         |  18 ++-
 config/registry_config.go                          |  32 +++--
 config/registry_config_test.go                     |   4 +-
 config/root_config.go                              | 156 +++------------------
 config/service_config.go                           |  71 +---------
 config/testdata/config/app/application.yaml        |   2 +-
 .../testdata/config/application/application.yaml   |   4 +
 config/testdata/config/protocol/application.yaml   |   5 +
 .../config/protocol/empty_application.yaml         |   5 +
 config/testdata/config/provider/application.yaml   |   5 +
 .../config/provider/registry_application.yaml      |  11 +-
 config/testdata/config/service/hello_service.go    |  31 ----
 config/testdata/config/service/order_service.go    |  31 ----
 go.mod                                             |   3 +-
 go.sum                                             |  13 --
 integrate_test.sh                                  |   2 +-
 .../service/exporter/configurable/exporter_test.go |   2 +-
 metrics/prometheus/reporter.go                     |  33 ++---
 protocol/dubbo3/internal/server.go                 |   6 +-
 36 files changed, 487 insertions(+), 573 deletions(-)

diff --git a/common/constant/key.go b/common/constant/key.go
index bf8b3e1..849d1de 100644
--- a/common/constant/key.go
+++ b/common/constant/key.go
@@ -177,6 +177,7 @@ const (
 
 const (
 	RegistryConfigPrefix       = "dubbo.registries"
+	ApplicationConfigPrefix    = "dubbo.application"
 	ConfigCenterPrefix         = "dubbo.config-center"
 	SingleRegistryConfigPrefix = "dubbo.registry"
 	ReferenceConfigPrefix      = "dubbo.reference"
@@ -190,6 +191,7 @@ const (
 	ShutdownConfigPrefix       = "dubbo.shutdown"
 	MetadataReportPrefix       = "dubbo.metadata-report"
 	RouterConfigPrefix         = "dubbo.router"
+	LoggerConfigPrefix         = "dubbo.logger"
 )
 
 const (
diff --git a/common/extension/registry.go b/common/extension/registry.go
index 31cb80c..abce206 100644
--- a/common/extension/registry.go
+++ b/common/extension/registry.go
@@ -22,17 +22,17 @@ import (
 	"dubbo.apache.org/dubbo-go/v3/registry"
 )
 
-var registrys = make(map[string]func(config *common.URL) (registry.Registry, error))
+var registries = make(map[string]func(config *common.URL) (registry.Registry, error))
 
 // SetRegistry sets the registry extension with @name
 func SetRegistry(name string, v func(_ *common.URL) (registry.Registry, error)) {
-	registrys[name] = v
+	registries[name] = v
 }
 
 // GetRegistry finds the registry extension with @name
 func GetRegistry(name string, config *common.URL) (registry.Registry, error) {
-	if registrys[name] == nil {
+	if registries[name] == nil {
 		panic("registry for " + name + " does not exist. please make sure that you have imported the package dubbo.apache.org/dubbo-go/v3/registry/" + name + ".")
 	}
-	return registrys[name](config)
+	return registries[name](config)
 }
diff --git a/config/application_config.go b/config/application_config.go
index b9334ad..1118109 100644
--- a/config/application_config.go
+++ b/config/application_config.go
@@ -19,6 +19,8 @@ package config
 
 import (
 	"github.com/creasty/defaults"
+
+	"github.com/pkg/errors"
 )
 
 import (
@@ -37,25 +39,77 @@ type ApplicationConfig struct {
 	MetadataType string `default:"local" yaml:"metadata-type" json:"metadataType,omitempty" property:"metadataType"`
 }
 
-// Prefix dubbo.applicationConfig
+// Prefix dubbo.application
 func (ApplicationConfig) Prefix() string {
-	return constant.DUBBO + ".application"
+	return constant.ApplicationConfigPrefix
 }
 
-func (ac *ApplicationConfig) Init(rc *RootConfig) error {
-	// ignore refresh action
-	if rc.refresh || ac == nil {
-		rootConfig.Application = new(ApplicationConfig)
-		return nil
+// Init  application config and set default value
+func (ac *ApplicationConfig) Init() error {
+	if ac == nil {
+		return errors.New("application is null")
 	}
-	defaults.MustSet(ac)
 	if err := ac.check(); err != nil {
 		return err
 	}
 	return nil
 }
 
+func GetApplicationInstance(opts ...ApplicationConfigOpt) *ApplicationConfig {
+	ac := &ApplicationConfig{}
+	for _, opt := range opts {
+		opt(ac)
+	}
+	return ac
+}
+
 func (ac *ApplicationConfig) check() error {
-	defaults.MustSet(ac)
+	if err := defaults.Set(ac); err != nil {
+		return err
+	}
 	return verify(ac)
 }
+
+type ApplicationConfigOpt func(config *ApplicationConfig)
+
+func WithOrganization(organization string) ApplicationConfigOpt {
+	return func(ac *ApplicationConfig) {
+		ac.Organization = organization
+	}
+}
+
+func WithName(name string) ApplicationConfigOpt {
+	return func(ac *ApplicationConfig) {
+		ac.Name = name
+	}
+}
+
+func WithModule(module string) ApplicationConfigOpt {
+	return func(ac *ApplicationConfig) {
+		ac.Module = module
+	}
+}
+
+func WithVersion(version string) ApplicationConfigOpt {
+	return func(ac *ApplicationConfig) {
+		ac.Version = version
+	}
+}
+
+func WithOwner(owner string) ApplicationConfigOpt {
+	return func(ac *ApplicationConfig) {
+		ac.Owner = owner
+	}
+}
+
+func WithEnvironment(env string) ApplicationConfigOpt {
+	return func(ac *ApplicationConfig) {
+		ac.Environment = env
+	}
+}
+
+func WithMetadataType(metadataType string) ApplicationConfigOpt {
+	return func(ac *ApplicationConfig) {
+		ac.MetadataType = metadataType
+	}
+}
diff --git a/config/network_config.go b/config/application_config_test.go
similarity index 75%
rename from config/network_config.go
rename to config/application_config_test.go
index e07aca1..398fa6e 100644
--- a/config/network_config.go
+++ b/config/application_config_test.go
@@ -17,9 +17,19 @@
 
 package config
 
-type NetworkConfig struct {
-}
+import (
+	"testing"
+)
+
+import (
+	"github.com/stretchr/testify/assert"
+)
+
+func TestApplicationConfig(t *testing.T) {
+
+	err := Load(WithPath("./testdata/config/application/application.yaml"))
+	assert.Nil(t, err)
 
-func initNetworkConfig(rc *RootConfig) error {
-	return nil
+	center := rootConfig.Registries
+	assert.NotNil(t, center)
 }
diff --git a/config/config_center_config.go b/config/config_center_config.go
index 479bf71..b0b4e60 100644
--- a/config/config_center_config.go
+++ b/config/config_center_config.go
@@ -49,10 +49,9 @@ import (
 //
 // CenterConfig has currently supported Zookeeper, Nacos, Etcd, Consul, Apollo
 type CenterConfig struct {
-	Protocol string `yaml:"protocol"  json:"protocol,omitempty"`
-	Address  string `yaml:"address" json:"address,omitempty"`
-	DataId   string `yaml:"data-id" json:"data-id,omitempty"`
-	// Deprecated
+	Protocol string `validate:"required" yaml:"protocol"  json:"protocol,omitempty"`
+	Address  string `validate:"required" yaml:"address" json:"address,omitempty"`
+	DataId   string `validate:"required" yaml:"data-id" json:"data-id,omitempty"`
 	Cluster  string `yaml:"cluster" json:"cluster,omitempty"`
 	Group    string `default:"dubbo" yaml:"group" json:"group,omitempty"`
 	Username string `yaml:"username" json:"username,omitempty"`
@@ -72,19 +71,31 @@ type CenterConfig struct {
 	Params    map[string]string `yaml:"params"  json:"parameters,omitempty"`
 }
 
+// Prefix dubbo.config-center
+func (CenterConfig) Prefix() string {
+	return constant.ConfigCenterPrefix
+}
+
+func GetConfigCenterInstance(opts ...CenterConfigOpt) *CenterConfig {
+	cc := &CenterConfig{
+		Params: make(map[string]string, 1),
+	}
+	for _, opt := range opts {
+		opt(cc)
+	}
+	return cc
+}
+
 func (c *CenterConfig) check() error {
 	if err := defaults.Set(c); err != nil {
 		return err
 	}
 	c.translateConfigAddress()
-	if c.Address == "" || c.Protocol == "" {
-		return errors.Errorf("invalid config center config %+v", c)
-	}
 	return verify(c)
 }
 
 func (c *CenterConfig) Init(rc *RootConfig) error {
-	if rc.refresh || c == nil {
+	if c == nil {
 		return nil
 	}
 	if err := c.check(); err != nil {
@@ -171,8 +182,6 @@ func startConfigCenter(rc *RootConfig) error {
 		return err
 	}
 
-	rc.refresh = false
-	rc.ConfigCenter = nil
 	return nil
 }
 
diff --git a/config/config_loader.go b/config/config_loader.go
index e15cb7e..2886269 100644
--- a/config/config_loader.go
+++ b/config/config_loader.go
@@ -25,8 +25,6 @@ import (
 )
 
 import (
-	hessian "github.com/apache/dubbo-go-hessian2"
-
 	"github.com/knadh/koanf"
 	"github.com/knadh/koanf/parsers/json"
 	"github.com/knadh/koanf/parsers/toml"
@@ -45,29 +43,22 @@ import (
 )
 
 var (
-	rootConfig *RootConfig
+	rootConfig = GetInstance()
 	maxWait    = 3
 )
 
 func Load(opts ...LoaderConfOption) error {
-	hessian.RegisterPOJO(&common.MetadataInfo{})
-	hessian.RegisterPOJO(&common.ServiceInfo{})
-	hessian.RegisterPOJO(&common.URL{})
 	// conf
 	conf := NewLoaderConf(opts...)
-	// init config
-	rootConfig = new(RootConfig)
 	koan := getKoanf(conf)
 	if err := koan.UnmarshalWithConf(rootConfig.Prefix(),
 		rootConfig, koanf.UnmarshalConf{Tag: "yaml"}); err != nil {
 		return err
 	}
-	rootConfig.refresh = false
-	extension.SetAndInitGlobalDispatcher(rootConfig.EventDispatcherType)
 	if err := rootConfig.Init(); err != nil {
 		return err
 	}
-	registerServiceInstance()
+	rootConfig.Start()
 	return nil
 }
 
diff --git a/config/config_loader_test.go b/config/config_loader_test.go
index eaa8358..73b96fc 100644
--- a/config/config_loader_test.go
+++ b/config/config_loader_test.go
@@ -25,22 +25,13 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
-import (
-	"dubbo.apache.org/dubbo-go/v3/config/testdata/config/service"
-)
-
-func init() {
-	SetProviderService(new(service.OrderService))
-	SetProviderService(new(service.HelloService))
-}
-
 const (
 	configPath = "./testdata/application.yaml"
 )
 
 func TestLoad(t *testing.T) {
-	Load(WithPath(configPath))
-
+	err := Load(WithPath(configPath))
+	assert.Nil(t, err)
 	t.Run("application", func(t *testing.T) {
 		application := rootConfig.Application
 
@@ -59,7 +50,7 @@ func TestLoad(t *testing.T) {
 		assert.Equal(t, 2, len(registries))
 		//address= nacos://127.0.0.1:8848 Translate Registry Address
 		assert.Equal(t, "nacos", registries["nacos"].Protocol)
-		assert.Equal(t, "10s", registries["zk"].Timeout)
+		assert.Equal(t, "5s", registries["zk"].Timeout)
 	})
 
 	//config-center
@@ -74,52 +65,32 @@ func TestLoad(t *testing.T) {
 //TestLoadConfigCenter test key  config_center、config-center 、configCenter
 func TestLoadConfigCenter(t *testing.T) {
 
-	t.Run("config-center", func(t *testing.T) {
-		Load(WithPath("./testdata/config/center/conf-application.yaml"))
-		conf := rootConfig.ConfigCenter
-		assert.Equal(t, "nacos", conf.Protocol)
-		assert.Equal(t, "10s", conf.Timeout)
-		assert.Equal(t, "./logs", conf.LogDir)
-	})
+	err := Load(WithPath("./testdata/config/center/conf-application.yaml"))
+	assert.Nil(t, err)
+	conf := rootConfig.ConfigCenter
+	assert.Equal(t, "nacos", conf.Protocol)
+	assert.Equal(t, "10s", conf.Timeout)
+	assert.Equal(t, "./logs", conf.LogDir)
 }
 
 func TestGetRegistriesConfig(t *testing.T) {
-	t.Run("registry", func(t *testing.T) {
-		Load(WithPath("./testdata/config/registry/application.yaml"))
 
-		registries := rootConfig.Registries
-
-		assert.Equal(t, 2, len(registries))
-		// nacos
-		assert.Equal(t, "nacos", registries["nacos"].Protocol)
-		assert.Equal(t, "5s", registries["nacos"].Timeout)
-		assert.Equal(t, "127.0.0.1:8848", registries["nacos"].Address)
-		assert.Equal(t, "dev", registries["nacos"].Group)
-		// zk
-		assert.Equal(t, "zookeeper", registries["zk"].Protocol)
-		assert.Equal(t, "10s", registries["zk"].Timeout)
-		assert.Equal(t, "127.0.0.1:2181", registries["zk"].Address)
-		assert.Equal(t, "test", registries["zk"].Group)
-	})
-}
-
-func TestGetProviderConfig(t *testing.T) {
-	// empty registry
-	t.Run("empty registry", func(t *testing.T) {
-		assert.Nil(t, Load(WithPath("./testdata/config/provider/empty_registry_application.yaml")))
-		provider := rootConfig.Provider
-		assert.Equal(t, 0, len(provider.Registry))
-	})
+	err := Load(WithPath("./testdata/config/registry/application.yaml"))
 
-	t.Run("root registry", func(t *testing.T) {
-		Load(WithPath("./testdata/config/provider/registry_application.yaml"))
-		provider := rootConfig.Provider
-		assert.NotNil(t, provider)
-	})
-}
+	assert.Nil(t, err)
+	registries := rootConfig.Registries
 
-func TestRootConfig(t *testing.T) {
-	Load(WithPath("./testdata/config/app/application.yaml"))
+	assert.Equal(t, 2, len(registries))
+	// nacos
+	assert.Equal(t, "nacos", registries["nacos"].Protocol)
+	assert.Equal(t, "5s", registries["nacos"].Timeout)
+	assert.Equal(t, "127.0.0.1:8848", registries["nacos"].Address)
+	assert.Equal(t, "dev", registries["nacos"].Group)
+	// zk
+	assert.Equal(t, "zookeeper", registries["zk"].Protocol)
+	assert.Equal(t, "5s", registries["zk"].Timeout)
+	assert.Equal(t, "127.0.0.1:2181", registries["zk"].Address)
+	assert.Equal(t, "test", registries["zk"].Group)
 }
 
 //
diff --git a/config/config_utils.go b/config/config_utils.go
index 13ae4d7..82e2859 100644
--- a/config/config_utils.go
+++ b/config/config_utils.go
@@ -93,6 +93,7 @@ func removeDuplicateElement(items []string) []string {
 func translateRegistryIds(registryIds []string) []string {
 	ids := make([]string, 0)
 	for _, id := range registryIds {
+
 		ids = append(ids, strings.Split(id, ",")...)
 	}
 	return removeDuplicateElement(ids)
diff --git a/config/consumer_config.go b/config/consumer_config.go
index 25610d0..9f76e4c 100644
--- a/config/consumer_config.go
+++ b/config/consumer_config.go
@@ -49,10 +49,8 @@ type ConsumerConfig struct {
 	Check          bool   `yaml:"check" json:"check,omitempty" property:"check"`
 
 	References map[string]*ReferenceConfig `yaml:"references" json:"references,omitempty" property:"references"`
-	// ProtocolConf interface{}                 `yaml:"protocol_conf" json:"protocol-conf,omitempty" property:"protocol-conf"`
+
 	FilterConf interface{} `yaml:"filter-conf" json:"filter-conf,omitempty" property:"filter-conf"`
-	// ShutdownConfig *ShutdownConfig                             `yaml:"shutdown_conf" json:"shutdown_conf,omitempty" property:"shutdown_conf"`
-	ConfigType map[string]string `yaml:"config_type" json:"config_type,omitempty" property:"config_type"`
 
 	rootConfig *RootConfig
 }
@@ -66,8 +64,12 @@ func (cc *ConsumerConfig) Init(rc *RootConfig) error {
 	if cc == nil {
 		return nil
 	}
-	for k, _ := range cc.References {
-		if err := cc.References[k].Init(rc); err != nil {
+	cc.Registry = translateRegistryIds(cc.Registry)
+	if len(cc.Registry) <= 0 {
+		cc.Registry = rc.getRegistryIds()
+	}
+	for _, reference := range cc.References {
+		if err := reference.Init(rc); err != nil {
 			return err
 		}
 	}
@@ -78,7 +80,6 @@ func (cc *ConsumerConfig) Init(rc *RootConfig) error {
 		return err
 	}
 	cc.rootConfig = rc
-	cc.Load()
 	return nil
 }
 
@@ -127,7 +128,6 @@ func (cc *ConsumerConfig) Load() {
 			break
 		}
 	}
-
 }
 
 // SetConsumerConfig sets consumerConfig by @c
@@ -196,13 +196,6 @@ func configCenterRefreshConsumer() error {
 	//}
 	return nil
 }
-
-///////////////////////////////////// consumer config api
-// ConsumerConfigOpt is the options to init ConsumerConfig
-type ConsumerConfigOpt func(config *ConsumerConfig) *ConsumerConfig
-
-// NewEmptyConsumerConfig returns default ConsumerConfig
-// with connection timeout = 3s, request timeout = 3s
 func NewEmptyConsumerConfig() *ConsumerConfig {
 
 	newConsumerConfig := &ConsumerConfig{
@@ -224,6 +217,22 @@ func NewConsumerConfig(opts ...ConsumerConfigOpt) *ConsumerConfig {
 	return newConfig
 }
 
+///////////////////////////////////// consumer config api
+// ConsumerConfigOpt is the options to init ConsumerConfig
+type ConsumerConfigOpt func(config *ConsumerConfig) *ConsumerConfig
+
+// GetConsumerInstance returns ConsumerConfig with @opts
+func GetConsumerInstance(opts ...ConsumerConfigOpt) *ConsumerConfig {
+	cc := &ConsumerConfig{
+		References: make(map[string]*ReferenceConfig, 8),
+		Check:      true,
+	}
+	for _, opt := range opts {
+		opt(cc)
+	}
+	return cc
+}
+
 // WithRootConfig returns ConsumerConfigOpt with given @rootConfig
 func WithRootConfig(rootConfig *RootConfig) ConsumerConfigOpt {
 	return func(config *ConsumerConfig) *ConsumerConfig {
diff --git a/config/dubbo_bootstrap.go b/config/dubbo_bootstrap.go
new file mode 100644
index 0000000..c509287
--- /dev/null
+++ b/config/dubbo_bootstrap.go
@@ -0,0 +1,112 @@
+/*
+ * 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 config
+
+import (
+	"sync"
+)
+
+import (
+	hessian "github.com/apache/dubbo-go-hessian2"
+)
+
+import (
+	"dubbo.apache.org/dubbo-go/v3/common"
+	"dubbo.apache.org/dubbo-go/v3/common/extension"
+	"dubbo.apache.org/dubbo-go/v3/common/logger"
+)
+
+var (
+	startOnce sync.Once
+)
+
+func GetInstance(opts ...RootConfigOpt) *RootConfig {
+	registerPOJO()
+	rc := &RootConfig{
+		ConfigCenter:         GetConfigCenterInstance(),
+		ServiceDiscoveries:   make(map[string]*ServiceDiscoveryConfig),
+		MetadataReportConfig: &MetadataReportConfig{},
+		Application:          GetApplicationInstance(),
+		Registries:           make(map[string]*RegistryConfig),
+		Protocols:            GetProtocolsInstance(),
+		Provider:             GetProviderInstance(),
+		Consumer:             GetConsumerInstance(),
+		MetricConfig:         &MetricConfig{},
+		Logger:               GetLoggerConfigInstance(),
+	}
+	for _, opt := range opts {
+		opt(rc)
+	}
+	return rc
+}
+
+func registerPOJO() {
+	hessian.RegisterPOJO(&common.MetadataInfo{})
+	hessian.RegisterPOJO(&common.ServiceInfo{})
+	hessian.RegisterPOJO(&common.URL{})
+}
+
+func (rc *RootConfig) Init() error {
+
+	if err := rc.Logger.Init(); err != nil {
+		return err
+	}
+	if err := rc.ConfigCenter.Init(rc); err != nil {
+		logger.Warnf("config center doesn't start. error is %s", err)
+	}
+	if err := rc.Application.Init(); err != nil {
+		return err
+	}
+	if err := initProtocolsConfig(rc); err != nil {
+		return err
+	}
+	if err := initRegistryConfig(rc); err != nil {
+		return err
+	}
+	if err := initServiceDiscoveryConfig(rc); err != nil {
+		return err
+	}
+	if err := rc.MetadataReportConfig.Init(rc); err != nil {
+		return err
+	}
+	if err := initMetricConfig(rc); err != nil {
+		return err
+	}
+	if err := initRouterConfig(rc); err != nil {
+		return err
+	}
+	// provider、consumer must last init
+	if err := rc.Provider.Init(rc); err != nil {
+		return err
+	}
+	if err := rc.Consumer.Init(rc); err != nil {
+		return err
+	}
+
+	rc.Start()
+	return nil
+}
+
+func (rc *RootConfig) Start() {
+	startOnce.Do(func() {
+		rc.Provider.Load()
+		rc.Consumer.Load()
+		extension.SetAndInitGlobalDispatcher(rootConfig.EventDispatcherType)
+		registerServiceInstance()
+	})
+}
diff --git a/config/logger_config.go b/config/logger_config.go
index de7e9b0..d829256 100644
--- a/config/logger_config.go
+++ b/config/logger_config.go
@@ -31,6 +31,7 @@ import (
 )
 
 import (
+	"dubbo.apache.org/dubbo-go/v3/common/constant"
 	"dubbo.apache.org/dubbo-go/v3/common/logger"
 	"dubbo.apache.org/dubbo-go/v3/common/yaml"
 )
@@ -66,39 +67,49 @@ type EncoderConfig struct {
 	Params         map[string]string `yaml:"params" json:"params,omitempty"`
 }
 
-func initLoggerConfig(rc *RootConfig) error {
-	logConfig := rc.Logger
-	if logConfig == nil {
-		logConfig = new(LoggerConfig)
+// Prefix dubbo.logger
+func (LoggerConfig) Prefix() string {
+	return constant.LoggerConfigPrefix
+}
+
+func GetLoggerConfigInstance() *LoggerConfig {
+	lc := &LoggerConfig{}
+	return lc
+}
+
+func (lc *LoggerConfig) Init() error {
+
+	if lc == nil {
+		lc = GetLoggerConfigInstance()
 	}
-	err := logConfig.check()
+	err := lc.check()
 	if err != nil {
 		return err
 	}
-	rc.Logger = logConfig
-	byte, err := yaml.MarshalYML(logConfig)
+
+	bytes, err := yaml.MarshalYML(lc)
 	if err != nil {
 		return err
 	}
 
 	logConf := &logger.Config{}
-	if err = yaml.UnmarshalYML(byte, logConf); err != nil {
+	if err = yaml.UnmarshalYML(bytes, logConf); err != nil {
 		return err
 	}
-	err = logConfig.ZapConfig.EncoderConfig.setEncoderConfig(&(logConf.ZapConfig.EncoderConfig))
+	err = lc.ZapConfig.EncoderConfig.setEncoderConfig(&(logConf.ZapConfig.EncoderConfig))
 	if err != nil {
 		return err
 	}
-	logConfig.ZapConfig.setZapConfig(logConf.ZapConfig)
+	lc.ZapConfig.setZapConfig(logConf.ZapConfig)
 	logger.InitLogger(logConf)
 	return nil
 }
 
-func (l *LoggerConfig) check() error {
-	if err := defaults.Set(l); err != nil {
+func (lc *LoggerConfig) check() error {
+	if err := defaults.Set(lc); err != nil {
 		return err
 	}
-	return verify(l)
+	return verify(lc)
 }
 
 func (e *ZapConfig) setZapConfig(config *zap.Config) {
@@ -135,9 +146,9 @@ func (e *EncoderConfig) setEncoderConfig(encoderConfig *zapcore.EncoderConfig) e
 	return nil
 }
 
-func (l *LoggerConfig) getUrlMap() url.Values {
+func (lc *LoggerConfig) getUrlMap() url.Values {
 	urlMap := url.Values{}
-	for key, val := range l.ZapConfig.EncoderConfig.Params {
+	for key, val := range lc.ZapConfig.EncoderConfig.Params {
 		urlMap.Set(key, val)
 	}
 	return urlMap
diff --git a/config/logger_config_test.go b/config/logger_config_test.go
index faa96a7..94e464f 100644
--- a/config/logger_config_test.go
+++ b/config/logger_config_test.go
@@ -30,7 +30,6 @@ import (
 )
 
 func TestLoggerInit(t *testing.T) {
-
 	t.Run("empty use default", func(t *testing.T) {
 		err := Load(WithPath("./testdata/config/logger/empty_log.yaml"))
 		assert.Nil(t, err)
diff --git a/config/metadata_report_config.go b/config/metadata_report_config.go
index 70ec753..888edd1 100644
--- a/config/metadata_report_config.go
+++ b/config/metadata_report_config.go
@@ -34,14 +34,13 @@ import (
 
 // MetadataReportConfig is app level configuration
 type MetadataReportConfig struct {
-	Protocol string `required:"true"  yaml:"protocol"  json:"protocol,omitempty"`
-	Address  string `required:"true" yaml:"address" json:"address"`
-	Username string `yaml:"username" json:"username,omitempty"`
-	Password string `yaml:"password" json:"password,omitempty"`
-	Timeout  string `yaml:"timeout" json:"timeout,omitempty"`
-	Group    string `yaml:"group" json:"group,omitempty"`
-
-	MetadataReportType string
+	Protocol     string `required:"true"  yaml:"protocol"  json:"protocol,omitempty"`
+	Address      string `required:"true" yaml:"address" json:"address"`
+	Username     string `yaml:"username" json:"username,omitempty"`
+	Password     string `yaml:"password" json:"password,omitempty"`
+	Timeout      string `yaml:"timeout" json:"timeout,omitempty"`
+	Group        string `yaml:"group" json:"group,omitempty"`
+	MetadataType string `default:"local" yaml:"metadata-type" json:"metadata-type"`
 }
 
 // Prefix dubbo.consumer
@@ -49,23 +48,21 @@ func (MetadataReportConfig) Prefix() string {
 	return constant.MetadataReportPrefix
 }
 
-func (m *MetadataReportConfig) Init(rc *RootConfig) error {
-	if m == nil {
+func (mc *MetadataReportConfig) Init(rc *RootConfig) error {
+	if mc == nil {
 		return nil
 	}
-	m.MetadataReportType = rc.Application.MetadataType
-	return m.StartMetadataReport()
+	mc.MetadataType = rc.Application.MetadataType
+	return mc.StartMetadataReport()
 }
 
-// nolint
-func (c *MetadataReportConfig) ToUrl() (*common.URL, error) {
-	res, err := common.NewURL(c.Address,
-		//common.WithParams(urlMap),
-		common.WithUsername(c.Username),
-		common.WithPassword(c.Password),
-		common.WithLocation(c.Address),
-		common.WithProtocol(c.Protocol),
-		common.WithParamsValue(constant.METADATATYPE_KEY, c.MetadataReportType),
+func (mc *MetadataReportConfig) ToUrl() (*common.URL, error) {
+	res, err := common.NewURL(mc.Address,
+		common.WithUsername(mc.Username),
+		common.WithPassword(mc.Password),
+		common.WithLocation(mc.Address),
+		common.WithProtocol(mc.Protocol),
+		common.WithParamsValue(constant.METADATATYPE_KEY, mc.MetadataType),
 	)
 	if err != nil || len(res.Protocol) == 0 {
 		return nil, perrors.New("Invalid MetadataReportConfig.")
@@ -74,16 +71,16 @@ func (c *MetadataReportConfig) ToUrl() (*common.URL, error) {
 	return res, nil
 }
 
-func (c *MetadataReportConfig) IsValid() bool {
-	return len(c.Protocol) != 0
+func (mc *MetadataReportConfig) IsValid() bool {
+	return len(mc.Protocol) != 0
 }
 
 // StartMetadataReport: The entry of metadata report start
-func (c *MetadataReportConfig) StartMetadataReport() error {
-	if c == nil || !c.IsValid() {
+func (mc *MetadataReportConfig) StartMetadataReport() error {
+	if mc == nil || !mc.IsValid() {
 		return nil
 	}
-	if tmpUrl, err := c.ToUrl(); err == nil {
+	if tmpUrl, err := mc.ToUrl(); err == nil {
 		instance.GetMetadataReportInstance(tmpUrl)
 		return nil
 	} else {
diff --git a/config/protocol_config.go b/config/protocol_config.go
index ab24145..0a1a1a9 100644
--- a/config/protocol_config.go
+++ b/config/protocol_config.go
@@ -29,10 +29,19 @@ import (
 type ProtocolConfig struct {
 	Name   string      `default:"dubbo" validate:"required" yaml:"name" json:"name,omitempty" property:"name"`
 	Ip     string      `yaml:"ip"  json:"ip,omitempty" property:"ip"`
-	Port   string      `default:"2000" yaml:"port" json:"port,omitempty" property:"port"`
+	Port   string      `default:"20000" yaml:"port" json:"port,omitempty" property:"port"`
 	Params interface{} `yaml:"params" json:"params,omitempty" property:"params"`
 }
 
+// Prefix dubbo.config-center
+func (ProtocolConfig) Prefix() string {
+	return constant.ConfigCenterPrefix
+}
+
+func GetProtocolsInstance() map[string]*ProtocolConfig {
+	return make(map[string]*ProtocolConfig, 1)
+}
+
 func initProtocolsConfig(rc *RootConfig) error {
 	protocols := rc.Protocols
 	if len(protocols) <= 0 {
@@ -52,7 +61,9 @@ func initProtocolsConfig(rc *RootConfig) error {
 }
 
 func (p *ProtocolConfig) check() error {
-	defaults.MustSet(p)
+	if err := defaults.Set(p); err != nil {
+		return err
+	}
 	return verify(p)
 }
 
diff --git a/config/protocol_config_test.go b/config/protocol_config_test.go
index 64d7737..b278120 100644
--- a/config/protocol_config_test.go
+++ b/config/protocol_config_test.go
@@ -34,7 +34,7 @@ func TestGetProtocolsConfig(t *testing.T) {
 		assert.NotNil(t, protocols)
 		// default
 		assert.Equal(t, "dubbo", protocols["dubbo"].Name)
-		assert.Equal(t, string("2000"), protocols["dubbo"].Port)
+		assert.Equal(t, string("20000"), protocols["dubbo"].Port)
 	})
 
 	t.Run("use config", func(t *testing.T) {
@@ -44,6 +44,6 @@ func TestGetProtocolsConfig(t *testing.T) {
 		assert.NotNil(t, protocols)
 		// default
 		assert.Equal(t, "dubbo", protocols["dubbo"].Name)
-		assert.Equal(t, string("2000"), protocols["dubbo"].Port)
+		assert.Equal(t, string("20000"), protocols["dubbo"].Port)
 	})
 }
diff --git a/config/provider_config.go b/config/provider_config.go
index f8bd8fd..a77f3f9 100644
--- a/config/provider_config.go
+++ b/config/provider_config.go
@@ -32,10 +32,8 @@ import (
 
 // ProviderConfig is the default configuration of service provider
 type ProviderConfig struct {
-	//base.ShutdownConfig         `yaml:",inline" property:"base"`
-	//center.configCenter `yaml:"-"`
 	Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"`
-	// Register whether registration is required
+	// Deprecated Register whether registration is required
 	Register bool `yaml:"register" json:"register" property:"register"`
 	// Registry registry ids
 	Registry []string `yaml:"registry" json:"registry" property:"registry"`
@@ -49,9 +47,14 @@ type ProviderConfig struct {
 	ConfigType map[string]string `yaml:"config_type" json:"config_type,omitempty" property:"config_type"`
 }
 
-func (c *ProviderConfig) CheckConfig() error {
-	// todo check
-	defaults.MustSet(c)
+func (ProviderConfig) Prefix() string {
+	return constant.ProviderConfigPrefix
+}
+
+func (c *ProviderConfig) check() error {
+	if err := defaults.Set(c); err != nil {
+		return err
+	}
 	return verify(c)
 }
 
@@ -59,45 +62,21 @@ func (c *ProviderConfig) Init(rc *RootConfig) error {
 	if c == nil {
 		return nil
 	}
-	for k, _ := range c.Services {
-		if err := c.Services[k].Init(rc); err != nil {
+	c.Registry = translateRegistryIds(c.Registry)
+	if len(c.Registry) <= 0 {
+		c.Registry = rc.getRegistryIds()
+	}
+	for _, service := range c.Services {
+		if err := service.Init(rc); err != nil {
 			return err
 		}
 	}
-	if err := defaults.Set(c); err != nil {
+	if err := c.check(); err != nil {
 		return err
 	}
-	c.Registry = translateRegistryIds(c.Registry)
-	c.Load()
 	return nil
 }
 
-func (c *ProviderConfig) Validate(r *RootConfig) {
-	ids := make([]string, 0)
-	for key := range r.Registries {
-		ids = append(ids, key)
-	}
-	c.Registry = removeDuplicateElement(ids)
-	for k, _ := range c.Services {
-		c.Services[k].Validate(r)
-	}
-	// todo set default application
-}
-
-// UnmarshalYAML unmarshals the ProviderConfig by @unmarshal function
-//func (c *ProviderConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
-//	if err := defaults.Set(c); err != nil {
-//		return err
-//	}
-//	type plain ProviderConfig
-//	return unmarshal((*plain)(c))
-//}
-
-// Prefix dubbo.provider
-func (c *ProviderConfig) Prefix() string {
-	return constant.ProviderConfigPrefix
-}
-
 func (c *ProviderConfig) Load() {
 	for key, svs := range c.Services {
 		rpcService := GetProviderService(key)
@@ -111,6 +90,7 @@ func (c *ProviderConfig) Load() {
 			logger.Errorf(fmt.Sprintf("service %s export failed! err: %#v", key, err))
 		}
 	}
+
 }
 
 // SetProviderConfig sets provider config by @p
@@ -118,43 +98,6 @@ func SetProviderConfig(p ProviderConfig) {
 	rootConfig.Provider = &p
 }
 
-//
-//// ProviderInit loads config file to init provider config
-//func ProviderInit(confProFile string) error {
-//	if len(confProFile) == 0 {
-//		return perrors.Errorf("applicationConfig configure(provider) file name is nil")
-//	}
-//	  providerConfig = &ProviderConfig{}
-//	fileStream, err := yaml.UnmarshalYMLConfig(confProFile,   providerConfig)
-//	if err != nil {
-//		return perrors.Errorf("unmarshalYmlConfig error %v", perrors.WithStack(err))
-//	}
-//
-//	  provider  fileStream = bytes.NewBuffer(fileStream)
-//	// set method interfaceId & interfaceName
-//	for k, v := range   provider  Services {
-//		// set id for reference
-//		for _, n := range   provider  Services[k].Methods {
-//			n.InterfaceName = v.InterfaceName
-//			n.InterfaceId = k
-//		}
-//	}
-//
-//	return nil
-//}
-//
-//func configCenterRefreshProvider() error {
-//	// fresh it
-//	if   provider  ConfigCenterConfig != nil {
-//		  provider  fatherConfig =   providerConfig
-//		if err :=   provider  startConfigCenter((*  providerConfig).BaseConfig); err != nil {
-//			return perrors.Errorf("start config center error , error message is {%v}", perrors.WithStack(err))
-//		}
-//		  provider  fresh()
-//	}
-//	return nil
-//}
-
 ///////////////////////////////////// provider config api
 // ProviderConfigOpt is the
 type ProviderConfigOpt func(config *ProviderConfig) *ProviderConfig
@@ -177,6 +120,18 @@ func NewProviderConfig(opts ...ProviderConfigOpt) *ProviderConfig {
 	return newConfig
 }
 
+// GetProviderInstance returns ProviderConfig with given @opts
+func GetProviderInstance(opts ...ProviderConfigOpt) *ProviderConfig {
+	newConfig := &ProviderConfig{
+		Services: make(map[string]*ServiceConfig),
+		Registry: make([]string, 8),
+	}
+	for _, opt := range opts {
+		opt(newConfig)
+	}
+	return newConfig
+}
+
 // WithProviderServices returns ProviderConfig with given serviceNameKey @serviceName and @serviceConfig
 func WithProviderService(serviceName string, serviceConfig *ServiceConfig) ProviderConfigOpt {
 	return func(config *ProviderConfig) *ProviderConfig {
diff --git a/config/provider_config_test.go b/config/provider_config_test.go
index 4427b0d..27b3c66 100644
--- a/config/provider_config_test.go
+++ b/config/provider_config_test.go
@@ -17,25 +17,33 @@
 
 package config
 
-//import (
-//	"dubbo.apache.org/dubbo-go/v3/config"
-//	"dubbo.apache.org/dubbo-go/v3/config/consumer"
-//	"path/filepath"
-//	"testing"
-//)
-//
-//import (
-//	"github.com/stretchr/testify/assert"
-//)
-//
-//func TestConsumerInit(t *testing.T) {
-//	conPath, err := filepath.Abs("./testdata/consumer_config_with_configcenter.yml")
-//	assert.NoError(t, err)
-//	assert.NoError(t, consumer.ConsumerInit(conPath))
-//	assert.Equal(t, "default", config.consumerConfig.ProxyFactory)
-//	assert.Equal(t, "dubbo.properties", config.consumerConfig.ConfigCenterConfig.ConfigFile)
-//	assert.Equal(t, "100ms", config.consumerConfig.Connect_Timeout)
-//}
+import (
+	"testing"
+)
+
+import (
+	"github.com/stretchr/testify/assert"
+)
+
+func TestProviderConfigEmptyRegistry(t *testing.T) {
+	err := Load(WithPath("./testdata/config/provider/empty_registry_application.yaml"))
+	assert.Nil(t, err)
+	provider := rootConfig.Provider
+	assert.Equal(t, 1, len(provider.Registry))
+	assert.Equal(t, "nacos", provider.Registry[0])
+}
+
+func TestProviderConfigRootRegistry(t *testing.T) {
+	err := Load(WithPath("./testdata/config/provider/registry_application.yaml"))
+	assert.Nil(t, err)
+	provider := rootConfig.Provider
+	assert.NotNil(t, provider)
+	assert.Equal(t, 2, len(provider.Services))
+
+	assert.Equal(t, 2, len(provider.Services["HelloService"].Registry))
+	assert.Equal(t, 1, len(provider.Services["OrderService"].Registry))
+}
+
 //
 //func TestConsumerInitWithDefaultProtocol(t *testing.T) {
 //	conPath, err := filepath.Abs("./testdata/consumer_config_withoutProtocol.yml")
diff --git a/config/reference_config.go b/config/reference_config.go
index 0318a7b..986a390 100644
--- a/config/reference_config.go
+++ b/config/reference_config.go
@@ -77,20 +77,24 @@ func (rc *ReferenceConfig) Prefix() string {
 	return constant.ReferenceConfigPrefix + rc.InterfaceName + "."
 }
 
-func (cc *ReferenceConfig) Init(rc *RootConfig) error {
-	for k, _ := range cc.Methods {
-		if err := cc.Methods[k].Init(); err != nil {
+func (rc *ReferenceConfig) Init(root *RootConfig) error {
+	for _, method := range rc.Methods {
+		if err := method.Init(); err != nil {
 			return err
 		}
 	}
 	if err := defaults.Set(rc); err != nil {
 		return err
 	}
-	cc.rootConfig = rc
-	if rc.Application != nil {
-		cc.metaDataType = rc.Application.MetadataType
+	rc.rootConfig = root
+	if root.Application != nil {
+		rc.metaDataType = root.Application.MetadataType
 	}
-	return verify(cc)
+	rc.Registry = translateRegistryIds(rc.Registry)
+	if len(rc.Registry) <= 0 {
+		rc.Registry = root.Consumer.Registry
+	}
+	return verify(rc)
 }
 
 // Refer ...
diff --git a/config/registry_config.go b/config/registry_config.go
index f96bbb4..c811eee 100644
--- a/config/registry_config.go
+++ b/config/registry_config.go
@@ -38,10 +38,10 @@ import (
 // RegistryConfig is the configuration of the registry center
 type RegistryConfig struct {
 	Protocol  string `validate:"required" yaml:"protocol"  json:"protocol,omitempty" property:"protocol"`
-	Timeout   string `default:"10s" validate:"required" yaml:"timeout" json:"timeout,omitempty" property:"timeout"` // unit: second
+	Timeout   string `default:"5s" validate:"required" yaml:"timeout" json:"timeout,omitempty" property:"timeout"` // unit: second
 	Group     string `yaml:"group" json:"group,omitempty" property:"group"`
 	Namespace string `yaml:"namespace" json:"namespace,omitempty" property:"namespace"`
-	TTL       string `default:"10m" yaml:"ttl" json:"ttl,omitempty" property:"ttl"` // unit: minute
+	TTL       string `default:"10s" yaml:"ttl" json:"ttl,omitempty" property:"ttl"` // unit: minute
 	// for registry
 	Address    string `validate:"required" yaml:"address" json:"address,omitempty" property:"address"`
 	Username   string `yaml:"username" json:"username,omitempty" property:"username"`
@@ -58,7 +58,7 @@ type RegistryConfig struct {
 	RegistryType string            `yaml:"registry-type"`
 }
 
-// Prefix dubbo.registriesConfig
+// Prefix dubbo.registries
 func (RegistryConfig) Prefix() string {
 	return constant.RegistryConfigPrefix
 }
@@ -71,8 +71,16 @@ func (c *RegistryConfig) check() error {
 	return verify(c)
 }
 
-func (c *RegistryConfig) Init() error {
-	return c.check()
+// initRegistryConfig init registry config
+func initRegistryConfig(rc *RootConfig) error {
+	registries := rc.Registries
+	for key, reg := range registries {
+		if err := reg.check(); err != nil {
+			return err
+		}
+		registries[key] = reg
+	}
+	return nil
 }
 
 func (c *RegistryConfig) getUrlMap(roleType common.RoleType) url.Values {
@@ -97,27 +105,27 @@ func (c *RegistryConfig) getUrlMap(roleType common.RoleType) url.Values {
 //  eg:address=nacos://127.0.0.1:8848 will return 127.0.0.1:8848 and protocol will set nacos
 func (c *RegistryConfig) translateRegistryAddress() string {
 	if strings.Contains(c.Address, "://") {
-		translatedUrl, err := url.Parse(c.Address)
+		u, err := url.Parse(c.Address)
 		if err != nil {
 			logger.Errorf("The registry url is invalid, error: %#v", err)
 			panic(err)
 		}
-		c.Protocol = translatedUrl.Scheme
-		c.Address = strings.Replace(c.Address, translatedUrl.Scheme+"://", "", -1)
+		c.Protocol = u.Scheme
+		c.Address = strings.Join([]string{u.Host, u.Path}, "")
 	}
 	return c.Address
 }
 
 func (c *RegistryConfig) GetInstance(roleType common.RoleType) (registry.Registry, error) {
-	url, err := c.toURL(roleType)
+	u, err := c.toURL(roleType)
 	if err != nil {
 		return nil, err
 	}
 	// if the protocol == registry, set protocol the registry value in url.params
-	if url.Protocol == constant.REGISTRY_PROTOCOL {
-		url.Protocol = url.GetParam(constant.REGISTRY_KEY, "")
+	if u.Protocol == constant.REGISTRY_PROTOCOL {
+		u.Protocol = u.GetParam(constant.REGISTRY_KEY, "")
 	}
-	return extension.GetRegistry(url.Protocol, url)
+	return extension.GetRegistry(u.Protocol, u)
 }
 
 func (c *RegistryConfig) toURL(roleType common.RoleType) (*common.URL, error) {
diff --git a/config/registry_config_test.go b/config/registry_config_test.go
index f1f4716..d9c5521 100644
--- a/config/registry_config_test.go
+++ b/config/registry_config_test.go
@@ -68,8 +68,8 @@ func TestTranslateRegistryAddress(t *testing.T) {
 	reg := new(RegistryConfig)
 	reg.Address = "nacos://127.0.0.1:8848"
 
-	address := reg.translateRegistryAddress()
+	reg.translateRegistryAddress()
 
 	assert.Equal(t, "nacos", reg.Protocol)
-	assert.Equal(t, "127.0.0.1:8848", address)
+	assert.Equal(t, "127.0.0.1:8848", reg.Address)
 }
diff --git a/config/root_config.go b/config/root_config.go
index de7731c..36d24b5 100644
--- a/config/root_config.go
+++ b/config/root_config.go
@@ -18,14 +18,11 @@
 package config
 
 import (
-	"bytes"
-	"net/http"
 	_ "net/http/pprof"
 )
 
 import (
 	"dubbo.apache.org/dubbo-go/v3/common/constant"
-	"dubbo.apache.org/dubbo-go/v3/common/logger"
 )
 
 // RootConfig is the root config
@@ -62,25 +59,14 @@ type RootConfig struct {
 	// Shutdown config
 	Shutdown *ShutdownConfig `yaml:"shutdown" json:"shutdown,omitempty" property:"shutdown"`
 
-	// Deprecated
-	Network map[interface{}]interface{} `yaml:"network" json:"network,omitempty" property:"network"`
-
 	Router []*RouterConfig `yaml:"router" json:"router,omitempty" property:"router"`
-	// is refresh action
-	refresh bool
-	// prefix              string
-	fatherConfig        interface{}
-	EventDispatcherType string `default:"direct" yaml:"event_dispatcher_type" json:"event_dispatcher_type,omitempty"`
-	fileStream          *bytes.Buffer
+
+	EventDispatcherType string `default:"direct" yaml:"event-dispatcher-type" json:"event-dispatcher-type,omitempty"`
 
 	// cache file used to store the current used configurations.
 	CacheFile string `yaml:"cache_file" json:"cache_file,omitempty" property:"cache_file"`
 }
 
-func init() {
-	rootConfig = NewRootConfig()
-}
-
 func SetRootConfig(r RootConfig) {
 	rootConfig = &r
 }
@@ -90,137 +76,28 @@ func (RootConfig) Prefix() string {
 	return constant.DUBBO
 }
 
-// Init init config
-func (rc *RootConfig) Init() error {
-	if err := initLoggerConfig(rc); err != nil {
-		return err
-	}
-	if err := rc.ConfigCenter.Init(rc); err != nil {
-		logger.Infof("config center doesn't start. error is %s", err)
-	}
-	if err := rc.Application.Init(rc); err != nil {
-		return err
-	}
-	if err := initProtocolsConfig(rc); err != nil {
-		return err
-	}
-	for i, _ := range rc.Registries {
-		if err := rc.Registries[i].Init(); err != nil {
-			return err
-		}
-	}
-	if err := initServiceDiscoveryConfig(rc); err != nil {
-		return err
-	}
-	if err := rc.MetadataReportConfig.Init(rc); err != nil {
-		return err
-	}
-	if err := initMetricConfig(rc); err != nil {
-		return err
-	}
-	if err := initNetworkConfig(rc); err != nil {
-		return err
-	}
-	if err := initRouterConfig(rc); err != nil {
-		return err
-	}
-	// provider、consumer must last init
-	if err := rc.Provider.Init(rc); err != nil {
-		return err
-	}
-	if err := rc.Consumer.Init(rc); err != nil {
-		return err
-	}
-	go func() {
-		_ = http.ListenAndServe("0.0.0.0:6060", nil)
-	}()
-	return nil
-}
-
-//func (rc *RootConfig) CheckConfig() error {
-//	defaults.MustSet(rc)
-//
-//	if err := rc.Application.CheckConfig(); err != nil {
-//		return err
-//	}
-//
-//	for k, _ := range rc.Registries {
-//		if err := rc.Registries[k].CheckConfig(); err != nil {
-//			return err
-//		}
-//	}
-//
-//	for k, _ := range rc.Protocols {
-//		if err := rc.Protocols[k].CheckConfig(); err != nil {
-//			return err
-//		}
-//	}
-//
-//	if err := rc.ConfigCenter.CheckConfig(); err != nil {
-//		return err
-//	}
-//
-//	if err := rc.MetadataReportConfig.CheckConfig(); err != nil {
-//		return err
-//	}
-//
-//	if err := rc.Provider.CheckConfig(); err != nil {
-//		return err
-//	}
-//
-//	if err := rc.Consumer.CheckConfig(); err != nil {
-//		return err
-//	}
-//
-//	return verify(rootConfig)
-//}
-
-//func (rc *RootConfig) Validate() {
-//	// 2. validate config
-//	rc.Application.Validate()
-//
-//	for k, _ := range rc.Registries {
-//		rc.Registries[k].Validate()
-//	}
-//
-//	for k, _ := range rc.Protocols {
-//		rc.Protocols[k].Validate()
-//	}
-//
-//	for k, _ := range rc.Registries {
-//		rc.Registries[k].Validate()
-//	}
-//
-//	rc.ConfigCenter.Validate()
-//	rc.MetadataReportConfig.Validate()
-//	rc.Provider.Validate(rc)
-//	rc.Consumer.Validate(rc)
-//}
-
-//GetApplicationConfig get applicationConfig config
-
 func GetRootConfig() *RootConfig {
 	return rootConfig
 }
 
 func GetProviderConfig() *ProviderConfig {
 	if err := check(); err != nil {
-		return NewProviderConfig()
+		return GetProviderInstance()
 	}
 	if rootConfig.Provider != nil {
 		return rootConfig.Provider
 	}
-	return NewProviderConfig()
+	return GetProviderInstance()
 }
 
 func GetConsumerConfig() *ConsumerConfig {
 	if err := check(); err != nil {
-		return NewConsumerConfig()
+		return GetConsumerInstance()
 	}
 	if rootConfig.Consumer != nil {
 		return rootConfig.Consumer
 	}
-	return NewConsumerConfig()
+	return GetConsumerInstance()
 }
 
 func GetApplicationConfig() *ApplicationConfig {
@@ -309,15 +186,16 @@ func GetApplicationConfig() *ApplicationConfig {
 //	return provider, nil
 //}
 
-//// getRegistryIds get registry keys
-//func getRegistryIds() []string {
-//	ids := make([]string, 0)
-//	for key := range rootConfig.Registries {
-//		ids = append(ids, key)
-//	}
-//	return removeDuplicateElement(ids)
-//}
+// getRegistryIds get registry ids
+func (rc *RootConfig) getRegistryIds() []string {
+	ids := make([]string, 0)
+	for key := range rc.Registries {
+		ids = append(ids, key)
+	}
+	return removeDuplicateElement(ids)
+}
 
+// NewRootConfig get root config
 func NewRootConfig(opts ...RootConfigOpt) *RootConfig {
 	newRootConfig := &RootConfig{
 		ConfigCenter:         &CenterConfig{},
@@ -326,8 +204,8 @@ func NewRootConfig(opts ...RootConfigOpt) *RootConfig {
 		Application:          &ApplicationConfig{},
 		Registries:           make(map[string]*RegistryConfig),
 		Protocols:            make(map[string]*ProtocolConfig),
-		Provider:             NewProviderConfig(),
-		Consumer:             NewConsumerConfig(),
+		Provider:             GetProviderInstance(),
+		Consumer:             GetConsumerInstance(),
 		MetricConfig:         &MetricConfig{},
 	}
 	for _, o := range opts {
diff --git a/config/service_config.go b/config/service_config.go
index 3948fc0..53dce7a 100644
--- a/config/service_config.go
+++ b/config/service_config.go
@@ -93,7 +93,7 @@ type ServiceConfig struct {
 
 // Prefix returns dubbo.service.${InterfaceName}.
 func (svc *ServiceConfig) Prefix() string {
-	return constant.ServiceConfigPrefix + svc.id
+	return strings.Join([]string{constant.ServiceConfigPrefix, svc.id}, ".")
 }
 
 func (svc *ServiceConfig) Init(rc *RootConfig) error {
@@ -111,75 +111,14 @@ func (svc *ServiceConfig) Init(rc *RootConfig) error {
 	if rc.Provider != nil {
 		svc.ProxyFactoryKey = rc.Provider.ProxyFactory
 	}
-
+	svc.Registry = translateRegistryIds(svc.Registry)
+	if len(svc.Registry) <= 0 {
+		svc.Registry = rc.Provider.Registry
+	}
 	svc.export = true
 	return verify(svc)
 }
 
-// UnmarshalYAML unmarshal the ServiceConfig by @unmarshal function
-//func (c *ServiceConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
-//	if err := defaults.Set(c); err != nil {
-//		return err
-//	}
-//	type plain ServiceConfig
-//	if err := unmarshal((*plain)(c)); err != nil {
-//		return err
-//	}
-//	c.exported = atomic.NewBool(false)
-//	c.unexported = atomic.NewBool(false)
-//	c.export = true
-//	return nil
-//}
-
-func (svc *ServiceConfig) CheckConfig() error {
-	// todo check
-	defaults.MustSet(svc)
-	return verify(svc)
-}
-
-func (svc *ServiceConfig) Validate(rootConfig *RootConfig) {
-	svc.exported = atomic.NewBool(false)
-	svc.unexported = atomic.NewBool(false)
-	svc.export = true
-	// todo set default application
-}
-
-//getRegistryServices get registry services
-func getRegistryServices(side int, services map[string]*ServiceConfig, registryIds []string) map[string]*ServiceConfig {
-	var (
-		svc              *ServiceConfig
-		exist            bool
-		initService      map[string]common.RPCService
-		registryServices map[string]*ServiceConfig
-	)
-	if side == common.PROVIDER {
-		initService = proServices
-	} else if side == common.CONSUMER {
-		initService = conServices
-	}
-	registryServices = make(map[string]*ServiceConfig, len(initService))
-	for key := range initService {
-		//存在配置了使用用户的配置
-		if svc, exist = services[key]; !exist {
-			svc = new(ServiceConfig)
-		}
-		defaults.MustSet(svc)
-		if len(svc.Registry) <= 0 {
-			svc.Registry = registryIds
-		}
-		svc.id = key
-		svc.export = true
-		svc.unexported = atomic.NewBool(false)
-		svc.exported = atomic.NewBool(false)
-		svc.Registry = translateRegistryIds(svc.Registry)
-		if err := verify(svc); err != nil {
-			return nil
-		}
-		registryServices[key] = svc
-	}
-	return registryServices
-}
-
 // InitExported will set exported as false atom bool
 func (svc *ServiceConfig) InitExported() {
 	svc.exported = atomic.NewBool(false)
diff --git a/config/testdata/config/app/application.yaml b/config/testdata/config/app/application.yaml
index 2dcb875..4cd30cc 100644
--- a/config/testdata/config/app/application.yaml
+++ b/config/testdata/config/app/application.yaml
@@ -2,7 +2,7 @@ dubbo:
   registries:
     nacos:
       timeout: 3s
-      address: zookeeper://127.0.0.1:2182
+      address: nacos://127.0.0.1:8848
   protocols:
     dubbo:
       name: dubbo
diff --git a/config/testdata/config/application/application.yaml b/config/testdata/config/application/application.yaml
new file mode 100644
index 0000000..ea32df4
--- /dev/null
+++ b/config/testdata/config/application/application.yaml
@@ -0,0 +1,4 @@
+dubbo:
+  registries:
+    nacos:
+      address: nacos://127.0.0.1:8848
\ No newline at end of file
diff --git a/config/testdata/config/protocol/application.yaml b/config/testdata/config/protocol/application.yaml
index bc0aecb..4f06d63 100644
--- a/config/testdata/config/protocol/application.yaml
+++ b/config/testdata/config/protocol/application.yaml
@@ -1,2 +1,7 @@
 dubbo:
+  registries:
+    nacos:
+      timeout: 5s
+      group: dev
+      address: nacos://127.0.0.1:8848
   protocols:
\ No newline at end of file
diff --git a/config/testdata/config/protocol/empty_application.yaml b/config/testdata/config/protocol/empty_application.yaml
index bc0aecb..4f06d63 100644
--- a/config/testdata/config/protocol/empty_application.yaml
+++ b/config/testdata/config/protocol/empty_application.yaml
@@ -1,2 +1,7 @@
 dubbo:
+  registries:
+    nacos:
+      timeout: 5s
+      group: dev
+      address: nacos://127.0.0.1:8848
   protocols:
\ No newline at end of file
diff --git a/config/testdata/config/provider/application.yaml b/config/testdata/config/provider/application.yaml
index 45e7231..8816257 100644
--- a/config/testdata/config/provider/application.yaml
+++ b/config/testdata/config/provider/application.yaml
@@ -1,4 +1,9 @@
 dubbo:
+  registries:
+    nacos:
+      timeout: 5s
+      group: dev
+      address: nacos://127.0.0.1:8848
   provider:
     register: true
     registry:
diff --git a/config/testdata/config/provider/registry_application.yaml b/config/testdata/config/provider/registry_application.yaml
index f5b04de..dd08a0d 100644
--- a/config/testdata/config/provider/registry_application.yaml
+++ b/config/testdata/config/provider/registry_application.yaml
@@ -1,10 +1,13 @@
 dubbo:
+  registries:
+    nacos:
+      timeout: 3s
+      address: naocs://127.0.0.1:8848
   provider:
-    register: true
-    registry: nacos,zk
+    registry: nacos
     services:
-      helloService:
+      HelloService:
         interface: org.dubbo.service.HelloService
         registry: nacos,zk
-      orderService:
+      OrderService:
         interface: org.dubbo.service.OrderService
\ No newline at end of file
diff --git a/config/testdata/config/service/hello_service.go b/config/testdata/config/service/hello_service.go
deleted file mode 100644
index b2b97d5..0000000
--- a/config/testdata/config/service/hello_service.go
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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 service
-
-import (
-	"context"
-)
-
-type HelloService struct {
-	// say hello
-	Say func(ctx context.Context, req []interface{}) error
-}
-
-func (HelloService) Reference() string {
-	return "helloService"
-}
diff --git a/config/testdata/config/service/order_service.go b/config/testdata/config/service/order_service.go
deleted file mode 100644
index 9b43de8..0000000
--- a/config/testdata/config/service/order_service.go
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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 service
-
-import (
-	"context"
-)
-
-type OrderService struct {
-	// GetOrders
-	GetOrders func(ctx context.Context, req []interface{}) error
-}
-
-func (OrderService) Reference() string {
-	return "orderService"
-}
diff --git a/go.mod b/go.mod
index c8107dd..8ba6c83 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,6 @@ module dubbo.apache.org/dubbo-go/v3
 go 1.15
 
 require (
-	contrib.go.opencensus.io/exporter/prometheus v0.4.0
 	github.com/RoaringBitmap/roaring v0.7.1
 	github.com/Workiva/go-datastructures v1.0.52
 	github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5
@@ -20,6 +19,7 @@ require (
 	github.com/go-co-op/gocron v0.1.1
 	github.com/go-playground/validator/v10 v10.7.0
 	github.com/go-resty/resty/v2 v2.3.0
+	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
 	github.com/golang/mock v1.4.4
 	github.com/golang/protobuf v1.5.2
 	github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645
@@ -34,6 +34,7 @@ require (
 	github.com/opentracing/opentracing-go v1.2.0
 	github.com/pkg/errors v0.9.1
 	github.com/prometheus/client_golang v1.11.0
+	github.com/prometheus/common v0.28.0 // indirect
 	github.com/satori/go.uuid v1.2.0
 	github.com/stretchr/testify v1.7.0
 	github.com/zouyx/agollo/v3 v3.4.5
diff --git a/go.sum b/go.sum
index bc3909e..5519d42 100644
--- a/go.sum
+++ b/go.sum
@@ -32,8 +32,6 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
 cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
 cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
-contrib.go.opencensus.io/exporter/prometheus v0.4.0 h1:0QfIkj9z/iVZgK31D9H9ohjjIDApI2GOPScCKwxedbs=
-contrib.go.opencensus.io/exporter/prometheus v0.4.0/go.mod h1:o7cosnyfuPVK0tB8q0QmaQNhGnptITnPQB+z1+qeFB0=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
 github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
@@ -238,14 +236,12 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
-github.com/go-kit/log v0.1.0 h1:DGJh0Sm43HbOeYDNnVZFl8BvcYVvjD5bqYJvp0REbwQ=
 github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
 github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
 github.com/go-ldap/ldap/v3 v3.1.3/go.mod h1:3rbOH3jRS2u6jg2rJnKAMLE/xQyCKIveG2Sa/Cohzb8=
 github.com/go-ldap/ldap/v3 v3.1.10/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q=
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
-github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4=
 github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
 github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
 github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
@@ -267,7 +263,6 @@ github.com/go-resty/resty/v2 v2.3.0 h1:JOOeAvjSlapTT92p8xiS19Zxev1neGikoHsXJeOq8
 github.com/go-resty/resty/v2 v2.3.0/go.mod h1:UpN9CgLZNsv4e9XG50UU8xdI0F43UQ4HmxLBDwaroHU=
 github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
 github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
-github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
 github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
@@ -330,7 +325,6 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@@ -665,8 +659,6 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
 github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
 github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
 github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/prometheus/statsd_exporter v0.21.0 h1:hA05Q5RFeIjgwKIYEdFd59xu5Wwaznf33yKI+pyX6T8=
-github.com/prometheus/statsd_exporter v0.21.0/go.mod h1:rbT83sZq2V+p73lHhPZfMc3MLCHmSHelCh9hSGYNLTQ=
 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
 github.com/rhnvrm/simples3 v0.6.1/go.mod h1:Y+3vYm2V7Y4VijFoJHHTrja6OgPrJ2cBti8dPGkC3sA=
@@ -733,7 +725,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
@@ -795,8 +786,6 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
-go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
 go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
@@ -903,7 +892,6 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
 golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
@@ -1153,7 +1141,6 @@ google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
 google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
 google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
-google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
 google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
 google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
 google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
diff --git a/integrate_test.sh b/integrate_test.sh
index 682e7e7..b12c653 100644
--- a/integrate_test.sh
+++ b/integrate_test.sh
@@ -37,7 +37,7 @@ echo "github pull request head branch -> ${GITHUB_HEAD_REF}"
 
 samples_testing() {
     echo "use dubbo-go-samples $3 branch for integration testing"
-    git clone -b "$3" https://github.com/apache/dubbo-go-samples.git samples && cd samples
+    git clone -b master https://github.com/apache/dubbo-go-samples.git samples && cd samples
 
     # update dubbo-go to current commit id
     go mod edit -replace=dubbo.apache.org/dubbo-go/v3=github.com/"$1"/v3@"$2"
diff --git a/metadata/service/exporter/configurable/exporter_test.go b/metadata/service/exporter/configurable/exporter_test.go
index 55393e1..1fe775d 100644
--- a/metadata/service/exporter/configurable/exporter_test.go
+++ b/metadata/service/exporter/configurable/exporter_test.go
@@ -78,7 +78,7 @@ func TestConfigurableExporter(t *testing.T) {
 
 // mockInitProviderWithSingleRegistry will init a mocked providerConfig
 func mockInitProviderWithSingleRegistry() {
-	providerConfig := config.NewProviderConfig(
+	providerConfig := config.GetProviderInstance(
 		config.WithProviderService("MockService", config.NewServiceConfig()))
 	providerConfig.Services["MockService"].InitExported()
 	config.SetRootConfig(config.RootConfig{
diff --git a/metrics/prometheus/reporter.go b/metrics/prometheus/reporter.go
index 02365a1..96ec309 100644
--- a/metrics/prometheus/reporter.go
+++ b/metrics/prometheus/reporter.go
@@ -19,7 +19,6 @@ package prometheus
 
 import (
 	"context"
-	"net/http"
 	"strconv"
 	"strings"
 	"sync"
@@ -27,8 +26,6 @@ import (
 )
 
 import (
-	ocprom "contrib.go.opencensus.io/exporter/prometheus"
-
 	"github.com/prometheus/client_golang/prometheus"
 	prom "github.com/prometheus/client_golang/prometheus"
 )
@@ -71,7 +68,7 @@ var (
 
 // should initialize after loading configuration
 func init() {
-	newPrometheusReporter()
+	//newPrometheusReporter()
 	extension.SetMetricReporter(reporterName, newPrometheusReporter)
 }
 
@@ -221,20 +218,20 @@ func newPrometheusReporter() metrics.Reporter {
 
 			prom.DefaultRegisterer.MustRegister(reporterInstance.consumerSummaryVec, reporterInstance.providerSummaryVec,
 				reporterInstance.consumerHistogramVec, reporterInstance.providerHistogramVec)
-			metricsExporter, err := ocprom.NewExporter(ocprom.Options{
-				Registry: prom.DefaultRegisterer.(*prom.Registry),
-			})
-			if err != nil {
-				logger.Errorf("new prometheus reporter with error = %s", err)
-				return
-			}
-			go func() {
-				mux := http.NewServeMux()
-				mux.Handle("/metrics", metricsExporter)
-				if err := http.ListenAndServe(":9090", mux); err != nil {
-					logger.Errorf("new prometheus reporter with error = %s", err)
-				}
-			}()
+			//metricsExporter, err := ocprom.NewExporter(ocprom.Options{
+			//	Registry: prom.DefaultRegisterer.(*prom.Registry),
+			//})
+			//if err != nil {
+			//	logger.Errorf("new prometheus reporter with error = %s", err)
+			//	return
+			//}
+			//go func() {
+			//	mux := http.NewServeMux()
+			//	mux.Handle("/metrics", metricsExporter)
+			//	if err := http.ListenAndServe(":9090", mux); err != nil {
+			//		logger.Errorf("new prometheus reporter with error = %s", err)
+			//	}
+			//}()
 		})
 	}
 	return reporterInstance
diff --git a/protocol/dubbo3/internal/server.go b/protocol/dubbo3/internal/server.go
index e1cf5da..5ba1765 100644
--- a/protocol/dubbo3/internal/server.go
+++ b/protocol/dubbo3/internal/server.go
@@ -48,7 +48,7 @@ func InitDubboServer() {
 		config.WithServiceProtocolKeys("tripleKey"),
 	)
 
-	providerConfig := config.NewProviderConfig(
+	providerConfig := config.GetProviderInstance(
 		config.WithProviderService(common.GetReference(&Server{}), serviceConfig),
 	)
 
@@ -57,12 +57,12 @@ func InitDubboServer() {
 		config.WithProtocolPort("20003"),
 	)
 
-	rootConfig := config.NewRootConfig(
+	rootConfig := config.GetInstance(
 		config.WithRootProviderConfig(providerConfig),
 		config.WithRootProtocolConfig("tripleKey", protocolConfig),
 	)
-	config.SetProviderConfig(*providerConfig) // set to providerConfig ptr
 
 	config.SetProviderService(&Server{})
 	rootConfig.Init()
+	rootConfig.Start()
 }