diff --git a/changelog/unreleased/add-grpc-max-connection-age-env.md b/changelog/unreleased/add-grpc-max-connection-age-env.md new file mode 100644 index 00000000000..06381c6df52 --- /dev/null +++ b/changelog/unreleased/add-grpc-max-connection-age-env.md @@ -0,0 +1,5 @@ +Enhancement: Allow configuring grpc max connection age + +We added a GRPC_MAX_CONNECTION_AGE env var that allows limiting the lifespan of connections. A closed connection triggers grpc clients to do a new DNS lookup to pick up new IPs. + +https://github.com/owncloud/ocis/pull/9657 diff --git a/ocis-pkg/service/grpc/keepalive.go b/ocis-pkg/service/grpc/keepalive.go new file mode 100644 index 00000000000..1a10a7be0d5 --- /dev/null +++ b/ocis-pkg/service/grpc/keepalive.go @@ -0,0 +1,24 @@ +package grpc + +import ( + "math" + "os" + "time" +) + +const ( + _serverMaxConnectionAgeEnv = "GRPC_MAX_CONNECTION_AGE" + + // same default as grpc + infinity = time.Duration(math.MaxInt64) + _defaultMaxConnectionAge = infinity +) + +// GetMaxConnectionAge returns the maximum grpc connection age. +func GetMaxConnectionAge() time.Duration { + d, err := time.ParseDuration(os.Getenv(_serverMaxConnectionAgeEnv)) + if err != nil { + return _defaultMaxConnectionAge + } + return d +} diff --git a/ocis-pkg/service/grpc/service.go b/ocis-pkg/service/grpc/service.go index 6afe731e2f8..59649607291 100644 --- a/ocis-pkg/service/grpc/service.go +++ b/ocis-pkg/service/grpc/service.go @@ -13,6 +13,8 @@ import ( "go-micro.dev/v4" "go-micro.dev/v4/client" "go-micro.dev/v4/server" + "google.golang.org/grpc" + "google.golang.org/grpc/keepalive" ) // Service simply wraps the go-micro grpc service. @@ -24,6 +26,9 @@ type Service struct { func NewServiceWithClient(client client.Client, opts ...Option) (Service, error) { var mServer server.Server sopts := newOptions(opts...) + keepaliveParams := grpc.KeepaliveParams(keepalive.ServerParameters{ + MaxConnectionAge: GetMaxConnectionAge(), // this forces clients to reconnect after 30 seconds, triggering a new DNS lookup to pick up new IPs + }) tlsConfig := &tls.Config{} if sopts.TLSEnabled { @@ -44,9 +49,9 @@ func NewServiceWithClient(client client.Client, opts ...Option) (Service, error) } } tlsConfig.Certificates = []tls.Certificate{cert} - mServer = mgrpcs.NewServer(mgrpcs.AuthTLS(tlsConfig)) + mServer = mgrpcs.NewServer(mgrpcs.Options(keepaliveParams), mgrpcs.AuthTLS(tlsConfig)) } else { - mServer = mgrpcs.NewServer() + mServer = mgrpcs.NewServer(mgrpcs.Options(keepaliveParams)) } mopts := []micro.Option{