You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by la...@apache.org on 2021/10/02 02:01:13 UTC

[dubbo-go] branch config-api updated: feat(config): add root config api builder (#1491)

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

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


The following commit(s) were added to refs/heads/config-api by this push:
     new 9220fa4  feat(config): add root config api builder (#1491)
9220fa4 is described below

commit 9220fa451bd6361797b1ab953a4736ddf1ea0974
Author: Mulavar <97...@qq.com>
AuthorDate: Sat Oct 2 09:58:50 2021 +0800

    feat(config): add root config api builder (#1491)
    
    * feat(config): add root&application config api
    
    * feat(config): add protocol config api
    
    * feat(config): remove structure embedding
    
    * feat(config): add registry config api builder
    
    * feat(config): add service discovery config api builder
    
    * feat(config): add prefix Set
    
    * feat(config): add consumer&provider&metric&metadata&remote_route&logger config api
    
    Co-authored-by: dongjianhui03 <do...@meituan.com>
---
 config/application_config.go       |  50 +++++++++++++++++
 config/config_loader.go            |  12 ++--
 config/consumer_config.go          |  55 ++++++++++++++++++
 config/dubbo_bootstrap.go          |  63 +++++++++++++++------
 config/graceful_shutdown_config.go |  37 ++++++++++++
 config/logger_config.go            |  26 +++++++++
 config/metadata_report_config.go   |  59 ++++++++++++++++++-
 config/metric_config.go            |  57 +++++++++++++++++--
 config/protocol_config.go          |  57 ++++++++++++-------
 config/provider_config.go          |  95 +++++++++++++++++++++++++++++--
 config/registry_config.go          | 109 +++++++++++++++++++++++++++++++-----
 config/remote_config.go            |  80 ++++++++++++++++++++++----
 config/root_config.go              | 112 ++++++++++++++++++++++++++++++++-----
 config/router_config.go            |  93 +++++++++++++++++++++++++++++-
 config/service_config.go           |   2 +-
 config/service_discovery_config.go |  34 ++++++++++-
 go.sum                             |   2 -
 remoting/nacos/builder_test.go     |   2 +-
 18 files changed, 846 insertions(+), 99 deletions(-)

diff --git a/config/application_config.go b/config/application_config.go
index 1118109..cb52c6b 100644
--- a/config/application_config.go
+++ b/config/application_config.go
@@ -113,3 +113,53 @@ func WithMetadataType(metadataType string) ApplicationConfigOpt {
 		ac.MetadataType = metadataType
 	}
 }
+
+func NewApplicationConfigBuilder() *ApplicationConfigBuilder {
+	return &ApplicationConfigBuilder{application: &ApplicationConfig{}}
+}
+
+type ApplicationConfigBuilder struct {
+	application *ApplicationConfig
+}
+
+func (acb *ApplicationConfigBuilder) SetOrganization(organization string) *ApplicationConfigBuilder {
+	acb.application.Organization = organization
+	return acb
+}
+
+func (acb *ApplicationConfigBuilder) SetName(name string) *ApplicationConfigBuilder {
+	acb.application.Name = name
+	return acb
+}
+
+func (acb *ApplicationConfigBuilder) SetModule(module string) *ApplicationConfigBuilder {
+	acb.application.Module = module
+	return acb
+}
+
+func (acb *ApplicationConfigBuilder) SetVersion(version string) *ApplicationConfigBuilder {
+	acb.application.Version = version
+	return acb
+}
+
+func (acb *ApplicationConfigBuilder) SetOwner(owner string) *ApplicationConfigBuilder {
+	acb.application.Owner = owner
+	return acb
+}
+
+func (acb *ApplicationConfigBuilder) SetEnvironment(environment string) *ApplicationConfigBuilder {
+	acb.application.Environment = environment
+	return acb
+}
+
+func (acb *ApplicationConfigBuilder) SetMetadataType(metadataType string) *ApplicationConfigBuilder {
+	acb.application.MetadataType = metadataType
+	return acb
+}
+
+func (acb *ApplicationConfigBuilder) Build() *ApplicationConfig {
+	if err := acb.application.Init(); err != nil {
+		panic(err)
+	}
+	return acb.application
+}
diff --git a/config/config_loader.go b/config/config_loader.go
index 6a3f411..7d611be 100644
--- a/config/config_loader.go
+++ b/config/config_loader.go
@@ -188,19 +188,19 @@ func RPCService(service common.RPCService) {
 // So you don't need to worry about the race condition
 func GetMetricConfig() *MetricConfig {
 	// todo
-	//if GetBaseConfig().MetricConfig == nil {
+	//if GetBaseConfig().Metric == nil {
 	//	configAccessMutex.Lock()
 	//	defer configAccessMutex.Unlock()
-	//	if GetBaseConfig().MetricConfig == nil {
-	//		GetBaseConfig().MetricConfig = &metric.MetricConfig{}
+	//	if GetBaseConfig().Metric == nil {
+	//		GetBaseConfig().Metric = &metric.Metric{}
 	//	}
 	//}
-	//return GetBaseConfig().MetricConfig
-	return rootConfig.MetricConfig
+	//return GetBaseConfig().Metric
+	return rootConfig.Metric
 }
 
 func GetMetadataReportConfg() *MetadataReportConfig {
-	return rootConfig.MetadataReportConfig
+	return rootConfig.MetadataReport
 }
 
 func IsProvider() bool {
diff --git a/config/consumer_config.go b/config/consumer_config.go
index 9f76e4c..d80b139 100644
--- a/config/consumer_config.go
+++ b/config/consumer_config.go
@@ -272,3 +272,58 @@ func WithConsumerConfigCheck(check bool) ConsumerConfigOpt {
 		return config
 	}
 }
+
+type ConsumerConfigBuilder struct {
+	consumerConfig *ConsumerConfig
+}
+
+func NewConsumerConfigBuilder() *ConsumerConfigBuilder {
+	return &ConsumerConfigBuilder{consumerConfig: &ConsumerConfig{}}
+}
+
+func (ccb *ConsumerConfigBuilder) SetFilter(filter string) *ConsumerConfigBuilder {
+	ccb.consumerConfig.Filter = filter
+	return ccb
+}
+
+func (ccb *ConsumerConfigBuilder) SetRegistry(registry []string) *ConsumerConfigBuilder {
+	ccb.consumerConfig.Registry = registry
+	return ccb
+}
+
+func (ccb *ConsumerConfigBuilder) SetRequestTimeout(requestTimeout string) *ConsumerConfigBuilder {
+	ccb.consumerConfig.RequestTimeout = requestTimeout
+	return ccb
+}
+
+func (ccb *ConsumerConfigBuilder) SetProxyFactory(proxyFactory string) *ConsumerConfigBuilder {
+	ccb.consumerConfig.ProxyFactory = proxyFactory
+	return ccb
+}
+
+func (ccb *ConsumerConfigBuilder) SetCheck(check bool) *ConsumerConfigBuilder {
+	ccb.consumerConfig.Check = check
+	return ccb
+}
+
+func (ccb *ConsumerConfigBuilder) SetReferences(references map[string]*ReferenceConfig) *ConsumerConfigBuilder {
+	ccb.consumerConfig.References = references
+	return ccb
+}
+
+func (ccb *ConsumerConfigBuilder) SetFilterConf(filterConf interface{}) *ConsumerConfigBuilder {
+	ccb.consumerConfig.FilterConf = filterConf
+	return ccb
+}
+
+func (ccb *ConsumerConfigBuilder) SetRootConfig(rootConfig *RootConfig) *ConsumerConfigBuilder {
+	ccb.consumerConfig.rootConfig = rootConfig
+	return ccb
+}
+
+func (ccb *ConsumerConfigBuilder) Build() *ConsumerConfig {
+	if err := ccb.consumerConfig.Init(ccb.consumerConfig.rootConfig); err != nil {
+		panic(err)
+	}
+	return ccb.consumerConfig
+}
diff --git a/config/dubbo_bootstrap.go b/config/dubbo_bootstrap.go
index 6793e26..f5ccf92 100644
--- a/config/dubbo_bootstrap.go
+++ b/config/dubbo_bootstrap.go
@@ -27,6 +27,7 @@ import (
 
 import (
 	"dubbo.apache.org/dubbo-go/v3/common"
+	"dubbo.apache.org/dubbo-go/v3/common/constant"
 	"dubbo.apache.org/dubbo-go/v3/common/logger"
 )
 
@@ -37,16 +38,16 @@ var (
 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(),
+		ConfigCenter:       GetConfigCenterInstance(),
+		ServiceDiscoveries: make(map[string]*ServiceDiscoveryConfig),
+		MetadataReport:     &MetadataReportConfig{},
+		Application:        GetApplicationInstance(),
+		Registries:         make(map[string]*RegistryConfig),
+		Protocols:          GetProtocolsInstance(),
+		Provider:           GetProviderInstance(),
+		Consumer:           GetConsumerInstance(),
+		Metric:             &MetricConfig{},
+		Logger:             GetLoggerConfigInstance(),
 	}
 	for _, opt := range opts {
 		opt(rc)
@@ -71,19 +72,45 @@ func (rc *RootConfig) Init() error {
 	if err := rc.Application.Init(); err != nil {
 		return err
 	}
-	if err := initProtocolsConfig(rc); err != nil {
-		return err
+
+	// init protocol
+	protocols := rc.Protocols
+	if len(protocols) <= 0 {
+		protocol := &ProtocolConfig{}
+		protocols = make(map[string]*ProtocolConfig, 1)
+		protocols[constant.DUBBO] = protocol
+		rc.Protocols = protocols
 	}
-	if err := initRegistryConfig(rc); err != nil {
-		return err
+	for _, protocol := range protocols {
+		if err := protocol.Init(); err != nil {
+			return err
+		}
 	}
-	if err := initServiceDiscoveryConfig(rc); err != nil {
-		return err
+
+	// init registry
+	registries := rc.Registries
+	if registries != nil {
+		for _, reg := range registries {
+			if err := reg.Init(); err != nil {
+				return err
+			}
+		}
+	}
+
+	// init serviceDiscoveries
+	serviceDiscoveries := rc.ServiceDiscoveries
+	if serviceDiscoveries != nil {
+		for _, sd := range serviceDiscoveries {
+			if err := sd.Init(); err != nil {
+				return err
+			}
+		}
 	}
-	if err := rc.MetadataReportConfig.Init(rc); err != nil {
+
+	if err := rc.MetadataReport.Init(rc); err != nil {
 		return err
 	}
-	if err := initMetricConfig(rc); err != nil {
+	if err := rc.Metric.Init(); err != nil {
 		return err
 	}
 	if err := initRouterConfig(rc); err != nil {
diff --git a/config/graceful_shutdown_config.go b/config/graceful_shutdown_config.go
index 76720a3..fdf2376 100644
--- a/config/graceful_shutdown_config.go
+++ b/config/graceful_shutdown_config.go
@@ -83,3 +83,40 @@ func (config *ShutdownConfig) GetStepTimeout() time.Duration {
 	}
 	return result
 }
+
+type ShutdownConfigBuilder struct {
+	shutdownConfig *ShutdownConfig
+}
+
+func NewShutDownConfigBuilder() *ShutdownConfigBuilder {
+	return &ShutdownConfigBuilder{shutdownConfig: &ShutdownConfig{}}
+}
+
+func (scb *ShutdownConfigBuilder) SetTimeout(timeout string) *ShutdownConfigBuilder {
+	scb.shutdownConfig.Timeout = timeout
+	return scb
+}
+
+func (scb *ShutdownConfigBuilder) SetStepTimeout(stepTimeout string) *ShutdownConfigBuilder {
+	scb.shutdownConfig.StepTimeout = stepTimeout
+	return scb
+}
+
+func (scb *ShutdownConfigBuilder) SetRejectRequestHandler(rejectRequestHandler string) *ShutdownConfigBuilder {
+	scb.shutdownConfig.RejectRequestHandler = rejectRequestHandler
+	return scb
+}
+
+func (scb *ShutdownConfigBuilder) SetRequestsFinished(requestsFinished bool) *ShutdownConfigBuilder {
+	scb.shutdownConfig.RequestsFinished = requestsFinished
+	return scb
+}
+
+func (scb *ShutdownConfigBuilder) SetRejectRequest(rejectRequest bool) *ShutdownConfigBuilder {
+	scb.shutdownConfig.RejectRequest = rejectRequest
+	return scb
+}
+
+func (scb *ShutdownConfigBuilder) Build() *ShutdownConfig {
+	return scb.shutdownConfig
+}
diff --git a/config/logger_config.go b/config/logger_config.go
index d829256..0e7ec43 100644
--- a/config/logger_config.go
+++ b/config/logger_config.go
@@ -153,3 +153,29 @@ func (lc *LoggerConfig) getUrlMap() url.Values {
 	}
 	return urlMap
 }
+
+type LoggerConfigBuilder struct {
+	loggerConfig *LoggerConfig
+}
+
+// nolint
+func NewLoggerConfigBuilder() *LoggerConfigBuilder {
+	return &LoggerConfigBuilder{loggerConfig: &LoggerConfig{}}
+}
+
+// nolint
+func (lcb *LoggerConfigBuilder) SetLumberjackConfig(lumberjackConfig *lumberjack.Logger) *LoggerConfigBuilder {
+	lcb.loggerConfig.LumberjackConfig = lumberjackConfig
+	return lcb
+}
+
+// nolint
+func (lcb *LoggerConfigBuilder) SetZapConfig(zapConfig ZapConfig) *LoggerConfigBuilder {
+	lcb.loggerConfig.ZapConfig = zapConfig
+	return lcb
+}
+
+// nolint
+func (lcb *LoggerConfigBuilder) Build() *LoggerConfig {
+	return lcb.loggerConfig
+}
diff --git a/config/metadata_report_config.go b/config/metadata_report_config.go
index 888edd1..22f1fcb 100644
--- a/config/metadata_report_config.go
+++ b/config/metadata_report_config.go
@@ -65,7 +65,7 @@ func (mc *MetadataReportConfig) ToUrl() (*common.URL, error) {
 		common.WithParamsValue(constant.METADATATYPE_KEY, mc.MetadataType),
 	)
 	if err != nil || len(res.Protocol) == 0 {
-		return nil, perrors.New("Invalid MetadataReportConfig.")
+		return nil, perrors.New("Invalid MetadataReport Config.")
 	}
 	res.SetParam("metadata", res.Protocol)
 	return res, nil
@@ -122,3 +122,60 @@ func selectMetadataServiceExportedURL() *common.URL {
 	}
 	return selectedUrl
 }
+
+type MetadataReportConfigBuilder struct {
+	metadataReportConfig *MetadataReportConfig
+}
+
+// nolint
+func NewMetadataReportConfigBuilder() *MetadataReportConfigBuilder {
+	return &MetadataReportConfigBuilder{metadataReportConfig: &MetadataReportConfig{}}
+}
+
+// nolint
+func (mrcb *MetadataReportConfigBuilder) SetProtocol(protocol string) *MetadataReportConfigBuilder {
+	mrcb.metadataReportConfig.Protocol = protocol
+	return mrcb
+}
+
+// nolint
+func (mrcb *MetadataReportConfigBuilder) SetAddress(address string) *MetadataReportConfigBuilder {
+	mrcb.metadataReportConfig.Address = address
+	return mrcb
+}
+
+// nolint
+func (mrcb *MetadataReportConfigBuilder) SetUsername(username string) *MetadataReportConfigBuilder {
+	mrcb.metadataReportConfig.Username = username
+	return mrcb
+}
+
+// nolint
+func (mrcb *MetadataReportConfigBuilder) SetPassword(password string) *MetadataReportConfigBuilder {
+	mrcb.metadataReportConfig.Password = password
+	return mrcb
+}
+
+// nolint
+func (mrcb *MetadataReportConfigBuilder) SetTimeout(timeout string) *MetadataReportConfigBuilder {
+	mrcb.metadataReportConfig.Timeout = timeout
+	return mrcb
+}
+
+// nolint
+func (mrcb *MetadataReportConfigBuilder) SetGroup(group string) *MetadataReportConfigBuilder {
+	mrcb.metadataReportConfig.Group = group
+	return mrcb
+}
+
+// nolint
+func (mrcb *MetadataReportConfigBuilder) SetMetadataType(metadataType string) *MetadataReportConfigBuilder {
+	mrcb.metadataReportConfig.MetadataType = metadataType
+	return mrcb
+}
+
+// nolint
+func (mrcb *MetadataReportConfigBuilder) Build() *MetadataReportConfig {
+	// TODO Init
+	return mrcb.metadataReportConfig
+}
diff --git a/config/metric_config.go b/config/metric_config.go
index e6d0a5a..64f6b2d 100644
--- a/config/metric_config.go
+++ b/config/metric_config.go
@@ -19,17 +19,19 @@ package config
 
 var defaultHistogramBucket = []float64{10, 50, 100, 200, 500, 1000, 10000}
 
-// This is the config struct for all metrics implementation
+// MetricConfig This is the config struct for all metrics implementation
 type MetricConfig struct {
-	Reporters       []string  `yaml:"reporters" json:"reporters,omitempty"`
+	Reporters []string `yaml:"reporters" json:"reporters,omitempty"`
+	// TODO s?
 	HistogramBucket []float64 `yaml:"histogram_bucket" json:"histogram_bucket,omitempty"`
 }
 
-func initMetricConfig(rc *RootConfig) error {
+// nolint
+func (mc *MetricConfig) Init() error {
 	return nil
 }
 
-// find the histogram bucket
+// GetHistogramBucket find the histogram bucket
 // if it's empty, the default value will be return
 func (mc *MetricConfig) GetHistogramBucket() []float64 {
 	if len(mc.HistogramBucket) == 0 {
@@ -37,3 +39,50 @@ func (mc *MetricConfig) GetHistogramBucket() []float64 {
 	}
 	return mc.HistogramBucket
 }
+
+type MetricConfigBuilder struct {
+	metricConfig *MetricConfig
+}
+
+// nolint
+func NewMetricConfigBuilder() *MetricConfigBuilder {
+	return &MetricConfigBuilder{metricConfig: &MetricConfig{}}
+}
+
+// nolint
+func (mcb *MetricConfigBuilder) SetReporters(reporters []string) *MetricConfigBuilder {
+	mcb.metricConfig.Reporters = reporters
+	return mcb
+}
+
+// nolint
+func (mcb *MetricConfigBuilder) AddReporter(reporter string) *MetricConfigBuilder {
+	if mcb.metricConfig.Reporters == nil {
+		mcb.metricConfig.Reporters = make([]string, 0)
+	}
+	mcb.metricConfig.Reporters = append(mcb.metricConfig.Reporters, reporter)
+	return mcb
+}
+
+// nolint
+func (mcb *MetricConfigBuilder) SetHistogramBucket(histogramBucket []float64) *MetricConfigBuilder {
+	mcb.metricConfig.HistogramBucket = histogramBucket
+	return mcb
+}
+
+// nolint
+func (mcb *MetricConfigBuilder) AddBucket(bucket float64) *MetricConfigBuilder {
+	if mcb.metricConfig.HistogramBucket == nil {
+		mcb.metricConfig.HistogramBucket = make([]float64, 0)
+	}
+	mcb.metricConfig.HistogramBucket = append(mcb.metricConfig.HistogramBucket, bucket)
+	return mcb
+}
+
+// nolint
+func (mcb *MetricConfigBuilder) Build() *MetricConfig {
+	if err := mcb.metricConfig.Init(); err != nil {
+		panic(err)
+	}
+	return mcb.metricConfig
+}
diff --git a/config/protocol_config.go b/config/protocol_config.go
index 0a1a1a9..39dcd00 100644
--- a/config/protocol_config.go
+++ b/config/protocol_config.go
@@ -42,25 +42,7 @@ func GetProtocolsInstance() map[string]*ProtocolConfig {
 	return make(map[string]*ProtocolConfig, 1)
 }
 
-func initProtocolsConfig(rc *RootConfig) error {
-	protocols := rc.Protocols
-	if len(protocols) <= 0 {
-		protocol := new(ProtocolConfig)
-		protocols = make(map[string]*ProtocolConfig, 1)
-		protocols[constant.DUBBO] = protocol
-		rc.Protocols = protocols
-		return protocol.check()
-	}
-	for _, protocol := range protocols {
-		if err := protocol.check(); err != nil {
-			return err
-		}
-	}
-	rc.Protocols = protocols
-	return nil
-}
-
-func (p *ProtocolConfig) check() error {
+func (p *ProtocolConfig) Init() error {
 	if err := defaults.Set(p); err != nil {
 		return err
 	}
@@ -87,7 +69,7 @@ func NewProtocolConfig(opts ...ProtocolConfigOpt) *ProtocolConfig {
 type ProtocolConfigOpt func(config *ProtocolConfig) *ProtocolConfig
 
 // WithProtocolIP set ProtocolConfig with given binding @ip
-// Deprecated: the param @ip would be used as service lisener binding and would be registered to registry center
+// Deprecated: the param @ip would be used as service listener binding and would be registered to registry center
 func WithProtocolIP(ip string) ProtocolConfigOpt {
 	return func(config *ProtocolConfig) *ProtocolConfig {
 		config.Ip = ip
@@ -108,3 +90,38 @@ func WithProtocolPort(port string) ProtocolConfigOpt {
 		return config
 	}
 }
+
+func NewProtocolConfigBuilder() *ProtocolConfigBuilder {
+	return &ProtocolConfigBuilder{protocolConfig: &ProtocolConfig{}}
+}
+
+type ProtocolConfigBuilder struct {
+	protocolConfig *ProtocolConfig
+}
+
+func (pcb *ProtocolConfigBuilder) SetName(name string) *ProtocolConfigBuilder {
+	pcb.protocolConfig.Name = name
+	return pcb
+}
+
+func (pcb *ProtocolConfigBuilder) SetIp(ip string) *ProtocolConfigBuilder {
+	pcb.protocolConfig.Ip = ip
+	return pcb
+}
+
+func (pcb *ProtocolConfigBuilder) SetPort(port string) *ProtocolConfigBuilder {
+	pcb.protocolConfig.Port = port
+	return pcb
+}
+
+func (pcb *ProtocolConfigBuilder) SetParams(params interface{}) *ProtocolConfigBuilder {
+	pcb.protocolConfig.Params = params
+	return pcb
+}
+
+func (pcb *ProtocolConfigBuilder) Build() *ProtocolConfig {
+	if err := pcb.protocolConfig.Init(); err != nil {
+		panic(err)
+	}
+	return pcb.protocolConfig
+}
diff --git a/config/provider_config.go b/config/provider_config.go
index a77f3f9..09c2864 100644
--- a/config/provider_config.go
+++ b/config/provider_config.go
@@ -35,16 +35,17 @@ type ProviderConfig struct {
 	Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"`
 	// Deprecated Register whether registration is required
 	Register bool `yaml:"register" json:"register" property:"register"`
-	// Registry registry ids
+	// Registry registry ids TODO Registries?
 	Registry []string `yaml:"registry" json:"registry" property:"registry"`
 	// Services services
 	Services map[string]*ServiceConfig `yaml:"services" json:"services,omitempty" property:"services"`
 
 	ProxyFactory string `default:"default" yaml:"proxy" json:"proxy,omitempty" property:"proxy"`
 
-	FilterConf interface{} `yaml:"filter_conf" json:"filter_conf,omitempty" property:"filter_conf"`
-	// ShutdownConfig *ShutdownConfig            `yaml:"shutdown_conf" json:"shutdown_conf,omitempty" property:"shutdown_conf"`
+	FilterConf interface{}       `yaml:"filter_conf" json:"filter_conf,omitempty" property:"filter_conf"`
 	ConfigType map[string]string `yaml:"config_type" json:"config_type,omitempty" property:"config_type"`
+
+	rootConfig *RootConfig
 }
 
 func (ProviderConfig) Prefix() string {
@@ -98,8 +99,7 @@ func SetProviderConfig(p ProviderConfig) {
 	rootConfig.Provider = &p
 }
 
-///////////////////////////////////// provider config api
-// ProviderConfigOpt is the
+// nolint
 type ProviderConfigOpt func(config *ProviderConfig) *ProviderConfig
 
 // NewEmptyProviderConfig returns ProviderConfig with default ApplicationConfig
@@ -132,7 +132,7 @@ func GetProviderInstance(opts ...ProviderConfigOpt) *ProviderConfig {
 	return newConfig
 }
 
-// WithProviderServices returns ProviderConfig with given serviceNameKey @serviceName and @serviceConfig
+// WithProviderService returns ProviderConfig with given serviceNameKey @serviceName and @serviceConfig
 func WithProviderService(serviceName string, serviceConfig *ServiceConfig) ProviderConfigOpt {
 	return func(config *ProviderConfig) *ProviderConfig {
 		config.Services[serviceName] = serviceConfig
@@ -147,3 +147,86 @@ func WithProviderRegistryKeys(registryKey ...string) ProviderConfigOpt {
 		return config
 	}
 }
+
+type ProviderConfigBuilder struct {
+	providerConfig *ProviderConfig
+}
+
+// nolint
+func NewProviderConfigBuilder() *ProviderConfigBuilder {
+	return &ProviderConfigBuilder{providerConfig: &ProviderConfig{}}
+}
+
+// nolint
+func (pcb *ProviderConfigBuilder) SetFilter(filter string) *ProviderConfigBuilder {
+	pcb.providerConfig.Filter = filter
+	return pcb
+}
+
+// nolint
+func (pcb *ProviderConfigBuilder) SetRegister(register bool) *ProviderConfigBuilder {
+	pcb.providerConfig.Register = register
+	return pcb
+}
+
+// nolint
+func (pcb *ProviderConfigBuilder) SetRegistry(registry []string) *ProviderConfigBuilder {
+	pcb.providerConfig.Registry = registry
+	return pcb
+}
+
+// nolint
+func (pcb *ProviderConfigBuilder) SetServices(services map[string]*ServiceConfig) *ProviderConfigBuilder {
+	pcb.providerConfig.Services = services
+	return pcb
+}
+
+// nolint
+func (pcb *ProviderConfigBuilder) AddService(serviceName string, serviceConfig *ServiceConfig) *ProviderConfigBuilder {
+	if pcb.providerConfig.Services == nil {
+		pcb.providerConfig.Services = make(map[string]*ServiceConfig)
+	}
+	pcb.providerConfig.Services[serviceName] = serviceConfig
+	return pcb
+}
+
+// nolint
+func (pcb *ProviderConfigBuilder) SetProxyFactory(proxyFactory string) *ProviderConfigBuilder {
+	pcb.providerConfig.ProxyFactory = proxyFactory
+	return pcb
+}
+
+// nolint
+func (pcb *ProviderConfigBuilder) SetFilterConf(filterConf interface{}) *ProviderConfigBuilder {
+	pcb.providerConfig.FilterConf = filterConf
+	return pcb
+}
+
+// nolint
+func (pcb *ProviderConfigBuilder) SetConfigType(configType map[string]string) *ProviderConfigBuilder {
+	pcb.providerConfig.ConfigType = configType
+	return pcb
+}
+
+// nolint
+func (pcb *ProviderConfigBuilder) AddConfigType(key, value string) *ProviderConfigBuilder {
+	if pcb.providerConfig.ConfigType == nil {
+		pcb.providerConfig.ConfigType = make(map[string]string)
+	}
+	pcb.providerConfig.ConfigType[key] = value
+	return pcb
+}
+
+// nolint
+func (pcb *ProviderConfigBuilder) SetRootConfig(rootConfig *RootConfig) *ProviderConfigBuilder {
+	pcb.providerConfig.rootConfig = rootConfig
+	return pcb
+}
+
+// nolint
+func (pcb *ProviderConfigBuilder) Build() *ProviderConfig {
+	if err := pcb.providerConfig.Init(pcb.providerConfig.rootConfig); err != nil {
+		panic(err)
+	}
+	return pcb.providerConfig
+}
diff --git a/config/registry_config.go b/config/registry_config.go
index c811eee..51e3539 100644
--- a/config/registry_config.go
+++ b/config/registry_config.go
@@ -63,7 +63,7 @@ func (RegistryConfig) Prefix() string {
 	return constant.RegistryConfigPrefix
 }
 
-func (c *RegistryConfig) check() error {
+func (c *RegistryConfig) Init() error {
 	if err := defaults.Set(c); err != nil {
 		return err
 	}
@@ -71,18 +71,6 @@ func (c *RegistryConfig) check() error {
 	return verify(c)
 }
 
-// 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 {
 	urlMap := url.Values{}
 	urlMap.Set(constant.GROUP_KEY, c.Group)
@@ -284,3 +272,98 @@ func WithRegistryParams(params map[string]string) RegistryConfigOpt {
 		return config
 	}
 }
+
+func NewRegistryConfigBuilder() *RegistryConfigBuilder {
+	return &RegistryConfigBuilder{
+		registryConfig: &RegistryConfig{},
+	}
+}
+
+type RegistryConfigBuilder struct {
+	registryConfig *RegistryConfig
+}
+
+func (rcb *RegistryConfigBuilder) SetProtocol(protocol string) *RegistryConfigBuilder {
+	rcb.registryConfig.Protocol = protocol
+	return rcb
+}
+
+func (rcb *RegistryConfigBuilder) SetTimeout(timeout string) *RegistryConfigBuilder {
+	rcb.registryConfig.Timeout = timeout
+	return rcb
+}
+
+func (rcb *RegistryConfigBuilder) SetGroup(group string) *RegistryConfigBuilder {
+	rcb.registryConfig.Group = group
+	return rcb
+}
+
+func (rcb *RegistryConfigBuilder) SetNamespace(namespace string) *RegistryConfigBuilder {
+	rcb.registryConfig.Namespace = namespace
+	return rcb
+}
+
+func (rcb *RegistryConfigBuilder) SetTTL(ttl string) *RegistryConfigBuilder {
+	rcb.registryConfig.TTL = ttl
+	return rcb
+}
+
+func (rcb *RegistryConfigBuilder) SetAddress(address string) *RegistryConfigBuilder {
+	rcb.registryConfig.Address = address
+	return rcb
+}
+
+func (rcb *RegistryConfigBuilder) SetUsername(username string) *RegistryConfigBuilder {
+	rcb.registryConfig.Username = username
+	return rcb
+}
+
+func (rcb *RegistryConfigBuilder) SetPassword(password string) *RegistryConfigBuilder {
+	rcb.registryConfig.Password = password
+	return rcb
+}
+
+func (rcb *RegistryConfigBuilder) SetSimplified(simplified bool) *RegistryConfigBuilder {
+	rcb.registryConfig.Simplified = simplified
+	return rcb
+}
+
+func (rcb *RegistryConfigBuilder) SetPreferred(preferred bool) *RegistryConfigBuilder {
+	rcb.registryConfig.Preferred = preferred
+	return rcb
+}
+
+func (rcb *RegistryConfigBuilder) SetZone(zone string) *RegistryConfigBuilder {
+	rcb.registryConfig.Zone = zone
+	return rcb
+}
+
+func (rcb *RegistryConfigBuilder) SetWeight(weight int64) *RegistryConfigBuilder {
+	rcb.registryConfig.Weight = weight
+	return rcb
+}
+
+func (rcb *RegistryConfigBuilder) SetParams(params map[string]string) *RegistryConfigBuilder {
+	rcb.registryConfig.Params = params
+	return rcb
+}
+
+func (rcb *RegistryConfigBuilder) addParam(key, value string) *RegistryConfigBuilder {
+	if rcb.registryConfig.Params == nil {
+		rcb.registryConfig.Params = make(map[string]string)
+	}
+	rcb.registryConfig.Params[key] = value
+	return rcb
+}
+
+func (rcb *RegistryConfigBuilder) SetRegistryType(registryType string) *RegistryConfigBuilder {
+	rcb.registryConfig.RegistryType = registryType
+	return rcb
+}
+
+func (rcb *RegistryConfigBuilder) Build() *RegistryConfig {
+	if err := rcb.registryConfig.Init(); err != nil {
+		panic(err)
+	}
+	return rcb.registryConfig
+}
diff --git a/config/remote_config.go b/config/remote_config.go
index 820f744..444db6e 100644
--- a/config/remote_config.go
+++ b/config/remote_config.go
@@ -31,17 +31,17 @@ import (
 	"dubbo.apache.org/dubbo-go/v3/common/constant"
 )
 
-// RemoteConfig: usually we need some middleware, including nacos, zookeeper
+// RemoteConfig usually we need some middleware, including nacos, zookeeper
 // this represents an instance of this middleware
 // so that other module, like config center, registry could reuse the config
 // but now, only metadata report, metadata service, service discovery use this structure
 type RemoteConfig struct {
-	Protocol   string            `yaml:"protocol"  json:"protocol,omitempty" property:"protocol"`
-	Address    string            `yaml:"address" json:"address,omitempty" property:"address"`
-	TimeoutStr string            `default:"5s" yaml:"timeout" json:"timeout,omitempty" property:"timeout"`
-	Username   string            `yaml:"username" json:"username,omitempty" property:"username"`
-	Password   string            `yaml:"password" json:"password,omitempty"  property:"password"`
-	Params     map[string]string `yaml:"params" json:"params,omitempty"`
+	Protocol string            `yaml:"protocol"  json:"protocol,omitempty" property:"protocol"`
+	Address  string            `yaml:"address" json:"address,omitempty" property:"address"`
+	Timeout  string            `default:"5s" yaml:"timeout" json:"timeout,omitempty" property:"timeout"`
+	Username string            `yaml:"username" json:"username,omitempty" property:"username"`
+	Password string            `yaml:"password" json:"password,omitempty"  property:"password"`
+	Params   map[string]string `yaml:"params" json:"params,omitempty"`
 }
 
 // Prefix dubbo.remote.
@@ -49,10 +49,15 @@ func (rc *RemoteConfig) Prefix() string {
 	return constant.RemotePrefix
 }
 
-// Timeout return timeout duration.
+// nolint
+func (rc *RemoteConfig) Init() error {
+	return nil
+}
+
+// GetTimeout return timeout duration.
 // if the configure is invalid, or missing, the default value 5s will be returned
-func (rc *RemoteConfig) Timeout() time.Duration {
-	if res, err := time.ParseDuration(rc.TimeoutStr); err == nil {
+func (rc *RemoteConfig) GetTimeout() time.Duration {
+	if res, err := time.ParseDuration(rc.Timeout); err == nil {
 		return res
 	}
 	return 5 * time.Second
@@ -87,10 +92,63 @@ func (rc *RemoteConfig) getUrlMap() url.Values {
 	urlMap := url.Values{}
 	urlMap.Set(constant.CONFIG_USERNAME_KEY, rc.Username)
 	urlMap.Set(constant.CONFIG_PASSWORD_KEY, rc.Password)
-	urlMap.Set(constant.CONFIG_TIMEOUT_KEY, rc.TimeoutStr)
+	urlMap.Set(constant.CONFIG_TIMEOUT_KEY, rc.Timeout)
 
 	for key, val := range rc.Params {
 		urlMap.Set(key, val)
 	}
 	return urlMap
 }
+
+func NewRemoteConfigBuilder() *RemoteConfigBuilder {
+	return &RemoteConfigBuilder{remoteConfig: &RemoteConfig{}}
+}
+
+type RemoteConfigBuilder struct {
+	remoteConfig *RemoteConfig
+}
+
+func (rcb *RemoteConfigBuilder) SetProtocol(protocol string) *RemoteConfigBuilder {
+	rcb.remoteConfig.Protocol = protocol
+	return rcb
+}
+
+func (rcb *RemoteConfigBuilder) SetAddress(address string) *RemoteConfigBuilder {
+	rcb.remoteConfig.Address = address
+	return rcb
+}
+
+func (rcb *RemoteConfigBuilder) SetTimeout(timeout string) *RemoteConfigBuilder {
+	rcb.remoteConfig.Timeout = timeout
+	return rcb
+}
+
+func (rcb *RemoteConfigBuilder) SetUsername(username string) *RemoteConfigBuilder {
+	rcb.remoteConfig.Username = username
+	return rcb
+}
+
+func (rcb *RemoteConfigBuilder) SetPassword(password string) *RemoteConfigBuilder {
+	rcb.remoteConfig.Password = password
+	return rcb
+}
+
+func (rcb *RemoteConfigBuilder) SetParams(params map[string]string) *RemoteConfigBuilder {
+	rcb.remoteConfig.Params = params
+	return rcb
+}
+
+func (rcb *RemoteConfigBuilder) AddParam(key, value string) *RemoteConfigBuilder {
+	if rcb.remoteConfig.Params == nil {
+		rcb.remoteConfig.Params = make(map[string]string)
+	}
+	rcb.remoteConfig.Params[key] = value
+	return rcb
+}
+
+func (rcb *RemoteConfigBuilder) Build() *RemoteConfig {
+	if err := rcb.remoteConfig.Init(); err != nil {
+		panic(err)
+	}
+	return rcb.remoteConfig
+}
diff --git a/config/root_config.go b/config/root_config.go
index 36d24b5..e5a39bb 100644
--- a/config/root_config.go
+++ b/config/root_config.go
@@ -38,12 +38,13 @@ type RootConfig struct {
 	// Remotes to be remove in 3.0 config-enhance
 	Remotes map[string]*RemoteConfig `yaml:"remote" json:"remote,omitempty" property:"remote"`
 
+	// TODO ConfigCenter and CenterConfig?
 	ConfigCenter *CenterConfig `yaml:"config-center" json:"config-center,omitempty"`
 
 	// ServiceDiscoveries to be remove in 3.0 config-enhance
 	ServiceDiscoveries map[string]*ServiceDiscoveryConfig `yaml:"service-discovery" json:"service-discovery,omitempty" property:"service-discovery"`
 
-	MetadataReportConfig *MetadataReportConfig `yaml:"metadata-report" json:"metadata-report,omitempty" property:"metadata-report"`
+	MetadataReport *MetadataReportConfig `yaml:"metadata-report" json:"metadata-report,omitempty" property:"metadata-report"`
 
 	// provider config
 	Provider *ProviderConfig `yaml:"provider" json:"provider" property:"provider"`
@@ -51,7 +52,7 @@ type RootConfig struct {
 	// consumer config
 	Consumer *ConsumerConfig `yaml:"consumer" json:"consumer" property:"consumer"`
 
-	MetricConfig *MetricConfig `yaml:"metrics" json:"metrics,omitempty" property:"metrics"`
+	Metric *MetricConfig `yaml:"metrics" json:"metrics,omitempty" property:"metrics"`
 
 	// Logger log
 	Logger *LoggerConfig `yaml:"logger" json:"logger,omitempty" property:"logger"`
@@ -198,15 +199,15 @@ func (rc *RootConfig) getRegistryIds() []string {
 // NewRootConfig get root config
 func NewRootConfig(opts ...RootConfigOpt) *RootConfig {
 	newRootConfig := &RootConfig{
-		ConfigCenter:         &CenterConfig{},
-		ServiceDiscoveries:   make(map[string]*ServiceDiscoveryConfig),
-		MetadataReportConfig: &MetadataReportConfig{},
-		Application:          &ApplicationConfig{},
-		Registries:           make(map[string]*RegistryConfig),
-		Protocols:            make(map[string]*ProtocolConfig),
-		Provider:             GetProviderInstance(),
-		Consumer:             GetConsumerInstance(),
-		MetricConfig:         &MetricConfig{},
+		ConfigCenter:       &CenterConfig{},
+		ServiceDiscoveries: make(map[string]*ServiceDiscoveryConfig),
+		MetadataReport:     &MetadataReportConfig{},
+		Application:        &ApplicationConfig{},
+		Registries:         make(map[string]*RegistryConfig),
+		Protocols:          make(map[string]*ProtocolConfig),
+		Provider:           GetProviderInstance(),
+		Consumer:           GetConsumerInstance(),
+		Metric:             &MetricConfig{},
 	}
 	for _, o := range opts {
 		o(newRootConfig)
@@ -219,7 +220,7 @@ type RootConfigOpt func(config *RootConfig)
 // WithMetricsConfig set root config with given @metricsConfig
 func WithMetricsConfig(metricsConfig *MetricConfig) RootConfigOpt {
 	return func(rc *RootConfig) {
-		rc.MetricConfig = metricsConfig
+		rc.Metric = metricsConfig
 	}
 }
 
@@ -261,7 +262,7 @@ func WithRootApplicationConfig(appConfig *ApplicationConfig) RootConfigOpt {
 // WithRootMetadataReportConfig set root config with given @metadataReportConfig
 func WithRootMetadataReportConfig(metadataReportConfig *MetadataReportConfig) RootConfigOpt {
 	return func(rc *RootConfig) {
-		rc.MetadataReportConfig = metadataReportConfig
+		rc.MetadataReport = metadataReportConfig
 	}
 }
 
@@ -278,3 +279,88 @@ func WithRootCenterConfig(centerConfig *CenterConfig) RootConfigOpt {
 		rc.ConfigCenter = centerConfig
 	}
 }
+
+func NewRootConfigBuilder() *RootConfigBuilder {
+	return &RootConfigBuilder{rootConfig: &RootConfig{}}
+}
+
+type RootConfigBuilder struct {
+	rootConfig *RootConfig
+}
+
+func (rb *RootConfigBuilder) SetApplication(application *ApplicationConfig) *RootConfigBuilder {
+	rb.rootConfig.Application = application
+	return rb
+}
+
+func (rb *RootConfigBuilder) SetProtocols(protocols map[string]*ProtocolConfig) *RootConfigBuilder {
+	rb.rootConfig.Protocols = protocols
+	return rb
+}
+
+func (rb *RootConfigBuilder) SetRegistries(registries map[string]*RegistryConfig) *RootConfigBuilder {
+	rb.rootConfig.Registries = registries
+	return rb
+}
+
+func (rb *RootConfigBuilder) SetRemotes(remotes map[string]*RemoteConfig) *RootConfigBuilder {
+	rb.rootConfig.Remotes = remotes
+	return rb
+}
+
+func (rb *RootConfigBuilder) SetServiceDiscoveries(serviceDiscoveries map[string]*ServiceDiscoveryConfig) *RootConfigBuilder {
+	rb.rootConfig.ServiceDiscoveries = serviceDiscoveries
+	return rb
+}
+
+func (rb *RootConfigBuilder) SetMetadataReport(metadataReport *MetadataReportConfig) *RootConfigBuilder {
+	rb.rootConfig.MetadataReport = metadataReport
+	return rb
+}
+
+func (rb *RootConfigBuilder) SetProvider(provider *ProviderConfig) *RootConfigBuilder {
+	rb.rootConfig.Provider = provider
+	return rb
+}
+
+func (rb *RootConfigBuilder) SetConsumer(consumer *ConsumerConfig) *RootConfigBuilder {
+	rb.rootConfig.Consumer = consumer
+	return rb
+}
+
+func (rb *RootConfigBuilder) SetMetric(metric *MetricConfig) *RootConfigBuilder {
+	rb.rootConfig.Metric = metric
+	return rb
+}
+
+func (rb *RootConfigBuilder) SetLogger(logger *LoggerConfig) *RootConfigBuilder {
+	rb.rootConfig.Logger = logger
+	return rb
+}
+
+func (rb *RootConfigBuilder) SetShutdown(shutdown *ShutdownConfig) *RootConfigBuilder {
+	rb.rootConfig.Shutdown = shutdown
+	return rb
+}
+
+func (rb *RootConfigBuilder) SetRouter(router []*RouterConfig) *RootConfigBuilder {
+	rb.rootConfig.Router = router
+	return rb
+}
+
+func (rb *RootConfigBuilder) SetEventDispatcherType(eventDispatcherType string) *RootConfigBuilder {
+	rb.rootConfig.EventDispatcherType = eventDispatcherType
+	return rb
+}
+
+func (rb *RootConfigBuilder) SetCacheFile(cacheFile string) *RootConfigBuilder {
+	rb.rootConfig.CacheFile = cacheFile
+	return rb
+}
+
+func (rb *RootConfigBuilder) Build() *RootConfig {
+	if err := rb.rootConfig.Init(); err != nil {
+		panic(err)
+	}
+	return rb.rootConfig
+}
diff --git a/config/router_config.go b/config/router_config.go
index 28cf7a0..854fa8e 100644
--- a/config/router_config.go
+++ b/config/router_config.go
@@ -51,7 +51,7 @@ func (RouterConfig) Prefix() string {
 	return constant.RouterConfigPrefix
 }
 
-func (c *RouterConfig) check() error {
+func (c *RouterConfig) Init() error {
 	if err := defaults.Set(c); err != nil {
 		return err
 	}
@@ -62,7 +62,7 @@ func initRouterConfig(rc *RootConfig) error {
 	routers := rc.Router
 	if len(routers) > 0 {
 		for _, r := range routers {
-			if err := r.check(); err != nil {
+			if err := r.Init(); err != nil {
 				return err
 			}
 		}
@@ -91,3 +91,92 @@ func initRouterConfig(rc *RootConfig) error {
 //	chain.SetVSAndDRConfigByte(vsBytes, drBytes)
 //	return nil
 //}
+
+type RouterConfigBuilder struct {
+	routerConfig *RouterConfig
+}
+
+// nolint
+func NewRouterConfigBuilder() *RouterConfigBuilder {
+	return &RouterConfigBuilder{routerConfig: &RouterConfig{}}
+}
+
+// nolint
+func (rcb *RouterConfigBuilder) SetScope(scope string) *RouterConfigBuilder {
+	rcb.routerConfig.Scope = scope
+	return rcb
+}
+
+// nolint
+func (rcb *RouterConfigBuilder) SetKey(key string) *RouterConfigBuilder {
+	rcb.routerConfig.Key = key
+	return rcb
+}
+
+// nolint
+func (rcb *RouterConfigBuilder) SetForce(force bool) *RouterConfigBuilder {
+	rcb.routerConfig.Force = force
+	return rcb
+}
+
+// nolint
+func (rcb *RouterConfigBuilder) SetRuntime(runtime bool) *RouterConfigBuilder {
+	rcb.routerConfig.Runtime = runtime
+	return rcb
+}
+
+// nolint
+func (rcb *RouterConfigBuilder) SetEnable(enable bool) *RouterConfigBuilder {
+	rcb.routerConfig.Enable = enable
+	return rcb
+}
+
+// nolint
+func (rcb *RouterConfigBuilder) SetValid(valid bool) *RouterConfigBuilder {
+	rcb.routerConfig.Valid = valid
+	return rcb
+}
+
+// nolint
+func (rcb *RouterConfigBuilder) SetPriority(priority int) *RouterConfigBuilder {
+	rcb.routerConfig.Priority = priority
+	return rcb
+}
+
+// nolint
+func (rcb *RouterConfigBuilder) SetConditions(conditions []string) *RouterConfigBuilder {
+	rcb.routerConfig.Conditions = conditions
+	return rcb
+}
+
+// nolint
+func (rcb *RouterConfigBuilder) AddCondition(condition string) *RouterConfigBuilder {
+	if rcb.routerConfig.Conditions == nil {
+		rcb.routerConfig.Conditions = make([]string, 0)
+	}
+	rcb.routerConfig.Conditions = append(rcb.routerConfig.Conditions, condition)
+	return rcb
+}
+
+// nolint
+func (rcb *RouterConfigBuilder) SetTags(tags []Tag) *RouterConfigBuilder {
+	rcb.routerConfig.Tags = tags
+	return rcb
+}
+
+// nolint
+func (rcb *RouterConfigBuilder) AddTag(tag Tag) *RouterConfigBuilder {
+	if rcb.routerConfig.Tags == nil {
+		rcb.routerConfig.Tags = make([]Tag, 0)
+	}
+	rcb.routerConfig.Tags = append(rcb.routerConfig.Tags, tag)
+	return rcb
+}
+
+// nolint
+func (rcb *RouterConfigBuilder) Build() *RouterConfig {
+	if err := rcb.routerConfig.Init(); err != nil {
+		panic(err)
+	}
+	return rcb.routerConfig
+}
diff --git a/config/service_config.go b/config/service_config.go
index 53dce7a..3bb1669 100644
--- a/config/service_config.go
+++ b/config/service_config.go
@@ -410,7 +410,7 @@ func (svc *ServiceConfig) GetExportedUrls() []*common.URL {
 }
 
 func (svc *ServiceConfig) publishServiceDefinition(url *common.URL) {
-	//svc.rootConfig.MetadataReportConfig.
+	//svc.rootConfig.MetadataReport.
 	if remoteMetadataService, err := extension.GetRemoteMetadataService(); err == nil && remoteMetadataService != nil {
 		remoteMetadataService.PublishServiceDefinition(url)
 	}
diff --git a/config/service_discovery_config.go b/config/service_discovery_config.go
index 2ba2bde..d93aea5 100644
--- a/config/service_discovery_config.go
+++ b/config/service_discovery_config.go
@@ -37,6 +37,38 @@ func (ServiceDiscoveryConfig) Prefix() string {
 	return constant.ServiceDiscPrefix
 }
 
-func initServiceDiscoveryConfig(rc *RootConfig) error {
+func (ServiceDiscoveryConfig) Init() error {
 	return nil
 }
+
+func NewServiceDiscoveryConfigBuilder() *ServiceDiscoveryConfigBuilder {
+	return &ServiceDiscoveryConfigBuilder{
+		serviceDiscoveryConfig: &ServiceDiscoveryConfig{},
+	}
+}
+
+type ServiceDiscoveryConfigBuilder struct {
+	serviceDiscoveryConfig *ServiceDiscoveryConfig
+}
+
+func (sdcb *ServiceDiscoveryConfigBuilder) SetProtocol(protocol string) *ServiceDiscoveryConfigBuilder {
+	sdcb.serviceDiscoveryConfig.Protocol = protocol
+	return sdcb
+}
+
+func (sdcb *ServiceDiscoveryConfigBuilder) SetGroup(group string) *ServiceDiscoveryConfigBuilder {
+	sdcb.serviceDiscoveryConfig.Group = group
+	return sdcb
+}
+
+func (sdcb *ServiceDiscoveryConfigBuilder) SetRemoteRef(remoteRef string) *ServiceDiscoveryConfigBuilder {
+	sdcb.serviceDiscoveryConfig.RemoteRef = remoteRef
+	return sdcb
+}
+
+func (sdcb *ServiceDiscoveryConfigBuilder) Build() *ServiceDiscoveryConfig {
+	if err := sdcb.serviceDiscoveryConfig.Init(); err != nil {
+		panic(err)
+	}
+	return sdcb.serviceDiscoveryConfig
+}
diff --git a/go.sum b/go.sum
index 3f0db58..a4412af 100644
--- a/go.sum
+++ b/go.sum
@@ -181,8 +181,6 @@ github.com/dubbogo/gost v1.11.16/go.mod h1:vIcP9rqz2KsXHPjsAwIUtfJIJjppQLQDcYaZT
 github.com/dubbogo/jsonparser v1.0.1/go.mod h1:tYAtpctvSP/tWw4MeelsowSPgXQRVHHWbqL6ynps8jU=
 github.com/dubbogo/net v0.0.4 h1:Rn9aMPZwOiRE22YhtxmDEE3H0Q3cfVRNhuEjNMelJ/8=
 github.com/dubbogo/net v0.0.4/go.mod h1:1CGOnM7X3he+qgGNqjeADuE5vKZQx/eMSeUkpU3ujIc=
-github.com/dubbogo/triple v1.0.6-0.20210904050749-5721796f3fd6 h1:ZrCFQ/a0rgK5EBF9FiiSYvCmtC2sLzOoFAbqBVmsA94=
-github.com/dubbogo/triple v1.0.6-0.20210904050749-5721796f3fd6/go.mod h1:KbfU/uZDv+fJEqXYK3qI8m1iuBQ309QxiC0tvTf2pog=
 github.com/dubbogo/triple v1.0.6-0.20210909153707-3620c8d2d97c h1:/Qrdqo2JVrywDANk04DHrvdfREdIApAWZ6stbYZfNaM=
 github.com/dubbogo/triple v1.0.6-0.20210909153707-3620c8d2d97c/go.mod h1:KbfU/uZDv+fJEqXYK3qI8m1iuBQ309QxiC0tvTf2pog=
 github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
diff --git a/remoting/nacos/builder_test.go b/remoting/nacos/builder_test.go
index 89992d6..eb4c1a6 100644
--- a/remoting/nacos/builder_test.go
+++ b/remoting/nacos/builder_test.go
@@ -50,7 +50,7 @@ func TestNewNacosClient(t *testing.T) {
 	assert.NotNil(t, err)
 
 	rc.Address = "console.nacos.io:80"
-	rc.TimeoutStr = "10s"
+	rc.Timeout = "10s"
 	client, err = NewNacosClient(rc)
 	assert.NotNil(t, client)
 	assert.Nil(t, err)