Digital Identity is Under Attack: FIDO Paris Seminar.pptx
"Enabling Googley microservices with gRPC" Riga DevDays 2018 edition
1. Alex Borysov
Software Engineer
Enabling Googley microservices with gRPC.
A high performance, open source, HTTP/2-based RPC framework.
Riga DevDays, May 30, 2018
2. Google Cloud Platform
Alex Borysov
• Software engineer / tech lead experienced in large scale
software development.
• 12+ years of software engineering experience.
• Active gRPC user.
• devoxx.org.ua program committee member.
@aiborisov
5. Google Cloud Platform
What is gRPC?
A high performance, general purpose, feature-rich
RPC framework.
Part of Cloud Native Computing Foundation cncf.io.
HTTP/2 and mobile first.
Open source version of Stubby RPC used in Google.
#RigaDevDays @aiborisov
6. Google Cloud Platform
g in gRPC stands for
#RigaDevDays @aiborisov
1.0 'gRPC'
1.1 'good'
1.2 'green'
1.3 'gentle'
. . .
1.9 'glossy'
1.10 'glamorous'
1.11 'gorgeous'
1.12 'glorious'
https://github.com/grpc/grpc/blob/master/doc/g_stands_for.md
8. Google Cloud Platform
gRPC is not RMI
#RigaDevDays @aiborisov
Maintainability
Ease of use
Performance
Scalability
L
e
s
s
o
n
s
Years of using Stubby
9. Google Cloud Platform
What is gRPC?
Abstractions and best practices on how to design
distributed systems.
Default implementation(s) from Google.
Extension points to plug custom implementations and
modifications.
Supports 10+ programming languages
#RigaDevDays @aiborisov
10. Google Cloud Platform
What is gRPC?
Abstractions and best practices on how to design
distributed systems.
Default implementation(s) from Google.
Extension points to plug custom implementations and
modifications.
Supports 10+ programming languages, including JS!
#RigaDevDays @aiborisov
11. Google Cloud Platform
gRPC vs JSON/HTTP for Google Cloud Pub/Sub
3x increase in throughput
https://cloud.google.com/blog/big-data/2016/03/announcing-grpc-alpha-for-google-cloud-pubsub
11x difference per CPU
#RigaDevDays @aiborisov
24. Google Cloud Platform
#RigaDevDays @aiborisov
Service Definition
weather.proto
WeatherServiceImplBase.java WeatherRequest.java
WeatherResponse.java
WeatherServiceStub.java
WeatherServiceFutureStub.java
WeatherServiceBlockingStub.java
Service Implementation Request and response Client libraries
gRPC Java runtime
25. Google Cloud Platform
Implement gRPC Service
public class WeatherService extends WeatherServiceImplBase {
@Override
public void getCurrent(WeatherRequest request,
StreamObserver<WeatherResponse> responseObserver) {
}
}
#RigaDevDays @aiborisov
26. Google Cloud Platform
#RigaDevDays @aiborisov
Thread #X
Thread ...
Thread #7
Thread #6
Thread #5
Thread #4
Thread #3
Thread #2
Thread #1
Thread pool
of size X
Blocking API (aka Thread-per-Request)?
27. Google Cloud Platform
Blocking API (aka Thread-per-Request)?
#RigaDevDays @aiborisov
Thread #X
Thread ...
Thread #7
Thread #6
Thread #5
Thread #4
Thread #3
Thread #2
Thread #1
Thread pool
of size X
1
28. Google Cloud Platform
Blocking API (aka Thread-per-Request)?
#RigaDevDays @aiborisov
Thread #X
Thread ...
Thread #7
Thread #6
Thread #5
Thread #4
Thread #3
Thread #2
Thread #1
Thread pool
of size X
1
2
29. Google Cloud Platform
Blocking API (aka Thread-per-Request)?
#RigaDevDays @aiborisov
Thread #X
Thread ...
Thread #7
Thread #6
Thread #5
Thread #4
Thread #3
Thread #2
Thread #1
Thread pool
of size X
1
2
3
30. Google Cloud Platform
Blocking API (aka Thread-per-Request)?
#RigaDevDays @aiborisov
Thread #X
Thread ...
Thread #7
Thread #6
Thread #5
Thread #4
Thread #3
Thread #2
Thread #1
Thread pool
of size X
1
2
3
X
. . .
31. Google Cloud Platform
Blocking API (aka Thread-per-Request)?
#RigaDevDays @aiborisov
Thread #X
Thread ...
Thread #7
Thread #6
Thread #5
Thread #4
Thread #3
Thread #2
Thread #1
Thread pool
of size X
1
2
3
X
. . .
X + 1
32. Google Cloud Platform
Blocking API (aka Thread-per-Request)?
#RigaDevDays @aiborisov
Thread #X
Thread ...
Thread #7
Thread #6
Thread #5
Thread #4
Thread #3
Thread #2
Thread #1
Thread pool
of size X
1
2
3
X
. . .
X + 1
33. Google Cloud Platform
Implement gRPC Service
public class WeatherService extends WeatherServiceImplBase {
@Override
public void getCurrent(WeatherRequest request,
StreamObserver<WeatherResponse> responseObserver) {
}
}
#RigaDevDays @aiborisov
34. Google Cloud Platform
Implement gRPC Service
public class WeatherService extends WeatherServiceImplBase {
@Override
public void getCurrent(WeatherRequest request,
public interface StreamObserver<WeatherResponse> responseObserver){{
void onNext(WeatherResponse response);
void onCompleted();
void onError(Throwable error);
}
}
}
#RigaDevDays @aiborisov
40. Google Cloud Platform
Implement gRPC Service
public class WeatherService extends WeatherServiceImplBase {
@Override
public void getCurrent(WeatherRequest request,
StreamObserver<WeatherResponse> responseObserver) {
}
}
#RigaDevDays @aiborisov
41. Google Cloud Platform
Implement gRPC Service
public class WeatherService extends WeatherServiceImplBase {
@Override
public void getCurrent(WeatherRequest request,
StreamObserver<WeatherResponse> responseObserver) {
WeatherResponse response = WeatherResponse.newBuilder()
.setTemperature(Temperature.newBuilder().setUnits(CELSUIS).setDegrees(20.f))
.setHumidity(Humidity.newBuilder().setValue(.65f))
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
#RigaDevDays @aiborisov
42. Google Cloud Platform
Start gRPC Server
Server grpcServer = NettyServerBuilder.forPort(8090)
.addService(new WeatherService()).build()
.start();
#RigaDevDays @aiborisov
59. Google Cloud Platform
...
Futures.addCallback(responsesFuture, new FutureCallback<List<WeatherResponse>>() {
@Override
public void onSuccess(@Nullable List<WeatherResponse> results) {
WeatherResponse.Builder response = WeatherResponse.newBuilder();
results.forEach(response::mergeFrom);
responseObserver.onNext(response.build());
responseObserver.onCompleted();
}
@Override
public void onFailure(Throwable t) { responseObserver.onError(t); }
});
}
}
Async Future Stub Dependencies
public class WeatherService extends WeatherServiceGrpc.WeatherServiceImplBase {
@Override
public void getCurrent(WeatherRequest request, StreamObserver<WeatherResponse> responseObserver) {
#RigaDevDays @aiborisov
60. Google Cloud Platform
Netty Transport
ManagedChannel grpcChannel = NettyChannelBuilder.forAddress("localhost", 8090).build();
WeatherServiceFutureStub futureClient = WeatherServiceGrpc.newFutureStub(grpcChannel);
#RigaDevDays @aiborisov
61. Google Cloud Platform
Netty Transport
ManagedChannel grpcChannel = NettyChannelBuilder.forAddress("localhost", 8090).build();
WeatherServiceFutureStub futureClient = WeatherServiceGrpc.newFutureStub(grpcChannel);
Server grpcServer = NettyServerBuilder.forPort(8090)
.addService(new WeatherService()).build().start();
#RigaDevDays @aiborisov
62. Google Cloud Platform
Netty: Asynchronous and Non-Blocking IO
Netty-based gRPC transport:
• Multiplexes connections on the event loops.
• Decouples I/O waiting from threads.
Request
Event
Loop
Worker thread
Worker thread
Worker thread
Worker thread
Worker thread
Worker thread
Worker thread
Event
Loop
Event
Loop
Event
Loop
Callback
Request
Callback
N
e
t
w
o
r
k
N
e
t
w
o
r
k
#RigaDevDays @aiborisov
63. Google Cloud Platform
Async Future Stub Dependencies
public class WeatherService extends WeatherServiceGrpc.WeatherServiceImplBase {
@Override
public void getCurrent(WeatherRequest request, StreamObserver<WeatherResponse> responseObserver) {
...
Futures.addCallback(responsesFuture, new FutureCallback<List<WeatherResponse>>() {
@Override
public void onSuccess(@Nullable List<WeatherResponse> results) {
WeatherResponse.Builder response = WeatherResponse.newBuilder();
results.forEach(response::mergeFrom);
responseObserver.onNext(response.build());
responseObserver.onCompleted();
}
@Override
public void onFailure(Throwable t) { responseObserver.onError(t); }
});
}
}
#RigaDevDays @aiborisov
64. Google Cloud Platform
Async Future Stub Dependencies
public class WeatherService extends WeatherServiceGrpc.WeatherServiceImplBase {
@Override
public void getCurrent(WeatherRequest request, StreamObserver<WeatherResponse> responseObserver) {
...
Futures.addCallback(responsesFuture, new FutureCallback<List<WeatherResponse>>() {
@Override
public void onSuccess(@Nullable List<WeatherResponse> results) {
WeatherResponse.Builder response = WeatherResponse.newBuilder();
results.forEach(response::mergeFrom);
responseObserver.onNext(response.build());
responseObserver.onCompleted();
}
@Override
public void onFailure(Throwable t) { responseObserver.onError(t); }
});
}
}
#RigaDevDays @aiborisov
65. Google Cloud Platform
Panta rhei, "everything flows".
Heraclitus of Ephesus
~2,400 years Before HTTP/1.x
https://en.wikipedia.org/wiki/Heraclitus
“ ”
#RigaDevDays @aiborisov
66. Google Cloud Platform
Service Definitions
service WeatherService {
rpc GetCurrent(WeatherRequest) returns (WeatherResponse);
}
service TemperatureService {
rpc GetCurrent(Coordinates) returns (Temperature);
}
service HumidityService {
rpc GetCurrent(Coordinates) returns (Humidity);
}
service WindService {
rpc GetCurrent(Coordinates) returns (Wind);
}
#RigaDevDays @aiborisov
67. Google Cloud Platform
Streaming Service Definitions
service WeatherStreamingService {
rpc GetCurrent(WeatherRequest) returns (stream WeatherResponse);
}
service TemperatureStreamingService {
rpc GetCurrent(Coordinates) returns (stream Temperature);
}
service HumidityStreamingService {
rpc GetCurrent(Coordinates) returns (stream Humidity);
}
service WindStreamingService {
rpc GetCurrent(Coordinates) returns (stream Wind);
}
#RigaDevDays @aiborisov
68. Google Cloud Platform
Bidirectional Streaming Service Definitions
service WeatherStreamingService {
rpc GetCurrent(stream WeatherRequest) returns (stream WeatherResponse);
}
service TemperatureStreamingService {
rpc GetCurrent(stream Coordinates) returns (stream Temperature);
}
service HumidityStreamingService {
rpc GetCurrent(stream Coordinates) returns (stream Humidity);
}
service WindStreamingService {
rpc GetCurrent(stream Coordinates) returns (stream Wind);
}
#RigaDevDays @aiborisov
69. Google Cloud Platform
Bidirectional Streaming Service Definitions
service WeatherStreamingService {
rpc Observe(stream WeatherRequest) returns (stream WeatherResponse);
}
service TemperatureStreamingService {
rpc Observe(stream Coordinates) returns (stream Temperature);
}
service HumidityStreamingService {
rpc Observe(stream Coordinates) returns (stream Humidity);
}
service WindStreamingService {
rpc Observe(stream Coordinates) returns (stream Wind);
}
#RigaDevDays @aiborisov
70. Google Cloud Platform
Bidirectional Streaming Service
public class WeatherStreamingService extends WeatherStreamingGrpc.WeatherStreamingImplBase {
...
@Override
public StreamObserver<WeatherRequest> observe(StreamObserver<WeatherResponse> responseObserver) {
#RigaDevDays @aiborisov
71. Google Cloud Platform
Bidirectional Streaming Service
public class WeatherStreamingService extends WeatherStreamingGrpc.WeatherStreamingImplBase {
...
@Override
public StreamObserver<WeatherRequest> observe(StreamObserver<WeatherResponse> responseObserver) {
StreamObserver<Coordinates> temperatureClientStream =
temperatureService.observe(new StreamObserver<Temperature>() {
@Override
public void onNext(Temperature temperature) {
WeatherResponse resp = WeatherResponse.newBuilder().setTemperature(temperature).build()
responseObserver.onNext(resp);
}
@Override
public void onError(Throwable t) { responseObserver.onError(t); }
@Override
public void onCompleted() { responseObserver.onCompleted(); } });
...
}
#RigaDevDays @aiborisov
72. Google Cloud Platform
Bidirectional Streaming Service
public class WeatherStreamingService extends WeatherStreamingGrpc.WeatherStreamingImplBase {
...
@Override
public StreamObserver<WeatherRequest> observe(StreamObserver<WeatherResponse> responseObserver) {
StreamObserver<Coordinates> temperatureClientStream =
temperatureService.observe(new StreamObserver<Temperature>() {
@Override
public void onNext(Temperature temperature) {
WeatherResponse resp = WeatherResponse.newBuilder().setTemperature(temperature).build()
responseObserver.onNext(resp);
}
@Override
public void onError(Throwable t) { responseObserver.onError(t); }
@Override
public void onCompleted() { responseObserver.onCompleted(); } });
...
}
#RigaDevDays @aiborisov
73. Google Cloud Platform
return new StreamObserver<WeatherRequest>() {
@Override
public void onNext(WeatherRequest request) {
temperatureClientStream.onNext(request.getCoordinates());
}
@Override
public void onError(Throwable t) { temperatureClientStream.onError(t); }
@Override
public void onCompleted() { temperatureClientStream.onCompleted(); }
};
}
Bidirectional Streaming Service
public class WeatherStreamingService extends WeatherStreamingGrpc.WeatherStreamingImplBase {
...
@Override
public StreamObserver<WeatherRequest> observe(StreamObserver<WeatherResponse> responseObserver) {
StreamObserver<Coordinates> temperatureClientStream = ...
#RigaDevDays @aiborisov
74. 74
Messaging applications.
Games / multiplayer tournaments.
Moving objects.
Sport results.
Stock market quotes.
Smart home devices.
You name it!
Streaming Use-Cases
#RigaDevDays @aiborisov
82. Google Cloud Platform
Default Timeout For Every Service?
GW
A1 A2 A3
B1 B2 B3
C1 C2 C3
200 ms
200 ms
200 ms
200 ms
200 ms 200 ms
200 ms 200 ms
200 ms 200 ms
#RigaDevDays @aiborisov
83. Google Cloud Platform
Default Timeout For Every Service?
Gateway
20 ms 10 ms 10 ms
FastFastFast
30 ms 40 ms 20 ms
130 ms
200 ms
timeout
200 ms
timeout
200 ms
timeout
200 ms
timeout
#RigaDevDays @aiborisov
84. Google Cloud Platform
Default Timeout For Every Service?
Gateway
30 ms 80 ms 100 ms
SlowFair
210 ms
200 ms
timeout
200 ms
timeout
200 ms
timeout
200 ms
timeout
#RigaDevDays @aiborisov
85. Google Cloud Platform
Default Timeout For Every Service?
30 ms 80 ms 100 ms
SlowFair
210 ms
200 ms
timeout
200 ms
timeout
200 ms
timeout
200 ms
timeout
#RigaDevDays @aiborisov
86. Google Cloud Platform
Default Timeout For Every Service?
80 ms 100 ms
SlowFair
200 ms
timeout
200 ms
timeout
200 ms
timeout
200 ms
timeout
Still working!
#RigaDevDays @aiborisov
87. Google Cloud Platform
Default Timeout For Every Service?
BusyBusy
200 ms
timeout
200 ms
timeout
200 ms
timeout
Idle Busy
#RigaDevDays @aiborisov
88. Google Cloud Platform
Default Timeout For Every Service?
BusyBusy
200 ms
timeout
200 ms
timeout
200 ms
timeout
Idle Busy
R
e
t
r
y
#RigaDevDays @aiborisov
89. Google Cloud Platform
Default Timeout For Every Service?
BusyBusy
200 ms
timeout
200 ms
timeout
200 ms
timeout
Idle Busy
R
e
t
r
y
#RigaDevDays @aiborisov
90. Google Cloud Platform
Default Timeout For Every Service?
200 ms
timeout
200 ms
timeout
200 ms
timeout
R
e
t
r
y
#RigaDevDays @aiborisov
91. Google Cloud Platform
Tune Timeout For Every Service?
GW
A1 A2 A3
B1 B2 B3
C1 C2 C3
200 ms
190 ms
190 ms
190 ms
110 ms 50 ms
110 ms 50 ms
110 ms 50 ms
#RigaDevDays @aiborisov
92. Google Cloud Platform
Tune Timeout For Every Service?
Gateway
200 ms
timeout
190 ms
timeout
110 ms
timeout
30 ms 80 ms 25 ms
FastFair
55 ms
Fast
30 ms
50 ms
timeout
#RigaDevDays @aiborisov
93. Google Cloud Platform
Tune Timeout For Every Service?
Gateway
200 ms
timeout
190 ms
timeout
110 ms
timeout
30 ms 80 ms 25 ms
Fair
55 ms
Fast
30 ms
50 ms
timeout
#RigaDevDays @aiborisov
94. Google Cloud Platform
200 ms
timeout
190 ms
timeout
110 ms
timeout
80 ms 25 ms
Fair
55 ms
Fast
30 ms
50 ms
timeout
#JokerConf @aiborisov
30 ms
Waiting
for an RPC
response
Tune Timeout For Every Service?
99. 99
gRPC Java does not support timeouts.
Timeouts in gRPC
#RigaDevDays @aiborisov
100. 100
gRPC Java does not support timeouts.
gRPC supports deadlines instead!
gRPC Deadlines
WeatherResponse response =
client.withDeadlineAfter(200, MILLISECONDS)
.getCurrent(request);
#RigaDevDays @aiborisov
101. 101
First-class feature in gRPC.
Deadline is an absolute point in time.
Deadline indicates to the server how
long the client is willing to wait for an
answer.
RPC will fail with DEADLINE_EXCEEDED
status code when deadline reached.
gRPC Deadlines
#RigaDevDays @aiborisov
102. Google Cloud Platform
gRPC Deadline Propagation
Gateway
Now =
1476600000000
Deadline =
1476600000200
Remaining = 200
withDeadlineAfter(200, MILLISECONDS)
DEADLINE_EXCEEDED DEADLINE_EXCEEDED
60 ms
DEADLINE_EXCEEDED
90 ms
DEADLINE_EXCEEDED
60 ms
Now =
1476600000060
Deadline =
1476600000200
Remaining = 140
Now =
1476600000150
Deadline =
1476600000200
Remaining = 50
Now =
1476600000210
Deadline =
1476600000200
Remaining = -10
#RigaDevDays @aiborisov
103. 103
Deadlines are automatically propagated!
Can be accessed by the receiver!
gRPC Deadlines
Context context = Context.current();
context.getDeadline().isExpired();
context.getDeadline()
.timeRemaining(MILLISECONDS);
context.getDeadline().runOnExpiration(() ->
logger.info("Deadline exceeded!"), exec);
#RigaDevDays @aiborisov
104. 104
Deadlines are expected.
What about unpredictable cancellations?
• User cancelled request.
• Caller is not interested in the result any
more.
• etc
Cancellation?
#RigaDevDays @aiborisov
105. Google Cloud Platform
Cancellation?
GW
Busy Busy Busy
Busy Busy Busy
Busy Busy Busy
RPC
Active RPC Active RPC
Active RPC
Active RPC Active RPCActive RPC
Active RPC Active RPC
Active RPC
#RigaDevDays @aiborisov
106. Google Cloud Platform
Cancellation?
GW
Busy Busy Busy
Busy Busy Busy
Busy Busy Busy
Active RPC Active RPC
Active RPC
Active RPC Active RPCActive RPC
Active RPC Active RPC
Active RPC
#RigaDevDays @aiborisov
108. 108
Automatically propagated.
RPC fails with CANCELLED status code.
Cancellation status can be accessed by
the receiver.
Server (receiver) always knows if RPC is
valid!
gRPC Cancellation
#RigaDevDays @aiborisov
109. Google Cloud Platform
gRPC Cancellation
public class WeatherService extends WeatherGrpc.WeatherServiceImplBase {
...
@Override
public void getCurrent(WeatherRequest request, StreamObserver<WeatherResponse> responseObserver) {
ServerCallStreamObserver<WeatherResponse> streamObserver =
(ServerCallStreamObserver<WeatherResponse>) responseObserver;
streamObserver.isCancelled();
...
#RigaDevDays @aiborisov
110. Google Cloud Platform
gRPC Cancellation
public class WeatherService extends WeatherGrpc.WeatherServiceImplBase {
...
@Override
public void getCurrent(WeatherRequest request, StreamObserver<WeatherResponse> responseObserver) {
ServerCallStreamObserver<WeatherResponse> streamObserver =
(ServerCallStreamObserver<WeatherResponse>) responseObserver;
streamObserver.setOnCancelHandler(() -> {
cleanupResources();
logger.info("Call cancelled by client!");
});
...
#RigaDevDays @aiborisov
116. Google Cloud Platform
Flow-Control (Client-Side)
CallStreamObserver<WeatherRequest> requestStream =
(CallStreamObserver) client.observe(new ClientResponseObserver<WeatherRequest, WeatherResponse>() {
@Override
public void beforeStart(ClientCallStreamObserver outboundStream) {
outboundStream.disableAutoInboundFlowControl();
}
@Override
public void onNext(WeatherResponse response) { processResponse(response); }
@Override
public void onError(Throwable e) { logger.error("Error on weather request.", e); }
@Override
public void onCompleted() { logger.info("Stream completed."); }
});
requestStream.onNext(request);
requestStream.request(3); // Request up to 3 responses from server
#RigaDevDays @aiborisov
117. Google Cloud Platform
Flow-Control (Client-Side)
CallStreamObserver<WeatherRequest> requestStream =
(CallStreamObserver) client.observe(new ClientResponseObserver<WeatherRequest, WeatherResponse>() {
@Override
public void beforeStart(ClientCallStreamObserver outboundStream) {
outboundStream.disableAutoInboundFlowControl();
}
@Override
public void onNext(WeatherResponse response) { processResponse(response); }
@Override
public void onError(Throwable e) { logger.error("Error on weather request.", e); }
@Override
public void onCompleted() { logger.info("Stream completed."); }
});
requestStream.onNext(request);
requestStream.request(3); // Request up to 3 responses from server
#RigaDevDays @aiborisov
118. Google Cloud Platform
Flow-Control (Client-Side)
CallStreamObserver<WeatherRequest> requestStream =
(CallStreamObserver) client.observe(new ClientResponseObserver<WeatherRequest, WeatherResponse>() {
@Override
public void beforeStart(ClientCallStreamObserver outboundStream) {
outboundStream.disableAutoInboundFlowControl();
}
@Override
public void onNext(WeatherResponse response) { processResponse(response); }
@Override
public void onError(Throwable e) { logger.error("Error on weather request.", e); }
@Override
public void onCompleted() { logger.info("Stream completed."); }
});
requestStream.onNext(request);
requestStream.request(3); // Request up to 3 responses from server
#RigaDevDays @aiborisov
119. Google Cloud Platform
Flow-Control (Client-Side)
CallStreamObserver<WeatherRequest> requestStream =
(CallStreamObserver) client.observe(new ClientResponseObserver<WeatherRequest, WeatherResponse>() {
@Override
public void beforeStart(ClientCallStreamObserver outboundStream) {
outboundStream.disableAutoInboundFlowControl();
}
@Override
public void onNext(WeatherResponse response) { processResponse(response); }
@Override
public void onError(Throwable e) { logger.error("Error on weather request.", e); }
@Override
public void onCompleted() { logger.info("Stream completed."); }
});
requestStream.onNext(request);
requestStream.request(3); // Request up to 3 responses from server
#RigaDevDays @aiborisov
120. Google Cloud Platform
Flow-Control (Client-Side)
CallStreamObserver<WeatherRequest> requestStream =
(CallStreamObserver) client.observe(new ClientResponseObserver<WeatherRequest, WeatherResponse>() {
@Override
public void beforeStart(ClientCallStreamObserver outboundStream) {
outboundStream.disableAutoInboundFlowControl();
}
@Override
public void onNext(WeatherResponse response) { processResponse(response); }
@Override
public void onError(Throwable e) { logger.error("Error on weather request.", e); }
@Override
public void onCompleted() { logger.info("Stream completed."); }
});
requestStream.onNext(request);
requestStream.request(3); // Request up to 3 responses from server
#RigaDevDays @aiborisov
121. Google Cloud Platform
Flow-Control (Client-Side)
public class WeatherStreamingService extends WeatherStreamingGrpc.WeatherStreaminServicegImplBase {
...
@Override
public StreamObserver<WeatherRequest> observe(StreamObserver<WeatherResponse> responseObserver) {
ServerCallStreamObserver<WeatherResponse> streamObserver =
(ServerCallStreamObserver<WeatherResponse>) responseObserver;
streamObserver.setOnReadyHandler(() -> {
if (streamObserver.isReady()) {
streamObserver.onNext(calculateWeather());
}
});
...
#RigaDevDays @aiborisov
122. 122
Helps to balance computing power
and network capacity between client
and server.
gRPC supports both client- and
server-side flow control.
Disabled by default.
Flow-Control
#RigaDevDays @aiborisov
127. Google Cloud Platform
Service Discovery & Load Balancing
HTTP/2
RPC Client-Side App
Channel
Stub
Future
Stub
Blocking
Stub
ClientCall
RPC Server-side Apps
Tran #1 Tran #2 Tran #N
Service Definition
(extends generated definition)
ServerCall handler
Transport
ServerCall
NameResolver LoadBalancer
Pluggable
Load
Balancing
and
Service
Discovery
#RigaDevDays @aiborisov
128. Google Cloud Platform
Service Discovery & Load Balancing
String host = System.getenv("weather_host");
int post = Integer.valueOf(System.getenv("weather_port"));
ManagedChannel grpcChannel = NettyChannelBuilder.forAddress(host, port)
.build();
#RigaDevDays @aiborisov
129. Google Cloud Platform
Service Discovery & Load Balancing
ManagedChannel grpcChannel = NettyChannelBuilder.forTarget("WeatherSrv")
.build();
#RigaDevDays @aiborisov
130. Google Cloud Platform
Service Discovery & Load Balancing
ManagedChannel grpcChannel = NettyChannelBuilder.forTarget("WeatherSrv")
.nameResolverFactory(new DnsNameResolverProvider())
.loadBalancerFactory(RoundRobinLoadBalancerFactory.getInstance())
.build();
#RigaDevDays @aiborisov
131. Google Cloud Platform
Service Discovery & Load Balancing
ManagedChannel grpcChannel = NettyChannelBuilder.forTarget("WeatherSrv")
.nameResolverFactory(new DnsNameResolverProvider())
.loadBalancerFactory(RoundRobinLoadBalancerFactory.getInstance())
.build();
#RigaDevDays @aiborisov
132. Google Cloud Platform
Service Discovery & Load Balancing
ManagedChannel grpcChannel = NettyChannelBuilder.forTarget("WeatherSrv")
.nameResolverFactory(new MyCustomNameResolverProviderFactory())
.loadBalancerFactory(new MyMoonPhaseLoadBalancerFactory())
.build();
#RigaDevDays @aiborisov
133. Google Cloud Platform
Testing Support
In-process server transport and client-side channel
StreamRecorder - StreamObserver that records all the observed values and errors.
MetadataUtils for testing metadata headers and trailer.
grpc-testing - utility functions for unit and integration testing:
https://github.com/grpc/grpc-java/tree/master/testing
#RigaDevDays @aiborisov
134. Google Cloud Platform
Testing Support - InProcess
In-process transport: fully-featured, high performance, and useful in testing.
WeatherServiceAsync weatherService =
new WeatherServiceAsync(tempService, humidityService, windService);
Server grpcServer = InProcessServerBuilder.forName("weather")
.addService(weatherService).build();
Channel grpcChannel = InProcessChannelBuilder.forName("weather").build();
WeatherServiceBlockingStub stub =
WeatherServiceGrpc.newBlockingStub(grpcChannel).withDeadlineAfter(100, MILLISECONDS);
#RigaDevDays @aiborisov
135. Google Cloud Platform
More Features
Distributed tracing support:
• OpenTracing, Zipkin / Brave support
Interceptors to add cross-cutting behavior:
• Client- and server-side
Monitoring:
• OpenCensus, gRPC Prometheus; grpcz-monitoring.
Built-in authentication mechanisms:
• SSL/TLS; token-based authentication with Google; authentication API.
Payload compression: https://github.com/grpc/grpc/blob/master/doc/compression.md
#RigaDevDays @aiborisov
141. Google Cloud Platform
Images Used
Special thanks for the provided photos:
• Andrey Borisenko
• Stanislav Vedmid
Photo from https://www.google.com/about/datacenters page:
• https://www.google.com/about/datacenters/gallery/#/tech/12
Photos licenced by Creative Commons 2.0 https://creativecommons.org/licenses/by/2.0/ :
• https://www.flickr.com/photos/garryknight/5754661212/ by Garry Knight
• https://www.flickr.com/photos/sodaigomi/21128888345/ by sodai gomi
• https://www.flickr.com/photos/zengame/15972170944/ by Zengame
• https://www.flickr.com/photos/londonmatt/18496249193/ by Matt Brown
• https://www.flickr.com/photos/gazeronly/8058105980/ by torbakhopper
#RigaDevDays @aiborisov