-
Notifications
You must be signed in to change notification settings - Fork 3.9k
examples: Health example #9991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
examples: Health example #9991
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
4afc5b1
checkpoint
larry-safran bb3faec
Completed health service example.
larry-safran a0d287a
Everything ready except for bazel dependency problem
larry-safran 5a14ea8
fix bazel
larry-safran 9b25ddc
Add round robin to the example.
larry-safran aae877e
fixed
larry-safran 09efd9d
disable recording real-time metrics using in gcp-o11y
DNVindhya caac3f0
gcp-o11y: add sleep in Observability close()
DNVindhya 7b6caef
test/android: fix the import for AndroidJUnit4
zhangkun83 c5949da
netty: implement GrpcHttp2InboundHeaders.iterator()
zhangkun83 4002b4e
examples: waitForReady example (#9960)
larry-safran f618fee
gcp-o11y: add default custom tag for metrics exporter
DNVindhya 21fe4c2
Remove sleep from Observability Interop Test binary now that its done…
stanley-cheung 7581150
examples: add gcp-observability examples (#9967)
DNVindhya c672d99
examples: Add cancellation example
ejona86 2d38926
Add support for cross-compiling for s390x platform (#9455)
haubenr 490de36
[Examples] health service example
larry-safran c43c4fe
fixed
larry-safran db31ca7
fix build
larry-safran cebe3e8
Add health service to README.md.
larry-safran f49f709
Merge branch 'master' into health_example
larry-safran 11f8d06
Address review comments.
larry-safran File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
194 changes: 194 additions & 0 deletions
194
examples/src/main/java/io/grpc/examples/healthservice/HealthServiceClient.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
/* | ||
* Copyright 2023 The gRPC Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.grpc.examples.healthservice; | ||
|
||
import io.grpc.Channel; | ||
import io.grpc.Grpc; | ||
import io.grpc.InsecureChannelCredentials; | ||
import io.grpc.LoadBalancerProvider; | ||
import io.grpc.LoadBalancerRegistry; | ||
import io.grpc.ManagedChannel; | ||
import io.grpc.ManagedChannelBuilder; | ||
import io.grpc.StatusRuntimeException; | ||
import io.grpc.examples.helloworld.GreeterGrpc; | ||
import io.grpc.examples.helloworld.HelloReply; | ||
import io.grpc.examples.helloworld.HelloRequest; | ||
import io.grpc.health.v1.HealthCheckRequest; | ||
import io.grpc.health.v1.HealthCheckResponse; | ||
import io.grpc.health.v1.HealthCheckResponse.ServingStatus; | ||
import io.grpc.health.v1.HealthGrpc; | ||
import java.util.Arrays; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.concurrent.TimeUnit; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
/** | ||
* A client that requests a greeting from the {@link HelloWorldServer}. | ||
*/ | ||
public class HealthServiceClient { | ||
private static final Logger logger = Logger.getLogger(HealthServiceClient.class.getName()); | ||
|
||
private final GreeterGrpc.GreeterBlockingStub greeterBlockingStub; | ||
private final HealthGrpc.HealthStub healthStub; | ||
private final HealthGrpc.HealthBlockingStub healthBlockingStub; | ||
|
||
private final HealthCheckRequest healthRequest; | ||
|
||
/** Construct client for accessing HelloWorld server using the existing channel. */ | ||
public HealthServiceClient(Channel channel) { | ||
greeterBlockingStub = GreeterGrpc.newBlockingStub(channel); | ||
healthStub = HealthGrpc.newStub(channel); | ||
healthBlockingStub = HealthGrpc.newBlockingStub(channel); | ||
healthRequest = HealthCheckRequest.getDefaultInstance(); | ||
LoadBalancerProvider roundRobin = LoadBalancerRegistry.getDefaultRegistry() | ||
.getProvider("round_robin"); | ||
|
||
} | ||
|
||
private ServingStatus checkHealth(String prefix) { | ||
HealthCheckResponse response = | ||
healthBlockingStub.check(healthRequest); | ||
logger.info(prefix + ", current health is: " + response.getStatus()); | ||
return response.getStatus(); | ||
} | ||
|
||
/** Say hello to server. */ | ||
public void greet(String name) { | ||
logger.info("Will try to greet " + name + " ..."); | ||
HelloRequest request = HelloRequest.newBuilder().setName(name).build(); | ||
HelloReply response; | ||
try { | ||
response = greeterBlockingStub.sayHello(request); | ||
} catch (StatusRuntimeException e) { | ||
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus()); | ||
return; | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
return; | ||
} | ||
logger.info("Greeting: " + response.getMessage()); | ||
} | ||
|
||
|
||
private static void runTest(String target, String[] users, boolean useRoundRobin) | ||
throws InterruptedException { | ||
ManagedChannelBuilder<?> builder = | ||
Grpc.newChannelBuilder(target, InsecureChannelCredentials.create()); | ||
|
||
// Round Robin, when a healthCheckConfig is present in the default service configuration, runs | ||
// a watch on the health service and when picking an endpoint will | ||
// consider a transport to a server whose service is not in SERVING state to be unavailable. | ||
// Since we only have a single server we are connecting to, then the load balancer will | ||
// return an error without sending the RPC. | ||
if (useRoundRobin) { | ||
builder = builder | ||
.defaultLoadBalancingPolicy("round_robin") | ||
.defaultServiceConfig(generateHealthConfig("")); | ||
} | ||
|
||
ManagedChannel channel = builder.build(); | ||
|
||
System.out.println("\nDoing test with" + (useRoundRobin ? "" : "out") | ||
+ " the Round Robin load balancer\n"); | ||
|
||
try { | ||
HealthServiceClient client = new HealthServiceClient(channel); | ||
if (!useRoundRobin) { | ||
client.checkHealth("Before call"); | ||
} | ||
client.greet(users[0]); | ||
if (!useRoundRobin) { | ||
client.checkHealth("After user " + users[0]); | ||
} | ||
|
||
for (String user : users) { | ||
client.greet(user); | ||
Thread.sleep(100); // Since the health update is asynchronous give it time to propagate | ||
} | ||
|
||
if (!useRoundRobin) { | ||
client.checkHealth("After all users"); | ||
Thread.sleep(10000); | ||
client.checkHealth("After 10 second wait"); | ||
} else { | ||
Thread.sleep(10000); | ||
} | ||
client.greet("Larry"); | ||
} finally { | ||
// ManagedChannels use resources like threads and TCP connections. To prevent leaking these | ||
// resources the channel should be shut down when it will no longer be used. If it may be used | ||
// again leave it running. | ||
channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS); | ||
} | ||
} | ||
private static Map<String, Object> generateHealthConfig(String serviceName) { | ||
Map<String, Object> config = new HashMap<>(); | ||
Map<String, Object> serviceMap = new HashMap<>(); | ||
|
||
config.put("healthCheckConfig", serviceMap); | ||
serviceMap.put("serviceName", serviceName); | ||
return config; | ||
} | ||
|
||
/** | ||
* Uses a server with both a greet service and the health service. | ||
* If provided, the first element of {@code args} is the name to use in the | ||
* greeting. The second argument is the target server. | ||
* This has an example of using the health service directly through the unary call | ||
* <a href="https://github.com/grpc/grpc-java/blob/master/services/src/main/proto/grpc/health/v1/health.proto">check</a> | ||
* to get the current health. It also utilizes the health of the server's greet service | ||
* indirectly through the round robin load balancer, which uses the streaming rpc | ||
* <strong>watch</strong> (you can see how it is done in | ||
* {@link io.grpc.protobuf.services.HealthCheckingLoadBalancerFactory}). | ||
*/ | ||
public static void main(String[] args) throws Exception { | ||
System.setProperty("java.util.logging.SimpleFormatter.format", | ||
"%1$tH:%1$tM:%1$tS %4$s %2$s: %5$s%6$s%n"); | ||
|
||
String[] users = {"world", "foo", "I am Grut"}; | ||
// Access a service running on the local machine on port 50051 | ||
String target = "localhost:50051"; | ||
// Allow passing in the user and target strings as command line arguments | ||
if (args.length > 0) { | ||
if ("--help".equals(args[0])) { | ||
System.err.println("Usage: [target [name] [name] ...]"); | ||
System.err.println(""); | ||
System.err.println(" target The server to connect to. Defaults to " + target); | ||
System.err.println(" name The names you wish to be greeted by. Defaults to " + Arrays.toString(users)); | ||
System.exit(1); | ||
} | ||
target = args[0]; | ||
} | ||
if (args.length > 1) { | ||
users = new String[args.length-1]; | ||
for (int i=0; i < users.length; i++) { | ||
users[i] = args[i+1]; | ||
} | ||
} | ||
|
||
// Will see failures of rpc's sent while server service is not serving, where the failures come | ||
// from the server | ||
runTest(target, users, false); | ||
|
||
// The client will throw an error when sending the rpc to a non-serving service because the | ||
// round robin load balancer uses the health service's watch rpc. | ||
runTest(target, users, true); | ||
|
||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.