From 6b8f403767b3775c2d9e4661f8c609336b04a77d Mon Sep 17 00:00:00 2001 From: giantwu Date: Thu, 25 Dec 2025 18:37:10 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=B4=9F=E8=BD=BD?= =?UTF-8?q?=E5=9D=87=E8=A1=A1=E9=85=8D=E7=BD=AE=E9=A1=B9=EF=BC=8C=E7=94=A8?= =?UTF-8?q?=E4=BA=8Egrpc-client?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/dtmgrpc/dtmgimp/grpc_clients.go | 28 +++++++++++++++++++++++++- conf.sample.yml | 3 +++ dtmsvr/config/config.go | 12 ++++++++++- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/client/dtmgrpc/dtmgimp/grpc_clients.go b/client/dtmgrpc/dtmgimp/grpc_clients.go index 2291c52..94effbe 100644 --- a/client/dtmgrpc/dtmgimp/grpc_clients.go +++ b/client/dtmgrpc/dtmgimp/grpc_clients.go @@ -8,6 +8,7 @@ package dtmgimp import ( "fmt" + "os" "sync" "github.com/dtm-labs/dtm/client/dtmcli/dtmimp" @@ -39,6 +40,9 @@ var normalClients, rawClients sync.Map // ClientInterceptors declares grpc.UnaryClientInterceptors slice var ClientInterceptors = []grpc.UnaryClientInterceptor{} +// GrpcServiceConfigGetter is a function to get gRPC service config, can be set by server config +var GrpcServiceConfigGetter func() string + // MustGetDtmClient 1 func MustGetDtmClient(grpcServer string) dtmgpb.DtmClient { return dtmgpb.NewDtmClient(MustGetGrpcConn(grpcServer, false)) @@ -61,7 +65,12 @@ func GetGrpcConn(grpcServer string, isRaw bool) (conn *grpc.ClientConn, rerr err interceptors := append(ClientInterceptors, GrpcClientLog) interceptors = append(interceptors, dtmdriver.Middlewares.Grpc...) inOpt := grpc.WithChainUnaryInterceptor(interceptors...) - conn, rerr := grpc.Dial(grpcServer, inOpt, grpc.WithTransportCredentials(insecure.NewCredentials()), opts) + grpcServiceConfig, hasConfig := getGrpcServiceConfig() + dialOpts := []grpc.DialOption{inOpt, grpc.WithTransportCredentials(insecure.NewCredentials()), opts} + if hasConfig { + dialOpts = append(dialOpts, grpc.WithDefaultServiceConfig(grpcServiceConfig)) + } + conn, rerr := grpc.Dial(grpcServer, dialOpts...) if rerr == nil { clients.Store(grpcServer, conn) v = conn @@ -77,3 +86,20 @@ func MustGetGrpcConn(grpcServer string, isRaw bool) *grpc.ClientConn { dtmimp.E2P(err) return conn } + +// getGrpcServiceConfig returns the gRPC service config from config getter or environment variable, and a bool indicating if config is set +func getGrpcServiceConfig() (string, bool) { + // First try to get from config getter (set by server) + if GrpcServiceConfigGetter != nil { + if config := GrpcServiceConfigGetter(); config != "" { + return config, true + } + } + // Fallback to environment variable + config := os.Getenv("GRPC_SERVICE_CONFIG") + if config != "" { + return config, true + } + // No config set + return "", false +} diff --git a/conf.sample.yml b/conf.sample.yml index 6da326f..c23079b 100644 --- a/conf.sample.yml +++ b/conf.sample.yml @@ -70,3 +70,6 @@ # AlertRetryLimit: 3 # default 3; if a transaction branch has been retried 3 times, the AlertHook will be called # AlertWebHook: '' # default ''; sample: 'http://localhost:8080/dtm-hook'. this hook will be called like this: ## curl -H "Content-Type: application/json" -d '{"gid":"xxxx","status":"submitted","retry_count":3}' http://localhost:8080/dtm-hook + +# GrpcBalancer: 'round_robin' # default round_robin,For more information about service configs, see:https://github.com/grpc/grpc/blob/master/doc/service_config.md +# GrpcServiceConfig: '{"loadBalancingConfig": [{"round_robin":{}}]}' # default gRPC service config for client connections diff --git a/dtmsvr/config/config.go b/dtmsvr/config/config.go index 35815f2..9cf7ce4 100644 --- a/dtmsvr/config/config.go +++ b/dtmsvr/config/config.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "github.com/dtm-labs/dtm/client/dtmcli" + "github.com/dtm-labs/dtm/client/dtmgrpc/dtmgimp" "github.com/dtm-labs/logger" "gopkg.in/yaml.v3" ) @@ -95,7 +96,7 @@ type Type struct { JSONRPCPort int64 `yaml:"JsonRpcPort" default:"36791"` MicroService MicroService `yaml:"MicroService"` HTTPMicroService HTTPMicroService `yaml:"HttpMicroService"` - UpdateBranchSync int64 `yaml:"UpdateBranchSync" default:"1"` + UpdateBranchSync int64 `yaml:"UpdateBranchSync"` UpdateBranchAsyncGoroutineNum int64 `yaml:"UpdateBranchAsyncGoroutineNum" default:"1"` LogLevel string `yaml:"LogLevel" default:"info"` Log Log `yaml:"Log"` @@ -104,6 +105,7 @@ type Type struct { AlertRetryLimit int64 `yaml:"AlertRetryLimit" default:"3"` AlertWebHook string `yaml:"AlertWebHook"` AdminBasePath string `yaml:"AdminBasePath"` + GrpcServiceConfig string `yaml:"GrpcServiceConfig" default:"{\"loadBalancingConfig\": [{\"round_robin\":{}}]}"` } // Config config @@ -124,4 +126,12 @@ func MustLoadConfig(confFile string) { err = checkConfig(&Config) logger.FatalfIf(err != nil, `config error: '%v'. please visit http://d.dtm.pub to see the config document.`, err) + // Set gRPC service config for client library + if Config.GrpcServiceConfig == "" { + Config.GrpcServiceConfig = `{"loadBalancingConfig": [{"round_robin":{}}]}` + } + // Set config getter function for client library to read config directly + dtmgimp.GrpcServiceConfigGetter = func() string { + return Config.GrpcServiceConfig + } } From 59a6a449c2e8fdd4e1422d1187b8d45217f72fae Mon Sep 17 00:00:00 2001 From: giantwu Date: Thu, 25 Dec 2025 18:43:30 +0800 Subject: [PATCH 2/2] Add default value for UpdateBranchSync in config Set default value for UpdateBranchSync to 1 --- dtmsvr/config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtmsvr/config/config.go b/dtmsvr/config/config.go index 9cf7ce4..e27bed1 100644 --- a/dtmsvr/config/config.go +++ b/dtmsvr/config/config.go @@ -96,7 +96,7 @@ type Type struct { JSONRPCPort int64 `yaml:"JsonRpcPort" default:"36791"` MicroService MicroService `yaml:"MicroService"` HTTPMicroService HTTPMicroService `yaml:"HttpMicroService"` - UpdateBranchSync int64 `yaml:"UpdateBranchSync"` + UpdateBranchSync int64 `yaml:"UpdateBranchSync" default:"1"` UpdateBranchAsyncGoroutineNum int64 `yaml:"UpdateBranchAsyncGoroutineNum" default:"1"` LogLevel string `yaml:"LogLevel" default:"info"` Log Log `yaml:"Log"`