Successfully reported this slideshow.
Your SlideShare is downloading. ×

gRPC vs REST: let the battle begin!

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 188 Ad
Advertisement

More Related Content

Slideshows for you (20)

Similar to gRPC vs REST: let the battle begin! (20)

Advertisement

Recently uploaded (20)

gRPC vs REST: let the battle begin!

  1. 1. gRPC vs REST: let the battle begin! Devoxx, November 9, 2017 Alex Borysov, Software Engineer @ Google Mykyta Protsenko, Software Engineer @ Roku
  2. 2. Who are we? Mykyta Protsenko Software Engineer @ Roku • passionate about all things scalable • 18+ years in software engineering • Author of Henka REST vs gRPC Alex Borysov Software Engineer @ Google • large scale systems developer • 11+ years in software engineering • Active gRPC user REST vs gRPC @aiborisov @mykyta_p
  3. 3. @aiborisov @mykyta_p @aiborisov @mykyta_p
  4. 4. JSON over HTTP @aiborisov @mykyta_p
  5. 5. I am getting frustrated by the number of people calling any HTTP-based interface a REST API. Roy Fielding http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven @aiborisov @mykyta_p
  6. 6. @aiborisov @mykyta_p
  7. 7. @aiborisov @mykyta_p
  8. 8. RESTful API GET /user/15 { “name”: “John Doe”, “email”:“john.doe@gmail.com”, ... } non-RESTful API GET /last_search?page=2 { “products”: [...] ... } @aiborisov @mykyta_p
  9. 9. What is gRPC? @aiborisov @mykyta_p
  10. 10. What is gRPC? gRPC stands for gRPC Remote Procedure Calls. A high performance, general purpose, feature-rich RPC framework. Part of Cloud Native Computing Foundation cncf.io HTTP/2 and mobile first. Open sourced version of Stubby RPC used in Google. @aiborisov @mykyta_p
  11. 11. RPC?! But... AMF? RMI? CORBA? @aiborisov @mykyta_p
  12. 12. gRPC is not RMI Maitainability Ease of use Performance Scalability L e s s o n s Years of using Stubby @aiborisov @mykyta_p
  13. 13. What is gRPC? Abstractions and best practices on how to design RPCs. Default implementation(s) from Google. Extension points to plug custom implementations and modifications. Supports 10+ programming languages. @aiborisov @mykyta_p
  14. 14. gRPC 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 @aiborisov @mykyta_p
  15. 15. Apples to Oranges? @aiborisov @mykyta_p
  16. 16. Microservices? @aiborisov @mykyta_p
  17. 17. Microservices? How to draw an owl? @aiborisov @mykyta_p
  18. 18. Microservices? How to draw an owl? How to build microservices? @aiborisov @mykyta_p
  19. 19. Microservices? How to draw an owl? How to build microservices? Draw some circles. @aiborisov @mykyta_p
  20. 20. Microservices? How to draw an owl? How to build microservices? Draw some circles. Take XYZ framework. @aiborisov @mykyta_p
  21. 21. Microservices? How to draw an owl? How to build microservices? Draw the REST of the owlDraw some circles. Take XYZ framework. @aiborisov @mykyta_p
  22. 22. Microservices? How to draw an owl? How to build microservices? Draw the REST of the owl Write your microservices! Draw some circles. Take XYZ framework. @aiborisov @mykyta_p
  23. 23. Microservices @aiborisov @mykyta_p
  24. 24. Microservices @aiborisov @mykyta_p
  25. 25. Microservices @aiborisov @mykyta_p
  26. 26. Microservices @aiborisov @mykyta_p
  27. 27. Remote Calls @aiborisov @mykyta_p
  28. 28. Call Flow @aiborisov @mykyta_p
  29. 29. Service Discovery? ? ? ? ? ? ? @aiborisov @mykyta_p
  30. 30. Multiple Instances #1 #N #2 . . . @aiborisov @mykyta_p
  31. 31. Multiple Instances #1 #N #2 ? ? ? . . . @aiborisov @mykyta_p
  32. 32. Call Flow @aiborisov @mykyta_p
  33. 33. Call Flow @aiborisov @mykyta_p
  34. 34. Call Flow @aiborisov @mykyta_p
  35. 35. Call Flow @aiborisov @mykyta_p
  36. 36. Call Flow @aiborisov @mykyta_p
  37. 37. Slow Services? @aiborisov @mykyta_p
  38. 38. Failure Scenarios @aiborisov @mykyta_p
  39. 39. A distributed system is one in which the failure of a computer you didn't even know existed can render your own computer unusable. Leslie Lamport, 1987 https://www.microsoft.com/en-us/research/wp-content/uploads/2016/12/Distribution.pdf @aiborisov @mykyta_p
  40. 40. Fault Tolerance @aiborisov @mykyta_p
  41. 41. Microservices?! But... Performance Hit? Service Discovery? Load Balancing? Fault Tolerance? Monitoring? Testing? @aiborisov @mykyta_p
  42. 42. Sample Problem Client @aiborisov @mykyta_p
  43. 43. Sample Problem: Aggregator Src #2 Src #1 Aggr ... Src #X Client @aiborisov @mykyta_p
  44. 44. Heterogeneous Data Format Src #2 Src #1 Aggr ... Src #X <XML>...<XML> {JSON} Binary 110011 [ Unified Format ] Client @aiborisov @mykyta_p
  45. 45. REST: It’s All About Resources @aiborisov @mykyta_p
  46. 46. REST: Call Hierarchy Controller Service Data Source A . . . Data Source N RestTemplate RestTemplate RestTemplate @aiborisov @mykyta_p
  47. 47. REST: Data Source JSON URL: http://bgdata.com/content/11 { "id": 11, "content": "Flink" } XML URL: http://pokemon.com/content/22 <ContentResponse> <id>22</id> <content>Pikachu</content> </ContentResponse> @aiborisov @mykyta_p
  48. 48. REST: Data Source ... ResponseEntity<Content> contentEntity = restTemplate.getForEntity( url + "{content_id}" Content.class, ImmutableMap.of("content_id", contentId)); ... @aiborisov @mykyta_p
  49. 49. REST: Service public class AggregatingService { public AggregatedContent fetch(int id) { ... return new AggregatedContent(...); } } public class AggregatedContent { private Integer id; private String type; private String content; private Integer nextId; @aiborisov @mykyta_p
  50. 50. REST: Service public class AggregatingService { public AggregatedContent fetch(int id) { ... return new AggregatedContent(...); } } public class AggregatedContent { private Integer id; private String type; private String content; private Integer nextId; @aiborisov @mykyta_p
  51. 51. REST: Service public class AggregatingService { public AggregatedContent fetch(int id) { ... return new AggregatedContent(...); } } public class AggregatedContent { private Integer id; // 115 private String type; // BigData private String content; // Flink private Integer nextId; // 116 @aiborisov @mykyta_p
  52. 52. REST: Service public class AggregatingService { public AggregatedContent fetch(int id) { ... return new AggregatedContent(...); } } public class AggregatedContent { private Integer id; // 115 private String type; // BigData private String content; // Flink private Integer nextId; // 116 @aiborisov @mykyta_p
  53. 53. REST: Controller @GetMapping( value = "/content/{id}", produces = "application/json") public AggregatedContent aggregated(@PathVariable("id") int id) { return aggregatingService.fetch(id); } @aiborisov @mykyta_p
  54. 54. REST: It’s All About Resources @GetMapping( value = "/content/{id}", produces = "application/json") public AggregatedContent aggregated(@PathVariable("id") int id) { return aggregatingService.fetch(id); } @aiborisov @mykyta_p
  55. 55. REST: It’s simple http://localhost:8080/content/115 { "id": 115, "content_type": "POKEMON", "content": "Pikachu", "next_uri": "/content/116" } @aiborisov @mykyta_p
  56. 56. REST: Service Discovery @aiborisov @mykyta_p
  57. 57. k8s/bigdata.yaml ... kind: Service metadata: name: rest-bigdata-content-service k8s/aggregator.yaml ... env: - name: datasource_a_url value: "http://rest-bigdata-content-service:8080" REST: Service Discovery @aiborisov @mykyta_p
  58. 58. k8s/bigdata.yaml ... kind: Service metadata: name: rest-bigdata-content-service k8s/aggregator.yaml ... env: - name: datasource_a_url value: "http://rest-bigdata-content-service:8080" REST: Service Discovery @aiborisov @mykyta_p
  59. 59. Controllers and POJOs, oh my! public class AggregatedContent { @JsonProperty("id") private Integer id; @JsonProperty("type") private String type; @JsonProperty("content") private String content; @JsonProperty("next_uri") private String nextUri; ... } { "id": 115, "content_type": "BigData", "content": "Flink", "next_uri": "/content/116" } @aiborisov @mykyta_p
  60. 60. gRPC: It’s All About APIs @aiborisov @mykyta_p
  61. 61. Sample Problem: Aggregator Src #2 Src #1 Aggr ... Src #X Client @aiborisov @mykyta_p
  62. 62. Service Definition (aggregator.proto) @aiborisov @mykyta_p
  63. 63. Service Definition (aggregator.proto) syntax = "proto3"; service AggregationService { rpc Get(AggregationRequest) returns (AggregationResponse); } @aiborisov @mykyta_p
  64. 64. Service Definition (aggregator.proto) syntax = "proto3"; service AggregationService { rpc Get(AggregationRequest) returns (AggregationResponse); } message AggregationRequest { int32 item_id = 1; } message AggregationResponse { int32 id = 1; ResponseType type = 2; string content = 3; int32 next_item_id = 4; } enum ResponseType { UNDEFINED = 0; POKEMON = 1; BIGDATA = 2; } @aiborisov @mykyta_p
  65. 65. Service Definition aggregator.proto @aiborisov @mykyta_p
  66. 66. Service Definition aggregator.proto gRPC Runtime @aiborisov @mykyta_p
  67. 67. Service Definition aggregator.proto AggregationServiceImplBase.java AggregationRequest.java AggregationResponse.java AggregationServiceStub.java AggregationServiceFutureStub.java AggregationServiceBlockingStub.java Service Implementation Request and response Client libraries gRPC Java runtime @aiborisov @mykyta_p
  68. 68. Implement gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void get(AggregationRequest request, StreamObserver<AggregationResponse> responseObserver) { } } @aiborisov @mykyta_p
  69. 69. Implement gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void get(AggregationRequest request, StreamObserver<AggregationResponse> responseObserver) { } }
  70. 70. Implement gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void get(AggregationRequest request, StreamObserver<AggregationResponse> responseObserver) { } } @aiborisov @mykyta_p
  71. 71. Thread #X Thread ... Thread #7 Thread #6 Thread #5 Thread #4 Blocking API (aka Thread-per-Request)? Thread #3 Thread #2 Thread #1 Thread pool of size X @aiborisov @mykyta_p
  72. 72. Thread #X Thread ... Thread #7 Thread #6 Thread #5 Thread #4 Blocking API (aka Thread-per-Request)? Thread #3 Thread #2 Thread #1 Thread pool of size X 1 @aiborisov @mykyta_p
  73. 73. Thread #X Thread ... Thread #7 Thread #6 Thread #5 Thread #4 Blocking API (aka Thread-per-Request)? Thread #3 Thread #2 Thread #1 Thread pool of size X 1 2 @aiborisov @mykyta_p
  74. 74. Thread #X Thread ... Thread #7 Thread #6 Thread #5 Thread #4 Blocking API (aka Thread-per-Request)? Thread #3 Thread #2 Thread #1 Thread pool of size X 1 2 3 @aiborisov @mykyta_p
  75. 75. Thread #X Thread ... Thread #7 Thread #6 Thread #5 Thread #4 Thread #3 Thread #2 Blocking API (aka Thread-per-Request)? Thread #1 Thread pool of size X 1 2 3 X . . . @aiborisov @mykyta_p
  76. 76. Thread #X Thread ... Thread #7 Thread #6 Thread #5 Thread #4 Thread #3 Thread #2 Blocking API (aka Thread-per-Request)? Thread #1 Thread pool of size X 1 2 3 X . . . X + 1 @aiborisov @mykyta_p
  77. 77. Thread #X Thread ... Thread #7 Thread #6 Thread #5 Thread #4 Thread #3 Thread #2 Blocking API (aka Thread-per-Request)? Thread #1 Thread pool of size X 1 2 3 X . . . X + 1 @aiborisov @mykyta_p
  78. 78. Implement gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void get(AggregationRequest request, StreamObserver<AggregationResponse> responseObserver) { } } @aiborisov @mykyta_p
  79. 79. Implement gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void get(AggregationRequest request, public interface StreamObserver<AggregationResponse> responseObserver){{ void onNext(AggregationResponse response); void onCompleted(); void onError(Throwable error); } } } @aiborisov @mykyta_p
  80. 80. Non-Blocking API 1 2 3 . . . X + Y X . . . @aiborisov @mykyta_p
  81. 81. Non-Blocking API (aka Hollywood Principle) 1 2 3 . . . X + Y X . . . WillCallYouLater! @aiborisov @mykyta_p
  82. 82. Non-Blocking API (aka Hollywood Principle) 1 2 3 . . . X + Y X . . . WillCallYouLater! onNext(1) @aiborisov @mykyta_p
  83. 83. Non-Blocking API (aka Hollywood Principle) 1 2 3 . . . X + Y X . . . WillCallYouLater! onNext(3) @aiborisov @mykyta_p
  84. 84. Non-Blocking API (aka Hollywood Principle) 1 2 3 . . . X + Y X . . . WillCallYouLater! onNext(X) @aiborisov @mykyta_p
  85. 85. Implement gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void get(AggregationRequest request, StreamObserver<AggregationResponse> responseObserver) { AggregationResponse response = AggregationResponse .newBuilder() .setId(request.getItemId()) .setContent("Pikachu") .setType(ResponseType.POKEMON) .build(); responseObserver.onNext(response); responseObserver.onCompleted(); } } @aiborisov @mykyta_p
  86. 86. Implement gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void get(AggregationRequest request, StreamObserver<AggregationResponse> responseObserver) { AggregationResponse response = AggregationResponse .newBuilder() .setId(request.getItemId()) .setContent("Pikachu") .setType(ResponseType.POKEMON) .build(); responseObserver.onNext(response); responseObserver.onCompleted(); } } @aiborisov @mykyta_p
  87. 87. Service Definition (aggregator.proto) syntax = "proto3"; service AggregationService { rpc Get(AggregationRequest) returns (AggregationResponse); } message AggregationRequest { int32 item_id = 1; } message AggregationResponse { int32 id = 1; ResponseType type = 2; string content = 3; int32 next_item_id = 4; } enum ResponseType { UNDEFINED = 0; POKEMON = 1; BIGDATA = 2; } @aiborisov @mykyta_p
  88. 88. Service Definition (aggregator.proto) syntax = "proto3"; service AggregationService { rpc Get(AggregationRequest) returns (AggregationResponse); } message AggregationRequest { } message AggregationResponse { int32 id = 1; ResponseType type = 2; string content = 3; } enum ResponseType { UNDEFINED = 0; POKEMON = 1; BIGDATA = 2; } @aiborisov @mykyta_p
  89. 89. Service Definition (aggregator.proto) syntax = "proto3"; service AggregationService { rpc Get(AggregationRequest) returns (AggregationResponse); } message AggregationRequest { } message AggregationResponse { int32 id = 1; ResponseType type = 2; string content = 3; } enum ResponseType { UNDEFINED = 0; POKEMON = 1; BIGDATA = 2; } @aiborisov @mykyta_p
  90. 90. Service Definition (aggregator.proto) syntax = "proto3"; service AggregationService { rpc Get(AggregationRequest) returns (stream AggregationResponse); } message AggregationRequest { } message AggregationResponse { int32 id = 1; ResponseType type = 2; string content = 3; } enum ResponseType { UNDEFINED = 0; POKEMON = 1; BIGDATA = 2; } @aiborisov @mykyta_p
  91. 91. Service Definition (aggregator.proto) syntax = "proto3"; service AggregationService { rpc Subscribe(AggregationRequest) returns (stream AggregationResponse); } message AggregationRequest { } message AggregationResponse { int32 id = 1; ResponseType type = 2; string content = 3; } enum ResponseType { UNDEFINED = 0; POKEMON = 1; BIGDATA = 2; } @aiborisov @mykyta_p
  92. 92. Service Definition (aggregator.proto) syntax = "proto3"; service AggregationService { rpc Subscribe(AggregationRequest) returns (stream AggregationResponse); } message AggregationRequest { } message AggregationResponse { int32 id = 1; ResponseType type = 2; string content = 3; } enum ResponseType { UNDEFINED = 0; POKEMON = 1; BIGDATA = 2; } @aiborisov @mykyta_p
  93. 93. Sample Problem: Aggregator Src #2 Src #1 Aggr ... Src #X Client aggregator.proto @aiborisov @mykyta_p
  94. 94. Sample Problem: Content Src #2 Src #1 Aggr ... Src #X Client aggregator.proto content.proto @aiborisov @mykyta_p
  95. 95. content.proto syntax = "proto3"; service ContentService { rpc Subscribe(ContentRequest) returns (stream ContentResponse); } message ContentRequest { } message ContentResponse { int32 id = 1; string content = 2; } @aiborisov @mykyta_p
  96. 96. Streaming gRPC Service public class AggregationService extends AggregationServiceImplBase { private final Collection<ContentServiceStub> contentStubs; public AggregationService(Collection<ContentServiceStub> contentStubs) { this.contentStubs = contentStubs; } ... @aiborisov @mykyta_p
  97. 97. Streaming gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void subscribe(AggregationRequest request,StreamObserver<AggregationResponse> responseObserver) { contentStubs.forEach(stub -> { stub.subscribe(ContentRequest.getDefaultInstance(), new StreamObserver<ContentResponse>() { @Override public void onNext(ContentResponse response) { ... } @Override public void onError(Throwable error) { responseObserver.onError(error); } @Override public void onCompleted() {} }); }); } @aiborisov @mykyta_p
  98. 98. Streaming gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void subscribe(AggregationRequest request,StreamObserver<AggregationResponse> responseObserver) { contentStubs.forEach(stub -> { stub.subscribe(ContentRequest.getDefaultInstance(), new StreamObserver<ContentResponse>() { @Override public void onNext(ContentResponse response) { ... } @Override public void onError(Throwable error) { responseObserver.onError(error); } @Override public void onCompleted() {} }); }); } @aiborisov @mykyta_p
  99. 99. Streaming gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void subscribe(AggregationRequest request,StreamObserver<AggregationResponse> responseObserver) { contentStubs.forEach(stub -> { stub.subscribe(ContentRequest.getDefaultInstance(), new StreamObserver<ContentResponse>() { @Override public void onNext(ContentResponse response) { ... } @Override public void onError(Throwable error) { responseObserver.onError(error); } @Override public void onCompleted() {} }); }); } @aiborisov @mykyta_p
  100. 100. Streaming gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void subscribe(AggregationRequest request,StreamObserver<AggregationResponse> responseObserver) { contentStubs.forEach(stub -> { stub.subscribe(ContentRequest.getDefaultInstance(), new StreamObserver<ContentResponse>() { @Override public void onNext(ContentResponse response) { ... } @Override public void onError(Throwable error) { responseObserver.onError(error); } @Override public void onCompleted() {} }); }); } @aiborisov @mykyta_p
  101. 101. Streaming gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void subscribe(AggregationRequest request,StreamObserver<AggregationResponse> responseObserver) { contentStubs.forEach(stub -> { stub.subscribe(ContentRequest.getDefaultInstance(), new StreamObserver<ContentResponse>() { @Override public void onNext(ContentResponse response) { ResponseType type = typeForStub(stub); int aggregationId = aggregationId(response.getId(), type); AggregationResponse aggrResponse = AggregationResponse.newBuilder() .setContent(response.getContent()).setId(aggregationId). .setType(type).build(); responseObserver.onNext(aggrResponse); } }); }); } @aiborisov @mykyta_p
  102. 102. Streaming gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void subscribe(AggregationRequest request,StreamObserver<AggregationResponse> responseObserver) { contentStubs.forEach(stub -> { stub.subscribe(ContentRequest.getDefaultInstance(), new StreamObserver<ContentResponse>() { @Override public void onNext(ContentResponse response) { ResponseType type = typeForStub(stub); int aggregationId = aggregationId(response.getId(), type); AggregationResponse aggrResponse = AggregationResponse.newBuilder() .setContent(response.getContent()).setId(aggregationId). .setType(type).build(); responseObserver.onNext(aggrResponse); } }); }); } @aiborisov @mykyta_p
  103. 103. Streaming gRPC Service Src #2 Src #1 Aggr ... Src #X Client @aiborisov @mykyta_p
  104. 104. Streaming gRPC Service Src #2 Src #1 Aggr ... Src #X Client Subscribe() @aiborisov @mykyta_p
  105. 105. Streaming gRPC Service Src #2 Src #1 Aggr ... Src #X Client Subscribe() Subscribe() Subscribe() Subscribe() @aiborisov @mykyta_p
  106. 106. Streaming gRPC Service Src #2 Src #1 Aggr ... Src #X Client onNext() @aiborisov @mykyta_p
  107. 107. Streaming gRPC Service Src #2 Src #1 Aggr ... Src #X Client onNext() onNext() @aiborisov @mykyta_p
  108. 108. Streaming gRPC Service Src #2 Src #1 Aggr ... Src #X Client onNext() @aiborisov @mykyta_p
  109. 109. Streaming gRPC Service Src #2 Src #1 Aggr ... Src #X Client onNext() onNext() @aiborisov @mykyta_p
  110. 110. Start gRPC Server ContentServiceStub pokemonClient = ... ContentServiceStub bigDataClient = ... Server grpcServer = NettyServerBuilder.forPort(8080) .addService(new AggregationService(asList(pokemonClient, bigDataClient))) .build().start(); @aiborisov @mykyta_p
  111. 111. Start gRPC Server ContentServiceStub pokemonClient = ... ContentServiceStub bigDataClient = ... Server grpcServer = NettyServerBuilder.forPort(8080) .addService(new AggregationService(asList(pokemonClient, bigDataClient))) .build().start(); @aiborisov @mykyta_p
  112. 112. Create gRPC Client String host = System.getenv("pokemon_host"); int post = Integer.valueOf(System.getenv("pokemon_port")); ManagedChannel pokemonChannel = NettyChannelBuilder.forAddress(host, port).build(); @aiborisov @mykyta_p
  113. 113. Create gRPC Client String host = System.getenv("pokemon_host"); int post = Integer.valueOf(System.getenv("pokemon_port")); ManagedChannel pokemonChannel = NettyChannelBuilder.forAddress(host, port).build(); ContentServiceStub pokemonClient = ContentServiceGrpc.newStub(pokemonChannel); @aiborisov @mykyta_p
  114. 114. Create gRPC Client String host = System.getenv("pokemon_host"); int port = Integer.valueOf(System.getenv("pokemon_port")); ManagedChannel pokemonChannel = NettyChannelBuilder.forAddress(host, port).build(); ContentServiceStub pokemonClient = ContentServiceGrpc.newStub(pokemonChannel); ContentServiceBlockingStub pokemonBlockingClient = ContentServiceGrpc.newBlockingStub(pokemonChannel); @aiborisov @mykyta_p
  115. 115. Create gRPC Client String host = System.getenv("pokemon_host"); int port = Integer.valueOf(System.getenv("pokemon_port")); ManagedChannel pokemonChannel = NettyChannelBuilder.forAddress(host, port).build(); ContentServiceStub pokemonClient = ContentServiceGrpc.newStub(pokemonChannel); ContentServiceBlockingStub pokemonBlockingClient = ContentServiceGrpc.newBlockingStub(pokemonChannel); ContentServiceFutureStub pokemonFutureClient = ContentServiceGrpc.newFutureStub(pokemonChannel); @aiborisov @mykyta_p
  116. 116. Service Discovery & Load Balancing String host = System.getenv("pokemon_host"); int post = Integer.valueOf(System.getenv("pokemon_port")); ManagedChannel pokemonChannel = NettyChannelBuilder.forAddress(host, port).build(); @aiborisov @mykyta_p
  117. 117. Service Discovery & Load Balancing ManagedChannel pokemonChannel = NettyChannelBuilder.forAddress(host, port).build(); @aiborisov @mykyta_p
  118. 118. Service Discovery & Load Balancing ManagedChannel pokemonChannel = NettyChannelBuilder.forTarget("pokemon") .build(); @aiborisov @mykyta_p
  119. 119. Service Discovery & Load Balancing ManagedChannel pokemonChannel = NettyChannelBuilder.forTarget("pokemon") .nameResolverFactory(new DnsNameResolverProvider()) .loadBalancerFactory(RoundRobinLoadBalancerFactory.getInstance()) .build(); @aiborisov @mykyta_p
  120. 120. Service Discovery & Load Balancing ManagedChannel pokemonChannel = NettyChannelBuilder.forTarget("pokemon") .nameResolverFactory(new MyCustomNameResolverProviderFactory()) .loadBalancerFactory(new MyMoonPhaseLoadBalancerFactory()) .build(); @aiborisov @mykyta_p
  121. 121. Netty ManagedChannel pokemonChannel = NettyChannelBuilder.forTarget("pokemon") .nameResolverFactory(new MyCustomNameResolverProvider()) .loadBalancerFactory(new MyMoonPhaseLoadBalancerFactory()) .build(); @aiborisov @mykyta_p
  122. 122. Netty + HTTP/2 + Protobuf @aiborisov @mykyta_p
  123. 123. Netty + HTTP/2 + Protobuf = Performance http://www.grpc.io/docs/guides/benchmarking.html @aiborisov @mykyta_p 8 core VMs, streaming throughput
  124. 124. Netty + HTTP/2 + Protobuf = Performance http://www.grpc.io/docs/guides/benchmarking.html @aiborisov @mykyta_p 32 core VMs, streaming throughput
  125. 125. Client Latency ... 900 ms! @aiborisov @mykyta_p
  126. 126. Caching CDN 9 ms ... @aiborisov @mykyta_p
  127. 127. pay 24/7 Classic Cloud VM VM LB ... VM pay as you go @aiborisov @mykyta_p
  128. 128. Serverless pay as you go Func Funcinput ... Func input ... input @aiborisov @mykyta_p
  129. 129. All about resources IDL optional Synchronous by default Unary Perfect fit for serverless All about APIs IDL centric Asynchronous by nature Streaming or Unary Performance first REST gRPC @aiborisov @mykyta_p
  130. 130. Sample Problem Src #2 Src #1 ... Src #X Client Aggr @aiborisov @mykyta_p
  131. 131. Sample Problem: Voting Src #2 Src #1 ... Src #X Client Voting Aggr @aiborisov @mykyta_p
  132. 132. Sample Problem: Voting Src #2 Src #1 ... Src #X Client Voting Aggr @aiborisov @mykyta_p
  133. 133. Sample Problem: Voting Src #2 Src #1 ... Src #X Client Voting Aggr @aiborisov @mykyta_p
  134. 134. Sample Problem: Voting & Leaderboard Src #2 Src #1 ... Src #X Client Voting Aggr L-board @aiborisov @mykyta_p
  135. 135. Sample Problem: Voting & Leaderboard Src #2 Src #1 ... Src #X Client Voting Aggr L-board @aiborisov @mykyta_p
  136. 136. Sample Problem: Voting & Leaderboard Src #2 Src #1 ... Src #X Gateway Voting Aggr L-board @aiborisov @mykyta_p
  137. 137. Sample Problem Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  138. 138. Failing Leaderboard Src #2 Src #1 ... Src #X Gateway Voting Aggr @aiborisov @mykyta_p
  139. 139. Cascading Failure Src #2 Src #1 ... Src #X Gateway Voting Aggr @aiborisov @mykyta_p
  140. 140. Cascading Failure Src #2 Src #1 ... Src #X Gateway Voting Aggr @aiborisov @mykyta_p
  141. 141. Cascading Failure Src #2 Src #1 ... Src #X Gateway Voting Aggr @aiborisov @mykyta_p
  142. 142. Circuit Breaker Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  143. 143. Circuit Breaker Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  144. 144. Circuit Breaker Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  145. 145. Circuit Breaker Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  146. 146. Circuit Breaker Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  147. 147. Circuit Breaker Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  148. 148. Slow Services Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  149. 149. Timeouts? Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr 200 ms 2 sec @aiborisov @mykyta_p
  150. 150. Large Timeouts Gateway Voting L-Board 1,000 ms timeout 1,000 ms timeout 200 ms client timeout @aiborisov @mykyta_p
  151. 151. Large Timeouts Gateway Voting L-Board 1,000 ms timeout 1,000 ms timeout 200 ms client timeout 50 ms @aiborisov @mykyta_p
  152. 152. Large Timeouts Gateway Voting L-Board 1,000 ms timeout 1,000 ms timeout 200 ms client timeout 50 ms 400 ms @aiborisov @mykyta_p
  153. 153. Large Timeouts Gateway Voting L-Board 1,000 ms timeout 1,000 ms timeout 200 ms client timeout 50 ms 400 ms @aiborisov @mykyta_p
  154. 154. Large Timeouts Gateway Voting L-Board 1,000 ms timeout 1,000 ms timeout 200 ms client timeout 50 ms 400 ms 300 ms @aiborisov @mykyta_p
  155. 155. Short Timeouts Gateway Voting L-Board 100 ms timeout 100 ms timeout @aiborisov @mykyta_p
  156. 156. Short Timeouts Gateway Voting L-Board 100 ms timeout 100 ms timeout 2,000 ms client timeout @aiborisov @mykyta_p
  157. 157. Short Timeouts Gateway Voting L-Board 100 ms timeout 100 ms timeout 2,000 ms client timeout 50 ms @aiborisov @mykyta_p
  158. 158. Short Timeouts Gateway Voting L-Board 100 ms timeout 100 ms timeout 2,000 ms client timeout 50 ms 400 ms @aiborisov @mykyta_p
  159. 159. Short Timeouts Gateway Voting L-Board 100 ms timeout 100 ms timeout 2,000 ms client timeout 50 ms 400 ms @aiborisov @mykyta_p
  160. 160. Short Timeouts Gateway Voting L-Board 100 ms timeout 100 ms timeout 2,000 ms client timeout 50 ms 400 ms @aiborisov @mykyta_p
  161. 161. gRPC Deadline Propagation Gateway Voting L-Board 200 ms client timeout @aiborisov @mykyta_p
  162. 162. gRPC Deadline Propagation Gateway Voting L-Board 200 ms client timeout 50 ms @aiborisov @mykyta_p
  163. 163. gRPC Deadline Propagation Gateway Voting L-Board 200 - 50 ms timeout 200 ms client timeout 50 ms @aiborisov @mykyta_p
  164. 164. gRPC Deadline Propagation Gateway Voting L-Board 200 - 50 ms timeout 200 ms client timeout 50 ms 400 ms @aiborisov @mykyta_p
  165. 165. gRPC Deadline Propagation Gateway Voting L-Board 200 - 50 - 400 ms timeout 200 - 50 ms timeout 200 ms client timeout 50 ms 400 ms @aiborisov @mykyta_p
  166. 166. gRPC Deadline Propagation (Short) Gateway Voting L-Board 200 - 50 - 400 ms timeout 200 - 50 ms timeout 200 ms client timeout 50 ms 400 ms @aiborisov @mykyta_p
  167. 167. gRPC Deadline Propagation (Large) Gateway Voting L-Board 2,000 - 50 - 400 ms timeout 2,000 - 50 ms timeout 2,000 ms client timeout 50 ms 400 ms 300 ms @aiborisov @mykyta_p
  168. 168. Investigation Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  169. 169. Gateway VotingL-board Aggr Investigation Src #2 Src #1 ... Src #X @aiborisov @mykyta_p
  170. 170. VotingL-board Aggr Investigation Src #2 Src #1 ... Src #X Gateway @aiborisov @mykyta_p
  171. 171. L-board Aggr Investigation Src #2 Src #1 ... Src #X Gateway Voting @aiborisov @mykyta_p
  172. 172. L-board Aggr Investigation Src #2 Src #1 ... Src #X Gateway Voting @aiborisov @mykyta_p
  173. 173. Aggr L-board Investigation Src #2 Src #1 ... Src #X Gateway Voting @aiborisov @mykyta_p
  174. 174. Aggr L-board Investigation Src #2 Src #1 ... Src #X Gateway Voting @aiborisov @mykyta_p
  175. 175. Zipkin: Traces and Latency @aiborisov @mykyta_p
  176. 176. Zipkin and gRPC https://github.com/openzipkin/brave/tree/master/instrumentation/grpc URLConnectionSender sender = ... GrpcTracing grpcTracing = GrpcTracing.create(Tracing.newBuilder() .sampler(ALWAYS_SAMPLE).spanReporter(AsyncReporter.create(sender)).build()); @aiborisov @mykyta_p
  177. 177. Zipkin and gRPC https://github.com/openzipkin/brave/tree/master/instrumentation/grpc URLConnectionSender sender = ... GrpcTracing grpcTracing = GrpcTracing.create(Tracing.newBuilder() .sampler(ALWAYS_SAMPLE).spanReporter(AsyncReporter.create(sender)).build()); ManagedChannel pokemonChannel = NettyChannelBuilder.forAddress(pokemonHost, pokemonPort) .intercept(grpcTracing.newClientInterceptor()) .build(); Server grpcServer = NettyServerBuilder.forPort(8080) .addService(new AggregationService(asList(pokemonClient, bigDataClient))) .intercept(grpcTracing.newServerInterceptor()) .build().start(); @aiborisov @mykyta_p
  178. 178. Zipkin and gRPC https://github.com/openzipkin/brave/tree/master/instrumentation/grpc URLConnectionSender sender = ... GrpcTracing grpcTracing = GrpcTracing.create(Tracing.newBuilder() .sampler(ALWAYS_SAMPLE).spanReporter(AsyncReporter.create(sender)).build()); ManagedChannel pokemonChannel = NettyChannelBuilder.forAddress(pokemonHost, pokemonPort) .intercept(grpcTracing.newClientInterceptor()) .build(); Server grpcServer = NettyServerBuilder.forPort(8080) .addService(new AggregationService(asList(pokemonClient, bigDataClient))) .intercept(grpcTracing.newServerInterceptor()) .build().start(); @aiborisov @mykyta_p
  179. 179. Zipkin and REST build.gradle: dependencies { compile 'org.springframework.cloud:spring-cloud-sleuth-zipkin' compile 'org.springframework.cloud:spring-cloud-starter-sleuth' ... application.properties: spring.zipkin.baseUrl=http://zipkin:9411/ # sample 100% spring.sleuth.sampler.percentage=1.0 ... @aiborisov @mykyta_p
  180. 180. Zipkin : REST and gRPC @aiborisov @mykyta_p
  181. 181. http://GrpcVsRest.com @aiborisov @mykyta_p
  182. 182. Explore More? Demo: https://github.com/grpcvsrest @aiborisov @mykyta_p
  183. 183. Explore More? Demo: https://github.com/grpcvsrest http://grpc.io https://github.com/grpc http://www.grpc.io/docs/quickstart/java.html gRPC Google group: grpc-io@googlegroups.com REST: http://google.com/search?q=rest @aiborisov @mykyta_p
  184. 184. Demo UI is written by Yevgen Golubenko Software Engineer @ Anomali • Twitter: @HalloGene_ • github.com/HalloGene • linkedin.com/in/yevgen-golubenko @aiborisov @mykyta_p
  185. 185. REST gRPC @aiborisov @mykyta_p
  186. 186. All about resources Synchronous and unary Simplicity first External fault-tolerance Production ready All about APIs Async and streaming Performance first Built-in fault-tolerance Production ready REST gRPC @aiborisov @mykyta_p
  187. 187. All about resources Synchronous and unary Simplicity first External fault-tolerance Production ready All about APIs Async and streaming Performance first Built-in fault-tolerance Production ready REST gRPC Be pragmatic, start with your problem! @aiborisov @mykyta_p
  188. 188. Questions? @aiborisov @mykyta_p

×