Skip to content

Commit b7c8ad2

Browse files
committed
Enable client side gRPC health check by default
Signed-off-by: Benjamin Wang <[email protected]>
1 parent 7ab7612 commit b7c8ad2

File tree

3 files changed

+13
-45
lines changed

3 files changed

+13
-45
lines changed

client/v3/internal/resolver/resolver.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package resolver
1616

1717
import (
18+
_ "google.golang.org/grpc/health"
1819
"google.golang.org/grpc/resolver"
1920
"google.golang.org/grpc/resolver/manual"
2021
"google.golang.org/grpc/serviceconfig"
@@ -41,7 +42,7 @@ func New(endpoints ...string) *EtcdManualResolver {
4142

4243
// Build returns itself for Resolver, because it's both a builder and a resolver.
4344
func (r *EtcdManualResolver) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
44-
r.serviceConfig = cc.ParseServiceConfig(`{"loadBalancingPolicy": "round_robin"}`)
45+
r.serviceConfig = cc.ParseServiceConfig(`{"loadBalancingPolicy": "round_robin", "healthCheckConfig": {"serviceName": ""}}`)
4546
if r.serviceConfig.Err != nil {
4647
return nil, r.serviceConfig.Err
4748
}

server/etcdserver/api/v3rpc/interceptor.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ import (
3434
)
3535

3636
const (
37-
maxNoLeaderCnt = 3
38-
snapshotMethod = "/etcdserverpb.Maintenance/Snapshot"
37+
maxNoLeaderCnt = 3
38+
snapshotMethod = "/etcdserverpb.Maintenance/Snapshot"
39+
gRPCHealthWatch = "/grpc.health.v1.Health/Watch"
3940
)
4041

4142
type streamsMap struct {
@@ -218,7 +219,7 @@ func newStreamInterceptor(s *etcdserver.EtcdServer) grpc.StreamServerInterceptor
218219
return rpctypes.ErrGRPCNotCapable
219220
}
220221

221-
if s.IsMemberExist(s.MemberID()) && s.IsLearner() && info.FullMethod != snapshotMethod { // learner does not support stream RPC except Snapshot
222+
if s.IsMemberExist(s.MemberID()) && s.IsLearner() && !isRPCStreamSupportForLearner(info) {
222223
return rpctypes.ErrGRPCNotSupportedForLearner
223224
}
224225

@@ -259,6 +260,11 @@ func newStreamInterceptor(s *etcdserver.EtcdServer) grpc.StreamServerInterceptor
259260
}
260261
}
261262

263+
// learner does not support stream RPC except Snapshot and gRPC Health Watch
264+
func isRPCStreamSupportForLearner(info *grpc.StreamServerInfo) bool {
265+
return info.FullMethod == snapshotMethod || info.FullMethod == gRPCHealthWatch
266+
}
267+
262268
// cancellableContext wraps a context with new cancellable context that allows a
263269
// specific cancellation error to be preserved and later retrieved using the
264270
// Context.Err() function. This is so downstream context users can disambiguate

tests/e2e/failover_test.go

+2-41
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323

2424
"github.com/stretchr/testify/require"
2525
"golang.org/x/sync/errgroup"
26-
"google.golang.org/grpc"
2726
_ "google.golang.org/grpc/health"
2827

2928
clientv3 "go.etcd.io/etcd/client/v3"
@@ -44,9 +43,8 @@ const (
4443

4544
func TestFailoverOnDefrag(t *testing.T) {
4645
tcs := []struct {
47-
name string
48-
clusterOptions []e2e.EPClusterOption
49-
gRPCDialOptions []grpc.DialOption
46+
name string
47+
clusterOptions []e2e.EPClusterOption
5048

5149
// common assertion
5250
expectedMinQPS float64
@@ -62,10 +60,6 @@ func TestFailoverOnDefrag(t *testing.T) {
6260
e2e.WithExperimentalStopGRPCServiceOnDefrag(true),
6361
e2e.WithGoFailEnabled(true),
6462
},
65-
gRPCDialOptions: []grpc.DialOption{
66-
grpc.WithDisableServiceConfig(),
67-
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin", "healthCheckConfig": {"serviceName": ""}}`),
68-
},
6963
expectedMinQPS: 20,
7064
expectedMaxFailureRate: 0.01,
7165
},
@@ -76,20 +70,6 @@ func TestFailoverOnDefrag(t *testing.T) {
7670
e2e.WithExperimentalStopGRPCServiceOnDefrag(false),
7771
e2e.WithGoFailEnabled(true),
7872
},
79-
gRPCDialOptions: []grpc.DialOption{
80-
grpc.WithDisableServiceConfig(),
81-
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin", "healthCheckConfig": {"serviceName": ""}}`),
82-
},
83-
expectedMinQPS: 20,
84-
expectedMinFailureRate: 0.25,
85-
},
86-
{
87-
name: "defrag blocks one-third of requests with stopGRPCServiceOnDefrag set to true and client health check disabled",
88-
clusterOptions: []e2e.EPClusterOption{
89-
e2e.WithClusterSize(3),
90-
e2e.WithExperimentalStopGRPCServiceOnDefrag(true),
91-
e2e.WithGoFailEnabled(true),
92-
},
9373
expectedMinQPS: 20,
9474
expectedMinFailureRate: 0.25,
9575
},
@@ -100,10 +80,6 @@ func TestFailoverOnDefrag(t *testing.T) {
10080
e2e.WithServerFeatureGate("StopGRPCServiceOnDefrag", true),
10181
e2e.WithGoFailEnabled(true),
10282
},
103-
gRPCDialOptions: []grpc.DialOption{
104-
grpc.WithDisableServiceConfig(),
105-
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin", "healthCheckConfig": {"serviceName": ""}}`),
106-
},
10783
expectedMinQPS: 20,
10884
expectedMaxFailureRate: 0.01,
10985
},
@@ -114,20 +90,6 @@ func TestFailoverOnDefrag(t *testing.T) {
11490
e2e.WithServerFeatureGate("StopGRPCServiceOnDefrag", false),
11591
e2e.WithGoFailEnabled(true),
11692
},
117-
gRPCDialOptions: []grpc.DialOption{
118-
grpc.WithDisableServiceConfig(),
119-
grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin", "healthCheckConfig": {"serviceName": ""}}`),
120-
},
121-
expectedMinQPS: 20,
122-
expectedMinFailureRate: 0.25,
123-
},
124-
{
125-
name: "defrag blocks one-third of requests with StopGRPCServiceOnDefrag feature gate set to true and client health check disabled",
126-
clusterOptions: []e2e.EPClusterOption{
127-
e2e.WithClusterSize(3),
128-
e2e.WithServerFeatureGate("StopGRPCServiceOnDefrag", true),
129-
e2e.WithGoFailEnabled(true),
130-
},
13193
expectedMinQPS: 20,
13294
expectedMinFailureRate: 0.25,
13395
},
@@ -151,7 +113,6 @@ func TestFailoverOnDefrag(t *testing.T) {
151113
DialKeepAliveTime: keepaliveTime,
152114
DialKeepAliveTimeout: keepaliveTimeout,
153115
Endpoints: endpoints,
154-
DialOptions: tc.gRPCDialOptions,
155116
})
156117
if cerr != nil {
157118
return cerr

0 commit comments

Comments
 (0)