SlideShare une entreprise Scribd logo
1  sur  141
Alex Borysov
Software Engineer
Enabling Googley microservices with gRPC.
A high performance, open source, HTTP/2-based RPC framework.
Riga DevDays, May 30, 2018
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
3
devoxx.org.ua
November 23-24, 2018
Kyiv, Ukraine
Save the Date!
#RigaDevDays @aiborisov
#RigaDevDays @aiborisov
Google Cloud Platform
What is gRPC?
#RigaDevDays @aiborisov
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
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
Google Cloud Platform
RPC?! But...
#RigaDevDays @aiborisov
AMF?
RMI?
CORBA?
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
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
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
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
Google Cloud Platform
Google ~O(1010
) QPS.
#RigaDevDays @aiborisov
Google Cloud Platform
Google ~O(1010
) QPS.
Your project QPS?
#RigaDevDays @aiborisov
Google Cloud Platform
Continuous Performance Benchmarking
http://www.grpc.io/docs/guides/benchmarking.html
#RigaDevDays @aiborisov
8 core VMs, unary throughput
Google Cloud Platform
Continuous Performance Benchmarking
http://www.grpc.io/docs/guides/benchmarking.html
#RigaDevDays @aiborisov
32 core VMs, unary throughput
Google Cloud Platform
• Single TCP connection.
• No Head-of-line blocking.
• Binary framing layer.
• Header Compression.
HTTP/2 in One Slide
Transport(TCP)
Application (HTTP/2)
Network (IP)
Session (TLS) [optional]
Binary Framing
HEADERS Frame
DATA Frame
HTTP/2
POST: /upload
HTTP/1.1
Host: www.rigadevdays.lv
Content-Type: application/json
Content-Length: 27
HTTP/1.x
{“msg”: “Welcome to 2018!”}
#RigaDevDays @aiborisov
Google Cloud Platform
HTTP/1.x vs HTTP/2
http://www.http2demo.io/
https://http2.golang.org/gophertiles
#RigaDevDays @aiborisov
HTTP/1.1 HTTP/2
Google Cloud Platform
Okay, but how?
#RigaDevDays @aiborisov
Google Cloud Platform
Service Definition (weather.proto)
#RigaDevDays @aiborisov
Google Cloud Platform
Service Definition (weather.proto)
syntax = "proto3";
option java_multiple_files = true;
option java_package = "lv.rigadevdays.grpcexample";
package lv.rigadevdays.grpcexample;
service WeatherService {
rpc GetCurrent(WeatherRequest) returns (WeatherResponse);
}
#RigaDevDays @aiborisov
Google Cloud Platform
Service Definition (weather.proto)
syntax = "proto3";
option java_multiple_files = true;
option java_package = "lv.rigadevdays.grpcexample";
package lv.rigadevdays.grpcexample;
service WeatherService {
rpc GetCurrent(WeatherRequest) returns (WeatherResponse);
}
#RigaDevDays @aiborisov
Google Cloud Platform
Service Definition (weather.proto)
syntax = "proto3";
service WeatherService {
rpc GetCurrent(WeatherRequest) returns (WeatherResponse);
}
message WeatherRequest {
Coordinates coordinates = 1;
message Coordinates {
fixed64 latitude = 1;
fixed64 longitude = 2;
}
}
message WeatherResponse {
Temperature temperature = 1;
Humidity humidity = 2;
}
message Temperature {
float degrees = 1;
Units units = 2;
enum Units {
FAHRENHEIT = 0;
CELSIUS = 1;
}
}
message Humidity {
float value = 1;
}
#RigaDevDays @aiborisov
Google Cloud Platform
#RigaDevDays @aiborisov
Service Definition
weather.proto
gRPC Runtime
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
Google Cloud Platform
Implement gRPC Service
public class WeatherService extends WeatherServiceImplBase {
@Override
public void getCurrent(WeatherRequest request,
StreamObserver<WeatherResponse> responseObserver) {
}
}
#RigaDevDays @aiborisov
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)?
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
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
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
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
. . .
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
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
Google Cloud Platform
Implement gRPC Service
public class WeatherService extends WeatherServiceImplBase {
@Override
public void getCurrent(WeatherRequest request,
StreamObserver<WeatherResponse> responseObserver) {
}
}
#RigaDevDays @aiborisov
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
Google Cloud Platform
Non-Blocking API
#RigaDevDays @aiborisov
1
2
3
. . .
X + Y
X
. . .
Google Cloud Platform
Non-Blocking API (aka Hollywood Principle)
#RigaDevDays @aiborisov
1
2
3
. . .
X + Y
X
. . .
WillCallYouLater!
Google Cloud Platform
Non-Blocking API
#RigaDevDays @aiborisov
1
2
3
. . .
X + Y
X
. . .
onNext(1)
WillCallYouLater!
Google Cloud Platform
Non-Blocking API
#RigaDevDays @aiborisov
1
2
3
. . .
X + Y
X
. . .
onNext(3)
WillCallYouLater!
Google Cloud Platform
Non-Blocking API
#RigaDevDays @aiborisov
1
2
3
. . .
X + Y
X
. . .
onNext(X)
WillCallYouLater!
Google Cloud Platform
Implement gRPC Service
public class WeatherService extends WeatherServiceImplBase {
@Override
public void getCurrent(WeatherRequest request,
StreamObserver<WeatherResponse> responseObserver) {
}
}
#RigaDevDays @aiborisov
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
Google Cloud Platform
Start gRPC Server
Server grpcServer = NettyServerBuilder.forPort(8090)
.addService(new WeatherService()).build()
.start();
#RigaDevDays @aiborisov
Google Cloud Platform
gRPC Clients
ManagedChannel grpcChannel = NettyChannelBuilder.forAddress("localhost", 8090).build();
WeatherServiceStub client = WeatherServiceGrpc.newStub(grpcChannel);
#RigaDevDays @aiborisov
Google Cloud Platform
gRPC Clients
ManagedChannel grpcChannel = NettyChannelBuilder.forAddress("localhost", 8090).build();
WeatherServiceStub client = WeatherServiceGrpc.newStub(grpcChannel);
WeatherServiceBlockingStub blockingClient = WeatherServiceGrpc.newBlockingStub(grpcChannel);
WeatherServiceFutureStub futureClient = WeatherServiceGrpc.newFutureStub(grpcChannel);
#RigaDevDays @aiborisov
Google Cloud Platform
gRPC Sync Client
WeatherRequest request = WeatherRequest.newBuilder()
.setCoordinates(Coordinates.newBuilder().setLatitude(420000000)
.setLongitude(-720000000)).build();
WeatherResponse response = blockingClient.getCurrent(request);
logger.info("Current weather for {}: {}", request, response);
#RigaDevDays @aiborisov
Google Cloud Platform
gRPC Async Client
WeatherRequest request = WeatherRequest.newBuilder()
.setCoordinates(Coordinates.newBuilder().setLatitude(504316220)
.setLongitude(305166450)).build();
client.getCurrent(request, new StreamObserver<WeatherResponse>() {
@Override
public void onNext(WeatherResponse response) {
logger.info("Current weather for {}: {}", request, response);
}
@Override
public void onError(Throwable t) { logger.info("Cannot get weather for {}", request); }
@Override
public void onCompleted() { logger.info("Stream completed."); }
});
#RigaDevDays @aiborisov
Google Cloud Platform
Implement gRPC Service
public class WeatherService extends WeatherServiceGrpc.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
Google Cloud Platform
Adding New [Micro]Services
Weather
Weather
Temp
Wind
Humidity
#RigaDevDays @aiborisov
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
Google Cloud Platform
Service Definition - Response Message
message WeatherResponse {
Temperature temperature = 1;
float humidity = 2;
}
#RigaDevDays @aiborisov
Google Cloud Platform
Adding New Field
message WeatherResponse {
Temperature temperature = 1;
float humidity = 2;
Wind wind = 3;
}
message Wind {
Speed speed = 1;
float direction = 2;
}
message Speed {
float value = 1;
Units units = 2;
enum Units {
MPH = 0;
MPS = 1;
KNOTS = 2;
KMH = 3;
}
}
#RigaDevDays @aiborisov
Google Cloud Platform
private final TemperatureServiceBlockingStub temperatureService;
private final HumidityServiceBlockingStub humidityService;
private final WindServiceBlockingStub windService;
public WeatherService(TemperatureServiceBlockingStub temperatureService,
HumidityServiceBlockingStub humidityService,
WindServiceBlockingStub windService) {
this.temperatureService = temperatureService;
this.humidityService = humidityService;
this.windService = windService;
}
...
Blocking Stub Dependencies
public class WeatherService extends WeatherServiceGrpc.WeatherServiceImplBase {
#RigaDevDays @aiborisov
Google Cloud Platform
...
@Override
public void getCurrent(WeatherRequest request,
StreamObserver<WeatherResponse> responseObserver) {
Temperature temperature = temperatureService.getCurrent(request.getCoordinates());
Humidity humidity = humidityService.getCurrent(request.getCoordinates());
Wind wind = windService.getCurrent(request.getCoordinates());
WeatherResponse response = WeatherResponse.newBuilder()
.setTemperature(temperature).setHumidity(humidity).setWind(wind).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
Blocking Stub Dependencies
public class WeatherService extends WeatherServiceGrpc.WeatherServiceImplBase {
#RigaDevDays @aiborisov
54
Blocking Stubs
Temp
Humidity
Wind
#RigaDevDays @aiborisov
Google Cloud Platform
private final TemperatureServiceFutureStub tempService;
private final HumidityServiceFutureStub humidityService;
private final WindServiceFutureStub windService;
public WeatherService(TemperatureServiceFutureStub tempService,
HumidityServiceFutureStub humidityService,
WindServiceFutureStub windService) {
this.tempService = tempService;
this.humidityService = humidityService;
this.windService = windService;
}
...
Async Future Stub Dependencies
public class WeatherService extends WeatherServiceGrpc.WeatherServiceImplBase {
#RigaDevDays @aiborisov
Google Cloud Platform
@Override
public void getCurrent(WeatherRequest request, StreamObserver<WeatherResponse> responseObserver) {
Coordinates coordinates = request.getCoordinates();
ListenableFuture<List<WeatherResponse>> responsesFuture = Futures.allAsList(
Futures.transform(tempService.getCurrent(coordinates),
(Temperature temp) -> WeatherResponse.newBuilder().setTemperature(temp).build()),
Futures.transform(windService.getCurrent(coordinates),
(Wind wind) -> WeatherResponse.newBuilder().setWind(wind).build()),
Futures.transform(humidityService.getCurrent(coordinates),
(Humidity humidity) -> WeatherResponse.newBuilder().setHumidity(humidity).build())
);
...
Async Future Stub Dependencies
public class WeatherService extends WeatherServiceGrpc.WeatherServiceImplBase {
#RigaDevDays @aiborisov
Google Cloud Platform
@Override
public void getCurrent(WeatherRequest request, StreamObserver<WeatherResponse> responseObserver) {
Coordinates coordinates = request.getCoordinates();
ListenableFuture<List<WeatherResponse>> responsesFuture = Futures.allAsList(
Futures.transform(tempService.getCurrent(coordinates),
(Temperature temp) -> WeatherResponse.newBuilder().setTemperature(temp).build()),
Futures.transform(windService.getCurrent(coordinates),
(Wind wind) -> WeatherResponse.newBuilder().setWind(wind).build()),
Futures.transform(humidityService.getCurrent(coordinates),
(Humidity humidity) -> WeatherResponse.newBuilder().setHumidity(humidity).build())
);
...
Async Future Stub Dependencies
public class WeatherService extends WeatherServiceGrpc.WeatherServiceImplBase {
#RigaDevDays @aiborisov
Google Cloud Platform
@Override
public void getCurrent(WeatherRequest request, StreamObserver<WeatherResponse> responseObserver) {
Coordinates coordinates = request.getCoordinates();
ListenableFuture<List<WeatherResponse>> responsesFuture = Futures.allAsList(
Futures.transform(tempService.getCurrent(coordinates),
(Temperature temp) -> WeatherResponse.newBuilder().setTemperature(temp).build()),
Futures.transform(windService.getCurrent(coordinates),
(Wind wind) -> WeatherResponse.newBuilder().setWind(wind).build()),
Futures.transform(humidityService.getCurrent(coordinates),
(Humidity humidity) -> WeatherResponse.newBuilder().setHumidity(humidity).build())
);
...
Async Future Stub Dependencies
public class WeatherService extends WeatherServiceGrpc.WeatherServiceImplBase {
#RigaDevDays @aiborisov
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
Google Cloud Platform
Netty Transport
ManagedChannel grpcChannel = NettyChannelBuilder.forAddress("localhost", 8090).build();
WeatherServiceFutureStub futureClient = WeatherServiceGrpc.newFutureStub(grpcChannel);
#RigaDevDays @aiborisov
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
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
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
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
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
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
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
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
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
Google Cloud Platform
Bidirectional Streaming Service
public class WeatherStreamingService extends WeatherStreamingGrpc.WeatherStreamingImplBase {
...
@Override
public StreamObserver<WeatherRequest> observe(StreamObserver<WeatherResponse> responseObserver) {
#RigaDevDays @aiborisov
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
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
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
Messaging applications.
Games / multiplayer tournaments.
Moving objects.
Sport results.
Stock market quotes.
Smart home devices.
You name it!
Streaming Use-Cases
#RigaDevDays @aiborisov
Google Cloud Platform
Continuous Performance Benchmarking
http://www.grpc.io/docs/guides/benchmarking.html
#RigaDevDays @aiborisov
32 core VMs, streaming throughput
Google Cloud Platform
Continuous Performance Benchmarking
http://www.grpc.io/docs/guides/benchmarking.html
#RigaDevDays @aiborisov
32 core VMs, streaming throughput
Google Cloud Platform
gRPC Speaks Your Language
● Java
● Go
● C/C++
● C#
● Node.js
● PHP
● Ruby
● Python
● Objective-C
● JavaScript
● MacOS
● Linux
● Windows
● Android
● iOS
Service definitions and client libraries Platforms supported
#RigaDevDays @aiborisov
Google Cloud Platform
Interoperability
Java
Service
Python
Service
GoLang
Service
C++
Service
gRPC
Service
gRPC
Stub
gRPC
Stub
gRPC
Stub
gRPC
Stub
gRPC
Service
gRPC
Service
gRPC
Service
gRPC
Stub
#RigaDevDays @aiborisov
#RigaDevDays @aiborisov
Fault Tolerance?
Google Cloud Platform
Use time-outs!
And it will be fine.
“ ”
#RigaDevDays @aiborisov
Google Cloud Platform
Timeouts?
GW
A1 A2 A3
B1 B2 B3
C1 C2 C3
200 ms
?
?
?
? ?
? ?
? ?
#RigaDevDays @aiborisov
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
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
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
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
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
Google Cloud Platform
Default Timeout For Every Service?
BusyBusy
200 ms
timeout
200 ms
timeout
200 ms
timeout
Idle Busy
#RigaDevDays @aiborisov
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
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
Google Cloud Platform
Default Timeout For Every Service?
200 ms
timeout
200 ms
timeout
200 ms
timeout
R
e
t
r
y
#RigaDevDays @aiborisov
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
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
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
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?
Google Cloud Platform
Timeouts?
GW
A1 A2 A3
B1 B2 B3
C1 C2 C3
200 ms
?
?
?
? ?
? ?
? ?
#RigaDevDays @aiborisov
Google Cloud Platform
Timeouts for Real World?
GW
A1 A2 A3
B1 B2 B3
C1 C2 C3
200 ms
#RigaDevDays @aiborisov
Google Cloud Platform
Timeouts for Real World?
GW
A1 A2 A3
B1 B2 B3
C1 C2 C3
200 ms
2,500 ms
140 ms
#RigaDevDays @aiborisov
98
Timeouts in gRPC
#RigaDevDays @aiborisov
99
gRPC Java does not support timeouts.
Timeouts in gRPC
#RigaDevDays @aiborisov
100
gRPC Java does not support timeouts.
gRPC supports deadlines instead!
gRPC Deadlines
WeatherResponse response =
client.withDeadlineAfter(200, MILLISECONDS)
.getCurrent(request);
#RigaDevDays @aiborisov
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
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
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
Deadlines are expected.
What about unpredictable cancellations?
• User cancelled request.
• Caller is not interested in the result any
more.
• etc
Cancellation?
#RigaDevDays @aiborisov
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
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
Google Cloud Platform
Cancellation Propagation
GW
Idle Idle Idle
Idle Idle Idle
Idle Idle Idle
#RigaDevDays @aiborisov
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
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
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
Google Cloud Platform
More Control?
#RigaDevDays @aiborisov
Google Cloud Platform
BiDi Streaming - Slow Client
Fast Server
Request
Responses
Slow Client
CANCELLED
UNAVAILABLE
RESOURCE_EXHAUSTED
#RigaDevDays @aiborisov
Google Cloud Platform
BiDi Streaming - Slow Server
Slow Server
Request
Response
Fast Client
CANCELLED
UNAVAILABLE
RESOURCE_EXHAUSTED
Requests
#RigaDevDays @aiborisov
Google Cloud Platform
Client-Side Flow-Control
Server
Request, count = 4
Client
2 Responses
4 Responses
Count = 2
#RigaDevDays @aiborisov
Google Cloud Platform
Server-Side Flow-Control
Server
Request
Client
Response
count = 2
2 Requests
count = 3
3 Requests
#RigaDevDays @aiborisov
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
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
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
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
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
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
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
Google Cloud Platform
What else?
#RigaDevDays @aiborisov
Google Cloud Platform
Microservices?! But...
#JokerConf @aiborisov
Performance Hit?
Service Discovery?
Load Balancing?
Fault Tolerance?
Monitoring?
Tracing?
Testing?
Google Cloud Platform
Service Discovery & Load Balancing
HTTP/2
RPC Server-side App
Service Definition
(extends generated definition)
ServerCall handler
TransportTransport
ServerCall
RPC Client-Side App
Channel
Stub
Future
Stub
Blocking
Stub
ClientCall
#RigaDevDays @aiborisov
Google Cloud Platform
HTTP/2
Service Discovery & Load Balancing
RPC Client-Side App
Instance
#1
Instance
#N
Instance
#2
RPC Server-side Apps
Transport
Channel
Stub
Future
Stub
Blocking
Stub
ClientCall
#RigaDevDays @aiborisov
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
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
Google Cloud Platform
Service Discovery & Load Balancing
ManagedChannel grpcChannel = NettyChannelBuilder.forTarget("WeatherSrv")
.build();
#RigaDevDays @aiborisov
Google Cloud Platform
Service Discovery & Load Balancing
ManagedChannel grpcChannel = NettyChannelBuilder.forTarget("WeatherSrv")
.nameResolverFactory(new DnsNameResolverProvider())
.loadBalancerFactory(RoundRobinLoadBalancerFactory.getInstance())
.build();
#RigaDevDays @aiborisov
Google Cloud Platform
Service Discovery & Load Balancing
ManagedChannel grpcChannel = NettyChannelBuilder.forTarget("WeatherSrv")
.nameResolverFactory(new DnsNameResolverProvider())
.loadBalancerFactory(RoundRobinLoadBalancerFactory.getInstance())
.build();
#RigaDevDays @aiborisov
Google Cloud Platform
Service Discovery & Load Balancing
ManagedChannel grpcChannel = NettyChannelBuilder.forTarget("WeatherSrv")
.nameResolverFactory(new MyCustomNameResolverProviderFactory())
.loadBalancerFactory(new MyMoonPhaseLoadBalancerFactory())
.build();
#RigaDevDays @aiborisov
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
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
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
Google Cloud Platform
Growing Community and Ecosystem
Your
company could
be here
#RigaDevDays @aiborisov
Google Cloud Platform
Try It Out!
http://grpc.io
gRPC on Github: https://github.com/grpc
Demo: https://github.com/alxbnet/rigadevdays-grpc-demo
Google group: grpc-io@googlegroups.com
gRPC Java quickstart: http://www.grpc.io/docs/quickstart/java.html
gRPC Java tutorial: http://www.grpc.io/docs/tutorials/basic/java.html
gRPC contribution: https://github.com/grpc/grpc-contrib
#RigaDevDays @aiborisov
Google Cloud Platform
Takeaways
gRPC (http://grpc.io):
• HTTP/2 transport based, open source, general purpose
standards-based, feature-rich RPC framework.
• Bidirectional streaming over one single TCP connection.
• Netty transport provides asynchronous and non-blocking I/O.
• Deadline and cancellations propagation.
• Client and server-side flow-control.
• Pluggable service discovery and load-balancing
• Generated client libraries
• Supports 10+ programming languages.
• Build-in testing support.
• Production-ready and growing ecosystem.
#RigaDevDays @aiborisov
Google Cloud Platform
Questions?
#RigaDevDays @aiborisov
Thank You
#RigaDevDays @aiborisov
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

Contenu connexe

Tendances

gRPC vs REST: let the battle begin!
gRPC vs REST: let the battle begin!gRPC vs REST: let the battle begin!
gRPC vs REST: let the battle begin!Alex Borysov
 
DevNexus 2020 "Break me if you can: practical guide to building fault-toleran...
DevNexus 2020 "Break me if you can: practical guide to building fault-toleran...DevNexus 2020 "Break me if you can: practical guide to building fault-toleran...
DevNexus 2020 "Break me if you can: practical guide to building fault-toleran...Alex Borysov
 
"gRPC vs REST: let the battle begin!" GeeCON Krakow 2018 edition
"gRPC vs REST: let the battle begin!" GeeCON Krakow 2018 edition"gRPC vs REST: let the battle begin!" GeeCON Krakow 2018 edition
"gRPC vs REST: let the battle begin!" GeeCON Krakow 2018 editionAlex Borysov
 
"gRPC vs REST: let the battle begin!" DevoxxUK 2018 edition
"gRPC vs REST: let the battle begin!" DevoxxUK 2018 edition"gRPC vs REST: let the battle begin!" DevoxxUK 2018 edition
"gRPC vs REST: let the battle begin!" DevoxxUK 2018 editionAlex Borysov
 
Devoxx Ukraine 2018 "Break me if you can: practical guide to building fault-t...
Devoxx Ukraine 2018 "Break me if you can: practical guide to building fault-t...Devoxx Ukraine 2018 "Break me if you can: practical guide to building fault-t...
Devoxx Ukraine 2018 "Break me if you can: practical guide to building fault-t...Alex Borysov
 
REST API vs gRPC, which one should you use in breaking a monolith [Dev conf 2...
REST API vs gRPC, which one should you use in breaking a monolith [Dev conf 2...REST API vs gRPC, which one should you use in breaking a monolith [Dev conf 2...
REST API vs gRPC, which one should you use in breaking a monolith [Dev conf 2...Vladimir Dejanovic
 
HTTP/3 is next generation HTTP
HTTP/3 is next generation HTTPHTTP/3 is next generation HTTP
HTTP/3 is next generation HTTPDaniel Stenberg
 
common mistakes when using libcurl
common mistakes when using libcurlcommon mistakes when using libcurl
common mistakes when using libcurlDaniel Stenberg
 
REST API vs gRPC, which one should you use in breaking a monolith [Kdg.net 2018]
REST API vs gRPC, which one should you use in breaking a monolith [Kdg.net 2018]REST API vs gRPC, which one should you use in breaking a monolith [Kdg.net 2018]
REST API vs gRPC, which one should you use in breaking a monolith [Kdg.net 2018]Vladimir Dejanovic
 
Build your next REST API with gRPC
Build your next REST API with gRPCBuild your next REST API with gRPC
Build your next REST API with gRPCTim Burks
 
Dependency management in golang
Dependency management in golangDependency management in golang
Dependency management in golangRamit Surana
 
Git and GitHub at the San Francisco JUG
 Git and GitHub at the San Francisco JUG Git and GitHub at the San Francisco JUG
Git and GitHub at the San Francisco JUGMatthew McCullough
 
Http3 fullstackfest-2019
Http3 fullstackfest-2019Http3 fullstackfest-2019
Http3 fullstackfest-2019Daniel Stenberg
 
Git Graphs, Hashes, and Compression, Oh My
Git Graphs, Hashes, and Compression, Oh MyGit Graphs, Hashes, and Compression, Oh My
Git Graphs, Hashes, and Compression, Oh MyMatthew McCullough
 
Migrating from Subversion to Git and GitHub
Migrating from Subversion to Git and GitHubMigrating from Subversion to Git and GitHub
Migrating from Subversion to Git and GitHubMatthew McCullough
 

Tendances (20)

gRPC vs REST: let the battle begin!
gRPC vs REST: let the battle begin!gRPC vs REST: let the battle begin!
gRPC vs REST: let the battle begin!
 
DevNexus 2020 "Break me if you can: practical guide to building fault-toleran...
DevNexus 2020 "Break me if you can: practical guide to building fault-toleran...DevNexus 2020 "Break me if you can: practical guide to building fault-toleran...
DevNexus 2020 "Break me if you can: practical guide to building fault-toleran...
 
"gRPC vs REST: let the battle begin!" GeeCON Krakow 2018 edition
"gRPC vs REST: let the battle begin!" GeeCON Krakow 2018 edition"gRPC vs REST: let the battle begin!" GeeCON Krakow 2018 edition
"gRPC vs REST: let the battle begin!" GeeCON Krakow 2018 edition
 
"gRPC vs REST: let the battle begin!" DevoxxUK 2018 edition
"gRPC vs REST: let the battle begin!" DevoxxUK 2018 edition"gRPC vs REST: let the battle begin!" DevoxxUK 2018 edition
"gRPC vs REST: let the battle begin!" DevoxxUK 2018 edition
 
Devoxx Ukraine 2018 "Break me if you can: practical guide to building fault-t...
Devoxx Ukraine 2018 "Break me if you can: practical guide to building fault-t...Devoxx Ukraine 2018 "Break me if you can: practical guide to building fault-t...
Devoxx Ukraine 2018 "Break me if you can: practical guide to building fault-t...
 
REST API vs gRPC, which one should you use in breaking a monolith [Dev conf 2...
REST API vs gRPC, which one should you use in breaking a monolith [Dev conf 2...REST API vs gRPC, which one should you use in breaking a monolith [Dev conf 2...
REST API vs gRPC, which one should you use in breaking a monolith [Dev conf 2...
 
Curl with rust
Curl with rustCurl with rust
Curl with rust
 
HTTP/3 is next generation HTTP
HTTP/3 is next generation HTTPHTTP/3 is next generation HTTP
HTTP/3 is next generation HTTP
 
common mistakes when using libcurl
common mistakes when using libcurlcommon mistakes when using libcurl
common mistakes when using libcurl
 
JavaLand gRPC vs REST API
JavaLand gRPC vs REST APIJavaLand gRPC vs REST API
JavaLand gRPC vs REST API
 
REST API vs gRPC, which one should you use in breaking a monolith [Kdg.net 2018]
REST API vs gRPC, which one should you use in breaking a monolith [Kdg.net 2018]REST API vs gRPC, which one should you use in breaking a monolith [Kdg.net 2018]
REST API vs gRPC, which one should you use in breaking a monolith [Kdg.net 2018]
 
Build your next REST API with gRPC
Build your next REST API with gRPCBuild your next REST API with gRPC
Build your next REST API with gRPC
 
Dependency management in golang
Dependency management in golangDependency management in golang
Dependency management in golang
 
curl better
curl bettercurl better
curl better
 
HTTP/3 for everyone
HTTP/3 for everyoneHTTP/3 for everyone
HTTP/3 for everyone
 
Git and GitHub at the San Francisco JUG
 Git and GitHub at the San Francisco JUG Git and GitHub at the San Francisco JUG
Git and GitHub at the San Francisco JUG
 
Http3 fullstackfest-2019
Http3 fullstackfest-2019Http3 fullstackfest-2019
Http3 fullstackfest-2019
 
HTTP/3 in curl
HTTP/3 in curlHTTP/3 in curl
HTTP/3 in curl
 
Git Graphs, Hashes, and Compression, Oh My
Git Graphs, Hashes, and Compression, Oh MyGit Graphs, Hashes, and Compression, Oh My
Git Graphs, Hashes, and Compression, Oh My
 
Migrating from Subversion to Git and GitHub
Migrating from Subversion to Git and GitHubMigrating from Subversion to Git and GitHub
Migrating from Subversion to Git and GitHub
 

Similaire à "Enabling Googley microservices with gRPC" Riga DevDays 2018 edition

"Enabling Googley microservices with gRPC." at Devoxx France 2017
"Enabling Googley microservices with gRPC." at Devoxx France 2017"Enabling Googley microservices with gRPC." at Devoxx France 2017
"Enabling Googley microservices with gRPC." at Devoxx France 2017Alex Borysov
 
"Enabling Googley microservices with gRPC" at JDK.IO 2017
"Enabling Googley microservices with gRPC" at JDK.IO 2017"Enabling Googley microservices with gRPC" at JDK.IO 2017
"Enabling Googley microservices with gRPC" at JDK.IO 2017Alex Borysov
 
Usable APIs at Scale
Usable APIs at ScaleUsable APIs at Scale
Usable APIs at ScaleTim Burks
 
"Enabling Googley microservices with gRPC" at JEEConf 2017
"Enabling Googley microservices with gRPC" at JEEConf 2017"Enabling Googley microservices with gRPC" at JEEConf 2017
"Enabling Googley microservices with gRPC" at JEEConf 2017Alex Borysov
 
Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}
Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}
Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}Md. Sadhan Sarker
 
OGCE Overview for SciDAC 2009
OGCE Overview for SciDAC 2009OGCE Overview for SciDAC 2009
OGCE Overview for SciDAC 2009marpierc
 
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...apidays
 
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexusMicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexusEmily Jiang
 
Kubernetes GitOps featuring GitHub, Kustomize and ArgoCD
Kubernetes GitOps featuring GitHub, Kustomize and ArgoCDKubernetes GitOps featuring GitHub, Kustomize and ArgoCD
Kubernetes GitOps featuring GitHub, Kustomize and ArgoCDSunnyvale
 
GraalVM and MicroProfile - A Polyglot Microservices Solution
GraalVM and MicroProfile - A Polyglot Microservices SolutionGraalVM and MicroProfile - A Polyglot Microservices Solution
GraalVM and MicroProfile - A Polyglot Microservices SolutionRoberto Cortez
 
Manageable Data Pipelines With Airflow (and kubernetes) - GDG DevFest
Manageable Data Pipelines With Airflow (and kubernetes) - GDG DevFestManageable Data Pipelines With Airflow (and kubernetes) - GDG DevFest
Manageable Data Pipelines With Airflow (and kubernetes) - GDG DevFestJarek Potiuk
 
GDG Cloud Taipei meetup #50 - Build go kit microservices at kubernetes with ...
GDG Cloud Taipei meetup #50 - Build go kit microservices at kubernetes  with ...GDG Cloud Taipei meetup #50 - Build go kit microservices at kubernetes  with ...
GDG Cloud Taipei meetup #50 - Build go kit microservices at kubernetes with ...KAI CHU CHUNG
 
Scientific Computing @ Fred Hutch
Scientific Computing @ Fred HutchScientific Computing @ Fred Hutch
Scientific Computing @ Fred HutchDirk Petersen
 
Software Supply Chains for DevOps @ InfoQ Live 2021
Software Supply Chains for DevOps @ InfoQ Live 2021Software Supply Chains for DevOps @ InfoQ Live 2021
Software Supply Chains for DevOps @ InfoQ Live 2021Aysylu Greenberg
 
MongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB SoCal 2020: Migrate Anything* to MongoDB AtlasMongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB SoCal 2020: Migrate Anything* to MongoDB AtlasMongoDB
 
OGCE Project Overview
OGCE Project OverviewOGCE Project Overview
OGCE Project Overviewmarpierc
 
Cloud nativemicroservices jax-london2020
Cloud nativemicroservices   jax-london2020Cloud nativemicroservices   jax-london2020
Cloud nativemicroservices jax-london2020Emily Jiang
 
Cloud nativemicroservices jax-london2020
Cloud nativemicroservices   jax-london2020Cloud nativemicroservices   jax-london2020
Cloud nativemicroservices jax-london2020Emily Jiang
 
Groovy and Grails intro
Groovy and Grails introGroovy and Grails intro
Groovy and Grails introMiguel Pastor
 

Similaire à "Enabling Googley microservices with gRPC" Riga DevDays 2018 edition (20)

"Enabling Googley microservices with gRPC." at Devoxx France 2017
"Enabling Googley microservices with gRPC." at Devoxx France 2017"Enabling Googley microservices with gRPC." at Devoxx France 2017
"Enabling Googley microservices with gRPC." at Devoxx France 2017
 
"Enabling Googley microservices with gRPC" at JDK.IO 2017
"Enabling Googley microservices with gRPC" at JDK.IO 2017"Enabling Googley microservices with gRPC" at JDK.IO 2017
"Enabling Googley microservices with gRPC" at JDK.IO 2017
 
Usable APIs at Scale
Usable APIs at ScaleUsable APIs at Scale
Usable APIs at Scale
 
"Enabling Googley microservices with gRPC" at JEEConf 2017
"Enabling Googley microservices with gRPC" at JEEConf 2017"Enabling Googley microservices with gRPC" at JEEConf 2017
"Enabling Googley microservices with gRPC" at JEEConf 2017
 
Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}
Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}
Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}
 
OGCE Overview for SciDAC 2009
OGCE Overview for SciDAC 2009OGCE Overview for SciDAC 2009
OGCE Overview for SciDAC 2009
 
Grails 101
Grails 101Grails 101
Grails 101
 
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
 
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexusMicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
MicroProfile, Docker, Kubernetes, Istio and Open Shift lab @dev nexus
 
Kubernetes GitOps featuring GitHub, Kustomize and ArgoCD
Kubernetes GitOps featuring GitHub, Kustomize and ArgoCDKubernetes GitOps featuring GitHub, Kustomize and ArgoCD
Kubernetes GitOps featuring GitHub, Kustomize and ArgoCD
 
GraalVM and MicroProfile - A Polyglot Microservices Solution
GraalVM and MicroProfile - A Polyglot Microservices SolutionGraalVM and MicroProfile - A Polyglot Microservices Solution
GraalVM and MicroProfile - A Polyglot Microservices Solution
 
Manageable Data Pipelines With Airflow (and kubernetes) - GDG DevFest
Manageable Data Pipelines With Airflow (and kubernetes) - GDG DevFestManageable Data Pipelines With Airflow (and kubernetes) - GDG DevFest
Manageable Data Pipelines With Airflow (and kubernetes) - GDG DevFest
 
GDG Cloud Taipei meetup #50 - Build go kit microservices at kubernetes with ...
GDG Cloud Taipei meetup #50 - Build go kit microservices at kubernetes  with ...GDG Cloud Taipei meetup #50 - Build go kit microservices at kubernetes  with ...
GDG Cloud Taipei meetup #50 - Build go kit microservices at kubernetes with ...
 
Scientific Computing @ Fred Hutch
Scientific Computing @ Fred HutchScientific Computing @ Fred Hutch
Scientific Computing @ Fred Hutch
 
Software Supply Chains for DevOps @ InfoQ Live 2021
Software Supply Chains for DevOps @ InfoQ Live 2021Software Supply Chains for DevOps @ InfoQ Live 2021
Software Supply Chains for DevOps @ InfoQ Live 2021
 
MongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB SoCal 2020: Migrate Anything* to MongoDB AtlasMongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
 
OGCE Project Overview
OGCE Project OverviewOGCE Project Overview
OGCE Project Overview
 
Cloud nativemicroservices jax-london2020
Cloud nativemicroservices   jax-london2020Cloud nativemicroservices   jax-london2020
Cloud nativemicroservices jax-london2020
 
Cloud nativemicroservices jax-london2020
Cloud nativemicroservices   jax-london2020Cloud nativemicroservices   jax-london2020
Cloud nativemicroservices jax-london2020
 
Groovy and Grails intro
Groovy and Grails introGroovy and Grails intro
Groovy and Grails intro
 

Dernier

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 

Dernier (20)

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
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
  • 3. 3 devoxx.org.ua November 23-24, 2018 Kyiv, Ukraine Save the Date! #RigaDevDays @aiborisov #RigaDevDays @aiborisov
  • 4. Google Cloud Platform What is gRPC? #RigaDevDays @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
  • 7. Google Cloud Platform RPC?! But... #RigaDevDays @aiborisov AMF? RMI? CORBA?
  • 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
  • 12. Google Cloud Platform Google ~O(1010 ) QPS. #RigaDevDays @aiborisov
  • 13. Google Cloud Platform Google ~O(1010 ) QPS. Your project QPS? #RigaDevDays @aiborisov
  • 14. Google Cloud Platform Continuous Performance Benchmarking http://www.grpc.io/docs/guides/benchmarking.html #RigaDevDays @aiborisov 8 core VMs, unary throughput
  • 15. Google Cloud Platform Continuous Performance Benchmarking http://www.grpc.io/docs/guides/benchmarking.html #RigaDevDays @aiborisov 32 core VMs, unary throughput
  • 16. Google Cloud Platform • Single TCP connection. • No Head-of-line blocking. • Binary framing layer. • Header Compression. HTTP/2 in One Slide Transport(TCP) Application (HTTP/2) Network (IP) Session (TLS) [optional] Binary Framing HEADERS Frame DATA Frame HTTP/2 POST: /upload HTTP/1.1 Host: www.rigadevdays.lv Content-Type: application/json Content-Length: 27 HTTP/1.x {“msg”: “Welcome to 2018!”} #RigaDevDays @aiborisov
  • 17. Google Cloud Platform HTTP/1.x vs HTTP/2 http://www.http2demo.io/ https://http2.golang.org/gophertiles #RigaDevDays @aiborisov HTTP/1.1 HTTP/2
  • 18. Google Cloud Platform Okay, but how? #RigaDevDays @aiborisov
  • 19. Google Cloud Platform Service Definition (weather.proto) #RigaDevDays @aiborisov
  • 20. Google Cloud Platform Service Definition (weather.proto) syntax = "proto3"; option java_multiple_files = true; option java_package = "lv.rigadevdays.grpcexample"; package lv.rigadevdays.grpcexample; service WeatherService { rpc GetCurrent(WeatherRequest) returns (WeatherResponse); } #RigaDevDays @aiborisov
  • 21. Google Cloud Platform Service Definition (weather.proto) syntax = "proto3"; option java_multiple_files = true; option java_package = "lv.rigadevdays.grpcexample"; package lv.rigadevdays.grpcexample; service WeatherService { rpc GetCurrent(WeatherRequest) returns (WeatherResponse); } #RigaDevDays @aiborisov
  • 22. Google Cloud Platform Service Definition (weather.proto) syntax = "proto3"; service WeatherService { rpc GetCurrent(WeatherRequest) returns (WeatherResponse); } message WeatherRequest { Coordinates coordinates = 1; message Coordinates { fixed64 latitude = 1; fixed64 longitude = 2; } } message WeatherResponse { Temperature temperature = 1; Humidity humidity = 2; } message Temperature { float degrees = 1; Units units = 2; enum Units { FAHRENHEIT = 0; CELSIUS = 1; } } message Humidity { float value = 1; } #RigaDevDays @aiborisov
  • 23. Google Cloud Platform #RigaDevDays @aiborisov Service Definition weather.proto gRPC Runtime
  • 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
  • 35. Google Cloud Platform Non-Blocking API #RigaDevDays @aiborisov 1 2 3 . . . X + Y X . . .
  • 36. Google Cloud Platform Non-Blocking API (aka Hollywood Principle) #RigaDevDays @aiborisov 1 2 3 . . . X + Y X . . . WillCallYouLater!
  • 37. Google Cloud Platform Non-Blocking API #RigaDevDays @aiborisov 1 2 3 . . . X + Y X . . . onNext(1) WillCallYouLater!
  • 38. Google Cloud Platform Non-Blocking API #RigaDevDays @aiborisov 1 2 3 . . . X + Y X . . . onNext(3) WillCallYouLater!
  • 39. Google Cloud Platform Non-Blocking API #RigaDevDays @aiborisov 1 2 3 . . . X + Y X . . . onNext(X) WillCallYouLater!
  • 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
  • 43. Google Cloud Platform gRPC Clients ManagedChannel grpcChannel = NettyChannelBuilder.forAddress("localhost", 8090).build(); WeatherServiceStub client = WeatherServiceGrpc.newStub(grpcChannel); #RigaDevDays @aiborisov
  • 44. Google Cloud Platform gRPC Clients ManagedChannel grpcChannel = NettyChannelBuilder.forAddress("localhost", 8090).build(); WeatherServiceStub client = WeatherServiceGrpc.newStub(grpcChannel); WeatherServiceBlockingStub blockingClient = WeatherServiceGrpc.newBlockingStub(grpcChannel); WeatherServiceFutureStub futureClient = WeatherServiceGrpc.newFutureStub(grpcChannel); #RigaDevDays @aiborisov
  • 45. Google Cloud Platform gRPC Sync Client WeatherRequest request = WeatherRequest.newBuilder() .setCoordinates(Coordinates.newBuilder().setLatitude(420000000) .setLongitude(-720000000)).build(); WeatherResponse response = blockingClient.getCurrent(request); logger.info("Current weather for {}: {}", request, response); #RigaDevDays @aiborisov
  • 46. Google Cloud Platform gRPC Async Client WeatherRequest request = WeatherRequest.newBuilder() .setCoordinates(Coordinates.newBuilder().setLatitude(504316220) .setLongitude(305166450)).build(); client.getCurrent(request, new StreamObserver<WeatherResponse>() { @Override public void onNext(WeatherResponse response) { logger.info("Current weather for {}: {}", request, response); } @Override public void onError(Throwable t) { logger.info("Cannot get weather for {}", request); } @Override public void onCompleted() { logger.info("Stream completed."); } }); #RigaDevDays @aiborisov
  • 47. Google Cloud Platform Implement gRPC Service public class WeatherService extends WeatherServiceGrpc.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
  • 48. Google Cloud Platform Adding New [Micro]Services Weather Weather Temp Wind Humidity #RigaDevDays @aiborisov
  • 49. 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
  • 50. Google Cloud Platform Service Definition - Response Message message WeatherResponse { Temperature temperature = 1; float humidity = 2; } #RigaDevDays @aiborisov
  • 51. Google Cloud Platform Adding New Field message WeatherResponse { Temperature temperature = 1; float humidity = 2; Wind wind = 3; } message Wind { Speed speed = 1; float direction = 2; } message Speed { float value = 1; Units units = 2; enum Units { MPH = 0; MPS = 1; KNOTS = 2; KMH = 3; } } #RigaDevDays @aiborisov
  • 52. Google Cloud Platform private final TemperatureServiceBlockingStub temperatureService; private final HumidityServiceBlockingStub humidityService; private final WindServiceBlockingStub windService; public WeatherService(TemperatureServiceBlockingStub temperatureService, HumidityServiceBlockingStub humidityService, WindServiceBlockingStub windService) { this.temperatureService = temperatureService; this.humidityService = humidityService; this.windService = windService; } ... Blocking Stub Dependencies public class WeatherService extends WeatherServiceGrpc.WeatherServiceImplBase { #RigaDevDays @aiborisov
  • 53. Google Cloud Platform ... @Override public void getCurrent(WeatherRequest request, StreamObserver<WeatherResponse> responseObserver) { Temperature temperature = temperatureService.getCurrent(request.getCoordinates()); Humidity humidity = humidityService.getCurrent(request.getCoordinates()); Wind wind = windService.getCurrent(request.getCoordinates()); WeatherResponse response = WeatherResponse.newBuilder() .setTemperature(temperature).setHumidity(humidity).setWind(wind).build(); responseObserver.onNext(response); responseObserver.onCompleted(); } } Blocking Stub Dependencies public class WeatherService extends WeatherServiceGrpc.WeatherServiceImplBase { #RigaDevDays @aiborisov
  • 55. Google Cloud Platform private final TemperatureServiceFutureStub tempService; private final HumidityServiceFutureStub humidityService; private final WindServiceFutureStub windService; public WeatherService(TemperatureServiceFutureStub tempService, HumidityServiceFutureStub humidityService, WindServiceFutureStub windService) { this.tempService = tempService; this.humidityService = humidityService; this.windService = windService; } ... Async Future Stub Dependencies public class WeatherService extends WeatherServiceGrpc.WeatherServiceImplBase { #RigaDevDays @aiborisov
  • 56. Google Cloud Platform @Override public void getCurrent(WeatherRequest request, StreamObserver<WeatherResponse> responseObserver) { Coordinates coordinates = request.getCoordinates(); ListenableFuture<List<WeatherResponse>> responsesFuture = Futures.allAsList( Futures.transform(tempService.getCurrent(coordinates), (Temperature temp) -> WeatherResponse.newBuilder().setTemperature(temp).build()), Futures.transform(windService.getCurrent(coordinates), (Wind wind) -> WeatherResponse.newBuilder().setWind(wind).build()), Futures.transform(humidityService.getCurrent(coordinates), (Humidity humidity) -> WeatherResponse.newBuilder().setHumidity(humidity).build()) ); ... Async Future Stub Dependencies public class WeatherService extends WeatherServiceGrpc.WeatherServiceImplBase { #RigaDevDays @aiborisov
  • 57. Google Cloud Platform @Override public void getCurrent(WeatherRequest request, StreamObserver<WeatherResponse> responseObserver) { Coordinates coordinates = request.getCoordinates(); ListenableFuture<List<WeatherResponse>> responsesFuture = Futures.allAsList( Futures.transform(tempService.getCurrent(coordinates), (Temperature temp) -> WeatherResponse.newBuilder().setTemperature(temp).build()), Futures.transform(windService.getCurrent(coordinates), (Wind wind) -> WeatherResponse.newBuilder().setWind(wind).build()), Futures.transform(humidityService.getCurrent(coordinates), (Humidity humidity) -> WeatherResponse.newBuilder().setHumidity(humidity).build()) ); ... Async Future Stub Dependencies public class WeatherService extends WeatherServiceGrpc.WeatherServiceImplBase { #RigaDevDays @aiborisov
  • 58. Google Cloud Platform @Override public void getCurrent(WeatherRequest request, StreamObserver<WeatherResponse> responseObserver) { Coordinates coordinates = request.getCoordinates(); ListenableFuture<List<WeatherResponse>> responsesFuture = Futures.allAsList( Futures.transform(tempService.getCurrent(coordinates), (Temperature temp) -> WeatherResponse.newBuilder().setTemperature(temp).build()), Futures.transform(windService.getCurrent(coordinates), (Wind wind) -> WeatherResponse.newBuilder().setWind(wind).build()), Futures.transform(humidityService.getCurrent(coordinates), (Humidity humidity) -> WeatherResponse.newBuilder().setHumidity(humidity).build()) ); ... Async Future Stub Dependencies public class WeatherService extends WeatherServiceGrpc.WeatherServiceImplBase { #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
  • 75. Google Cloud Platform Continuous Performance Benchmarking http://www.grpc.io/docs/guides/benchmarking.html #RigaDevDays @aiborisov 32 core VMs, streaming throughput
  • 76. Google Cloud Platform Continuous Performance Benchmarking http://www.grpc.io/docs/guides/benchmarking.html #RigaDevDays @aiborisov 32 core VMs, streaming throughput
  • 77. Google Cloud Platform gRPC Speaks Your Language ● Java ● Go ● C/C++ ● C# ● Node.js ● PHP ● Ruby ● Python ● Objective-C ● JavaScript ● MacOS ● Linux ● Windows ● Android ● iOS Service definitions and client libraries Platforms supported #RigaDevDays @aiborisov
  • 80. Google Cloud Platform Use time-outs! And it will be fine. “ ” #RigaDevDays @aiborisov
  • 81. Google Cloud Platform Timeouts? GW A1 A2 A3 B1 B2 B3 C1 C2 C3 200 ms ? ? ? ? ? ? ? ? ? #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?
  • 95. Google Cloud Platform Timeouts? GW A1 A2 A3 B1 B2 B3 C1 C2 C3 200 ms ? ? ? ? ? ? ? ? ? #RigaDevDays @aiborisov
  • 96. Google Cloud Platform Timeouts for Real World? GW A1 A2 A3 B1 B2 B3 C1 C2 C3 200 ms #RigaDevDays @aiborisov
  • 97. Google Cloud Platform Timeouts for Real World? GW A1 A2 A3 B1 B2 B3 C1 C2 C3 200 ms 2,500 ms 140 ms #RigaDevDays @aiborisov
  • 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
  • 107. Google Cloud Platform Cancellation Propagation GW Idle Idle Idle Idle Idle Idle Idle Idle Idle #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
  • 111. Google Cloud Platform More Control? #RigaDevDays @aiborisov
  • 112. Google Cloud Platform BiDi Streaming - Slow Client Fast Server Request Responses Slow Client CANCELLED UNAVAILABLE RESOURCE_EXHAUSTED #RigaDevDays @aiborisov
  • 113. Google Cloud Platform BiDi Streaming - Slow Server Slow Server Request Response Fast Client CANCELLED UNAVAILABLE RESOURCE_EXHAUSTED Requests #RigaDevDays @aiborisov
  • 114. Google Cloud Platform Client-Side Flow-Control Server Request, count = 4 Client 2 Responses 4 Responses Count = 2 #RigaDevDays @aiborisov
  • 115. Google Cloud Platform Server-Side Flow-Control Server Request Client Response count = 2 2 Requests count = 3 3 Requests #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
  • 123. Google Cloud Platform What else? #RigaDevDays @aiborisov
  • 124. Google Cloud Platform Microservices?! But... #JokerConf @aiborisov Performance Hit? Service Discovery? Load Balancing? Fault Tolerance? Monitoring? Tracing? Testing?
  • 125. Google Cloud Platform Service Discovery & Load Balancing HTTP/2 RPC Server-side App Service Definition (extends generated definition) ServerCall handler TransportTransport ServerCall RPC Client-Side App Channel Stub Future Stub Blocking Stub ClientCall #RigaDevDays @aiborisov
  • 126. Google Cloud Platform HTTP/2 Service Discovery & Load Balancing RPC Client-Side App Instance #1 Instance #N Instance #2 RPC Server-side Apps Transport Channel Stub Future Stub Blocking Stub ClientCall #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
  • 136. Google Cloud Platform Growing Community and Ecosystem Your company could be here #RigaDevDays @aiborisov
  • 137. Google Cloud Platform Try It Out! http://grpc.io gRPC on Github: https://github.com/grpc Demo: https://github.com/alxbnet/rigadevdays-grpc-demo Google group: grpc-io@googlegroups.com gRPC Java quickstart: http://www.grpc.io/docs/quickstart/java.html gRPC Java tutorial: http://www.grpc.io/docs/tutorials/basic/java.html gRPC contribution: https://github.com/grpc/grpc-contrib #RigaDevDays @aiborisov
  • 138. Google Cloud Platform Takeaways gRPC (http://grpc.io): • HTTP/2 transport based, open source, general purpose standards-based, feature-rich RPC framework. • Bidirectional streaming over one single TCP connection. • Netty transport provides asynchronous and non-blocking I/O. • Deadline and cancellations propagation. • Client and server-side flow-control. • Pluggable service discovery and load-balancing • Generated client libraries • Supports 10+ programming languages. • Build-in testing support. • Production-ready and growing ecosystem. #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