Repository: zeromicro/go-zero
Pull request #2950 (2023-03-02 08:34:33)

feat: support grpc client keepalive config

codecov[bot]: # [Codecov](https://codecov.io/gh/zeromicro/go-zero/pull/2950?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
> Merging [#2950](https://codecov.io/gh/zeromicro/go-zero/pull/2950?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (91cb2c2) into [master](https://codecov.io/gh/zeromicro/go-zero/commit/1cd1b17f70bc0fad39d28ca2b64b78cf811d8efc?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (1cd1b17) will **increase** coverage by `0.02%`.
> The diff coverage is `100.00%`.


| [Impacted Files](https://codecov.io/gh/zeromicro/go-zero/pull/2950?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [zrpc/config.go](https://codecov.io/gh/zeromicro/go-zero/pull/2950?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-enJwYy9jb25maWcuZ28=) | `100.00% <ø> (ø)` | |
| [zrpc/client.go](https://codecov.io/gh/zeromicro/go-zero/pull/2950?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-enJwYy9jbGllbnQuZ28=) | `95.00% <100.00%> (+1.12%)` | :arrow_up: |
| [core/logx/rotatelogger.go](https://codecov.io/gh/zeromicro/go-zero/pull/2950?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-Y29yZS9sb2d4L3JvdGF0ZWxvZ2dlci5nbw==) | `73.80% <0.00%> (+1.10%)` | :arrow_up: |


Patch:
diff --git a/zrpc/client.go b/zrpc/client.go
index 9966d038..db00d047 100644
--- a/zrpc/client.go
+++ b/zrpc/client.go
@@ -8,8 +8,11 @@ import (
 	"github.com/zeromicro/go-zero/zrpc/internal/auth"
 	"github.com/zeromicro/go-zero/zrpc/internal/clientinterceptors"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/keepalive"
 )
 
+const defaultClientKeepaliveTime = 20 * time.Second
+
 var (
 	// WithDialOption is an alias of internal.WithDialOption.
 	WithDialOption = internal.WithDialOption
@@ -62,6 +65,11 @@ func NewClient(c RpcClientConf, options ...ClientOption) (Client, error) {
 	if c.Timeout > 0 {
 		opts = append(opts, WithTimeout(time.Duration(c.Timeout)*time.Millisecond))
 	}
+	if c.KeepaliveTime > 0 {
+		opts = append(opts, WithDialOption(grpc.WithKeepaliveParams(keepalive.ClientParameters{
+			Time: c.KeepaliveTime,
+		})))
+	}
 
 	opts = append(opts, options...)
 
@@ -90,6 +98,12 @@ func NewClientWithTarget(target string, opts ...ClientOption) (Client, error) {
 		Timeout:    true,
 	}
 
+	opts = append([]ClientOption{
+		WithDialOption(grpc.WithKeepaliveParams(keepalive.ClientParameters{
+			Time: defaultClientKeepaliveTime,
+		})),
+	}, opts...)
+
 	return internal.NewClient(target, middlewares, opts...)
 }
 
diff --git a/zrpc/config.go b/zrpc/config.go
index 7f772807..646382fd 100644
--- a/zrpc/config.go
+++ b/zrpc/config.go
@@ -1,6 +1,8 @@
 package zrpc
 
 import (
+	"time"
+
 	"github.com/zeromicro/go-zero/core/discov"
 	"github.com/zeromicro/go-zero/core/service"
 	"github.com/zeromicro/go-zero/core/stores/redis"
@@ -14,6 +16,19 @@ type (
 	// ServerMiddlewaresConf defines whether to use server middlewares.
 	ServerMiddlewaresConf = internal.ServerMiddlewaresConf
 
+	// A RpcClientConf is a rpc client config.
+	RpcClientConf struct {
+		Etcd          discov.EtcdConf `json:",optional,inherit"`
+		Endpoints     []string        `json:",optional"`
+		Target        string          `json:",optional"`
+		App           string          `json:",optional"`
+		Token         string          `json:",optional"`
+		NonBlock      bool            `json:",optional"`
+		Timeout       int64           `json:",default=2000"`
+		KeepaliveTime time.Duration   `json:",default=20s"`
+		Middlewares   ClientMiddlewaresConf
+	}
+
 	// A RpcServerConf is a rpc server config.
 	RpcServerConf struct {
 		service.ServiceConf
@@ -29,18 +44,6 @@ type (
 		Health      bool `json:",default=true"`
 		Middlewares ServerMiddlewaresConf
 	}
-
-	// A RpcClientConf is a rpc client config.
-	RpcClientConf struct {
-		Etcd        discov.EtcdConf `json:",optional,inherit"`
-		Endpoints   []string        `json:",optional"`
-		Target      string          `json:",optional"`
-		App         string          `json:",optional"`
-		Token       string          `json:",optional"`
-		NonBlock    bool            `json:",optional"`
-		Timeout     int64           `json:",default=2000"`
-		Middlewares ClientMiddlewaresConf
-	}
 )
 
 // NewDirectClientConf returns a RpcClientConf.


Test patch:
diff --git a/zrpc/client_test.go b/zrpc/client_test.go
index 368ca2ee..70da01b2 100644
--- a/zrpc/client_test.go
+++ b/zrpc/client_test.go
@@ -113,10 +113,11 @@ func TestDepositServer_Deposit(t *testing.T) {
 	)
 	tarConfClient := MustNewClient(
 		RpcClientConf{
-			Target:  "foo",
-			App:     "foo",
-			Token:   "bar",
-			Timeout: 1000,
+			Target:        "foo",
+			App:           "foo",
+			Token:         "bar",
+			Timeout:       1000,
+			KeepaliveTime: time.Second * 15,
 			Middlewares: ClientMiddlewaresConf{
 				Trace:      true,
 				Duration:   true,