3232import io .grpc .health .v1 .HealthCheckResponse .ServingStatus ;
3333import io .grpc .health .v1 .HealthGrpc ;
3434import java .util .Arrays ;
35+ import java .util .Collections ;
3536import java .util .HashMap ;
3637import java .util .Map ;
3738import java .util .concurrent .TimeUnit ;
@@ -45,25 +46,17 @@ public class HealthServiceClient {
4546 private static final Logger logger = Logger .getLogger (HealthServiceClient .class .getName ());
4647
4748 private final GreeterGrpc .GreeterBlockingStub greeterBlockingStub ;
48- private final HealthGrpc .HealthStub healthStub ;
4949 private final HealthGrpc .HealthBlockingStub healthBlockingStub ;
5050
51- private final HealthCheckRequest healthRequest ;
52-
5351 /** Construct client for accessing HelloWorld server using the existing channel. */
5452 public HealthServiceClient (Channel channel ) {
5553 greeterBlockingStub = GreeterGrpc .newBlockingStub (channel );
56- healthStub = HealthGrpc .newStub (channel );
5754 healthBlockingStub = HealthGrpc .newBlockingStub (channel );
58- healthRequest = HealthCheckRequest .getDefaultInstance ();
59- LoadBalancerProvider roundRobin = LoadBalancerRegistry .getDefaultRegistry ()
60- .getProvider ("round_robin" );
61-
6255 }
6356
6457 private ServingStatus checkHealth (String prefix ) {
6558 HealthCheckResponse response =
66- healthBlockingStub .check (healthRequest );
59+ healthBlockingStub .check (HealthCheckRequest . getDefaultInstance () );
6760 logger .info (prefix + ", current health is: " + response .getStatus ());
6861 return response .getStatus ();
6962 }
@@ -86,34 +79,35 @@ public void greet(String name) {
8679 }
8780
8881
89- private static void runTest (String target , String [] users , boolean useRoundRobin )
82+ private static void runTest (String target , String [] users , boolean enableHealthChecking )
9083 throws InterruptedException {
91- ManagedChannelBuilder <?> builder =
92- Grpc .newChannelBuilder (target , InsecureChannelCredentials .create ());
93-
94- // Round Robin, when a healthCheckConfig is present in the default service configuration, runs
95- // a watch on the health service and when picking an endpoint will
96- // consider a transport to a server whose service is not in SERVING state to be unavailable.
97- // Since we only have a single server we are connecting to, then the load balancer will
98- // return an error without sending the RPC.
99- if (useRoundRobin ) {
100- builder = builder
101- .defaultLoadBalancingPolicy ("round_robin" )
102- .defaultServiceConfig (generateHealthConfig ("" ));
84+ String healthServiceName ;
85+ if (enableHealthChecking ) {
86+ healthServiceName = "" ; // requests the backend's "overall health status"
87+ } else {
88+ healthServiceName = null ; // disables health checking in generateServiceConfig()
10389 }
90+ ManagedChannel channel =
91+ Grpc .newChannelBuilder (target , InsecureChannelCredentials .create ())
92+ // Enable the round_robin load balancer, with or without health checking
93+ .defaultServiceConfig (generateServiceConfig (healthServiceName ))
94+ .build ();
10495
105- ManagedChannel channel = builder .build ();
96+ // Round Robin, when a healthCheckConfig is present in the service configuration, runs a watch
97+ // on the health service and when picking an endpoint will consider a transport to a server
98+ // whose service is not in SERVING state to be unavailable. Since we only have a single server
99+ // we are connecting to, then the load balancer will return an error without sending the RPC.
106100
107- System .out .println ("\n Doing test with" + (useRoundRobin ? "" : "out" )
108- + " the Round Robin load balancer \n " );
101+ System .out .println ("\n Doing test with" + (enableHealthChecking ? "" : "out" )
102+ + " health checking \n " );
109103
110104 try {
111105 HealthServiceClient client = new HealthServiceClient (channel );
112- if (!useRoundRobin ) {
106+ if (!enableHealthChecking ) {
113107 client .checkHealth ("Before call" );
114108 }
115109 client .greet (users [0 ]);
116- if (!useRoundRobin ) {
110+ if (!enableHealthChecking ) {
117111 client .checkHealth ("After user " + users [0 ]);
118112 }
119113
@@ -122,7 +116,7 @@ private static void runTest(String target, String[] users, boolean useRoundRobin
122116 Thread .sleep (100 ); // Since the health update is asynchronous give it time to propagate
123117 }
124118
125- if (!useRoundRobin ) {
119+ if (!enableHealthChecking ) {
126120 client .checkHealth ("After all users" );
127121 Thread .sleep (10000 );
128122 client .checkHealth ("After 10 second wait" );
@@ -137,12 +131,17 @@ private static void runTest(String target, String[] users, boolean useRoundRobin
137131 channel .shutdownNow ().awaitTermination (5 , TimeUnit .SECONDS );
138132 }
139133 }
140- private static Map <String , Object > generateHealthConfig (String serviceName ) {
134+ private static Map <String , Object > generateServiceConfig (String healthServiceName ) {
141135 Map <String , Object > config = new HashMap <>();
142- Map <String , Object > serviceMap = new HashMap <>();
143-
144- config .put ("healthCheckConfig" , serviceMap );
145- serviceMap .put ("serviceName" , serviceName );
136+ if (healthServiceName != null ) {
137+ config .put ("healthCheckConfig" , Collections .singletonMap ("serviceName" , healthServiceName ));
138+ }
139+ // There is more than one round_robin implementation. If the client doesn't depend on
140+ // io.grpc:grpc-services, then the round_robin implementation does not support health watching
141+ // (to avoid a Protobuf dependency). When the client depends on grpc-services the
142+ // health-supporting round_robin implementation is used instead.
143+ config .put ("loadBalancingConfig" , Arrays .asList (
144+ Collections .singletonMap ("round_robin" , Collections .emptyMap ())));
146145 return config ;
147146 }
148147
0 commit comments