Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

"gRPC vs REST: let the battle begin!" OSCON 2018 edition

O'Reilly Open Source Convention "gRPC vs REST: let the battle begin!" slides

  • Soyez le premier à commenter

"gRPC vs REST: let the battle begin!" OSCON 2018 edition

  1. 1. gRPC vs REST: let the battle begin! Alex Borysov @aiborisov Mykyta Protsenko @mykyta_p
  2. 2. Who are we? Mykyta Protsenko Software Engineer @ Netflix • passionate about all things scalable • 18+ years in software engineering • avid biker • Author of Henka Alex Borysov Software Engineer @ Google • large scale systems developer • 12+ years in software engineering • devoxx.org.ua PC member • Active gRPC user REST vs gRPC @aiborisov @mykyta_p
  3. 3. devoxx.org.ua November 23-24, 2018 Kyiv, Ukraine Save the Date! #VoxxedDaysMinsk @aiborisov @aiborisov @mykyta_p
  4. 4. @aiborisov @mykyta_p @aiborisov @mykyta_p
  5. 5. JSON over HTTP @aiborisov @mykyta_p
  6. 6. 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
  7. 7. @aiborisov @mykyta_p
  8. 8. @aiborisov @mykyta_p
  9. 9. 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
  10. 10. What is gRPC? @aiborisov @mykyta_p
  11. 11. 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 sourced version of Stubby RPC used in Google. @aiborisov @mykyta_p
  12. 12. g in gRPC stands for 1.0 'gRPC' 1.1 'good' 1.2 'green' 1.3 'gentle' . . . 1.11 'gorgeous' 1.12 'glorious' 1.13 'gloriosa' 1.14 'gladiolus' @aiborisov @mykyta_p https://github.com/grpc/grpc/blob/master/doc/g_stands_for.md
  13. 13. RPC?! But... AMF? RMI? CORBA? @aiborisov @mykyta_p Image by Dan4th Nicholas. See slide #177 for details.
  14. 14. gRPC is not RMI Maitainability Ease of use Performance Scalability L e s s o n s Years of using Stubby @aiborisov @mykyta_p
  15. 15. 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
  16. 16. 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, including JS! @aiborisov @mykyta_p
  17. 17. gRPC Interoperability Java Service Python Service GoLang Service C++ Service gRPC Service gRPC Stub gRPC Stub gRPC Stub gRPC Service gRPC Service gRPC Service @aiborisov @mykyta_p gRPC Stub gRPC- Web Stub
  18. 18. Apples to Oranges? @aiborisov @mykyta_p
  19. 19. Microservices? @aiborisov @mykyta_p
  20. 20. Microservices? How to draw an owl? @aiborisov @mykyta_p
  21. 21. Microservices? How to draw an owl? How to build microservices? @aiborisov @mykyta_p
  22. 22. Microservices? How to draw an owl? How to build microservices? Draw some circles. @aiborisov @mykyta_p
  23. 23. Microservices? How to draw an owl? How to build microservices? Draw some circles. Take XYZ framework. @aiborisov @mykyta_p
  24. 24. Microservices? How to draw an owl? How to build microservices? Draw the REST of the owlDraw some circles. Take XYZ framework. @aiborisov @mykyta_p Image by https://www.flickr.com/photos/centralasian/. See slide #177 for details.
  25. 25. 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 Image by https://www.flickr.com/photos/centralasian/. See slide #177 for details.
  26. 26. Microservices @aiborisov @mykyta_p
  27. 27. Microservices @aiborisov @mykyta_p
  28. 28. Microservices @aiborisov @mykyta_p
  29. 29. Microservices @aiborisov @mykyta_p
  30. 30. Remote Calls @aiborisov @mykyta_p
  31. 31. Call Flow @aiborisov @mykyta_p
  32. 32. Service Discovery? ? ? ? ? ? ? @aiborisov @mykyta_p
  33. 33. Multiple Instances #1 #N #2 ? ? ? . . . @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. Call Flow @aiborisov @mykyta_p
  38. 38. Call Flow @aiborisov @mykyta_p
  39. 39. Slow Services? @aiborisov @mykyta_p
  40. 40. Failure Scenarios @aiborisov @mykyta_p
  41. 41. 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
  42. 42. Fault Tolerance @aiborisov @mykyta_p
  43. 43. Microservices?! But... Performance Hit? Service Discovery? Load Balancing? Fault Tolerance? Monitoring? Testing? @aiborisov @mykyta_p Image by Dan4th Nicholas. See slide #177 for details.
  44. 44. Sample Problem Client @aiborisov @mykyta_p
  45. 45. Sample Problem: Aggregator Src #2 Src #1 Aggr ... Src #X Client @aiborisov @mykyta_p
  46. 46. Heterogeneous Data Format Src #2 Src #1 Aggr ... Src #X <XML>...<XML> {JSON} Binary 110011 [ Unified Format ] Client @aiborisov @mykyta_p
  47. 47. REST: It’s All About Resources @aiborisov @mykyta_p
  48. 48. REST: Call Hierarchy Controller Service Data Source A . . . Data Source N RestTemplate RestTemplate RestTemplate @aiborisov @mykyta_p
  49. 49. REST: Data Source JSON URL: http://pokemon.com/content/11 { "id": 11, "content": "Pikachu" } XML URL: http://crypto.com/content/22 <ContentResponse> <id>22</id> <content>Ethereum</content> </ContentResponse> @aiborisov @mykyta_p
  50. 50. REST: Data Source ... ResponseEntity<Content> contentEntity = restTemplate.getForEntity( url + "{content_id}" Content.class, ImmutableMap.of("content_id", contentId)); ... @aiborisov @mykyta_p
  51. 51. 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
  52. 52. 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
  53. 53. REST: Service public class AggregatingService { public AggregatedContent fetch(int id) { ... return new AggregatedContent(...); } } public class AggregatedContent { private Integer id; // 115 private String type; // Pokemon private String content; // Pikachu private Integer nextId; // 116 @aiborisov @mykyta_p
  54. 54. REST: Service public class AggregatingService { public AggregatedContent fetch(int id) { ... return new AggregatedContent(...); } } public class AggregatedContent { private Integer id; // 115 private String type; // Pokemon private String content; // Pikachu private Integer nextId; // 116 @aiborisov @mykyta_p
  55. 55. REST: Controller @GetMapping( value = "/content/{id}", produces = "application/json") public AggregatedContent aggregated(@PathVariable("id") int id) { return aggregatingService.fetch(id); } @aiborisov @mykyta_p
  56. 56. 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
  57. 57. REST: It’s simple http://localhost:8080/content/115 { "id": 115, "content_type": "CRYPTO", "content": "Ethereum", "next_uri": "/content/116" } @aiborisov @mykyta_p
  58. 58. REST: Service Discovery @aiborisov @mykyta_p
  59. 59. k8s/pokemon.yaml ... kind: Service metadata: name: rest-pokemon-content-service k8s/aggregator.yaml ... env: - name: datasource_a_url value: "http://rest-pokemon-content-service:8080" REST: Service Discovery @aiborisov @mykyta_p
  60. 60. k8s/pokemon.yaml ... kind: Service metadata: name: rest-pokemon-content-service k8s/aggregator.yaml ... env: - name: datasource_a_url value: "http://rest-pokemon-content-service:8080" REST: Service Discovery @aiborisov @mykyta_p
  61. 61. 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": "Pokemon", "content": "Pikachu", "next_uri": "/content/116" } @aiborisov @mykyta_p
  62. 62. gRPC: It’s All About APIs @aiborisov @mykyta_p
  63. 63. Sample Problem: Aggregator Src #2 Src #1 Aggr ... Src #X Client @aiborisov @mykyta_p
  64. 64. Service Definition (aggregator.proto) @aiborisov @mykyta_p
  65. 65. Service Definition (aggregator.proto) syntax = "proto3"; service AggregationService { rpc Get(AggregationRequest) returns (AggregationResponse); } @aiborisov @mykyta_p
  66. 66. 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; CRYPTO = 2; } @aiborisov @mykyta_p
  67. 67. Service Definition aggregator.proto @aiborisov @mykyta_p
  68. 68. Service Definition aggregator.proto gRPC Runtime @aiborisov @mykyta_p
  69. 69. Service Definition aggregator.proto AggregationServiceImplBase.java AggregationRequest.java AggregationResponse.java AggregationServiceStub.java AggregationServiceFutureStub.java AggregationServiceBlockingStub.java Service Implementation Request and response Client libraries @aiborisov @mykyta_p gRPC Java Runtime
  70. 70. Implement gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void get(AggregationRequest request, StreamObserver<AggregationResponse> responseObserver) { } } @aiborisov @mykyta_p
  71. 71. Implement gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void get(AggregationRequest request, StreamObserver<AggregationResponse> responseObserver) { } } Generated service class @aiborisov @mykyta_p
  72. 72. Implement gRPC Service public class AggregationService extends AggregationServiceImplBase { @Override public void get(AggregationRequest request, StreamObserver<AggregationResponse> responseObserver) { } } @aiborisov @mykyta_p
  73. 73. 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
  74. 74. 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("Ethereum") .setType(ResponseType.CRYPTO) .build(); responseObserver.onNext(response); responseObserver.onCompleted(); } } @aiborisov @mykyta_p
  75. 75. 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("Ethereum") .setType(ResponseType.CRYPTO) .build(); responseObserver.onNext(response); responseObserver.onCompleted(); } } @aiborisov @mykyta_p
  76. 76. 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; CRYPTO = 2; } @aiborisov @mykyta_p
  77. 77. 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; CRYPTO = 2; } @aiborisov @mykyta_p
  78. 78. 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; CRYPTO = 2; } @aiborisov @mykyta_p
  79. 79. 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; CRYPTO = 2; } @aiborisov @mykyta_p
  80. 80. 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; CRYPTO = 2; } @aiborisov @mykyta_p
  81. 81. 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; CRYPTO = 2; } @aiborisov @mykyta_p
  82. 82. Sample Problem: Aggregator Src #2 Src #1 Aggr ... Src #X Client aggregator.proto @aiborisov @mykyta_p
  83. 83. Sample Problem: Content Src #2 Src #1 Aggr ... Src #X Client aggregator.proto content.proto @aiborisov @mykyta_p
  84. 84. 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
  85. 85. Streaming gRPC Service public class AggregationService extends AggregationServiceImplBase { private final Collection<ContentServiceStub> contentStubs; public AggregationService(Collection<ContentServiceStub> contentStubs) { this.contentStubs = contentStubs; } ... @aiborisov @mykyta_p
  86. 86. 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
  87. 87. 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
  88. 88. 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
  89. 89. 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
  90. 90. 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
  91. 91. 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
  92. 92. Streaming gRPC Service Src #2 Src #1 Aggr ... Src #X Client @aiborisov @mykyta_p
  93. 93. Streaming gRPC Service Src #2 Src #1 Aggr ... Src #X Client Subscribe() @aiborisov @mykyta_p
  94. 94. Streaming gRPC Service Src #2 Src #1 Aggr ... Src #X Client Subscribe() Subscribe() Subscribe() Subscribe() @aiborisov @mykyta_p
  95. 95. Streaming gRPC Service Src #2 Src #1 Aggr ... Src #X Client onNext() @aiborisov @mykyta_p
  96. 96. Streaming gRPC Service Src #2 Src #1 Aggr ... Src #X Client onNext() onNext() @aiborisov @mykyta_p
  97. 97. Streaming gRPC Service Src #2 Src #1 Aggr ... Src #X Client onNext() @aiborisov @mykyta_p
  98. 98. Streaming gRPC Service Src #2 Src #1 Aggr ... Src #X Client onNext() onNext() @aiborisov @mykyta_p
  99. 99. Start gRPC Server ContentServiceStub cryptoClient = ... ContentServiceStub pokemonClient = ... Server grpcServer = NettyServerBuilder.forPort(8080) .addService(new AggregationService(asList(cryptoClient, pokemonClient))) .build().start(); @aiborisov @mykyta_p
  100. 100. Start gRPC Server ContentServiceStub cryptoClient = ... ContentServiceStub pokemonClient = ... Server grpcServer = NettyServerBuilder.forPort(8080) .addService(new AggregationService(asList(cryptoClient, pokemonClient))) .build().start(); @aiborisov @mykyta_p
  101. 101. Create gRPC Client String host = System.getenv("crypto_host"); int post = Integer.valueOf(System.getenv("crypto_port")); ManagedChannel cryptoChannel = NettyChannelBuilder.forAddress(host, port).build(); @aiborisov @mykyta_p
  102. 102. Create gRPC Client String host = System.getenv("crypto_host"); int post = Integer.valueOf(System.getenv("crypto_port")); ManagedChannel cryptoChannel = NettyChannelBuilder.forAddress(host, port).build(); ContentServiceStub cryptoClient = ContentServiceGrpc.newStub(cryptoChannel); @aiborisov @mykyta_p
  103. 103. Create gRPC Client String host = System.getenv("crypto_host"); int port = Integer.valueOf(System.getenv("crypto_port")); ManagedChannel cryptoChannel = NettyChannelBuilder.forAddress(host, port).build(); ContentServiceStub cryptoClient = ContentServiceGrpc.newStub(cryptoChannel); ContentServiceBlockingStub cryptoBlockingClient = ContentServiceGrpc.newBlockingStub(cryptoChannel); @aiborisov @mykyta_p
  104. 104. Create gRPC Client tring host = System.getenv("crypto_host"); int port = Integer.valueOf(System.getenv("crypto_port")); ManagedChannel cryptoChannel = NettyChannelBuilder.forAddress(host, port).build(); ContentServiceStub cryptoClient = ContentServiceGrpc.newStub(cryptoChannel); ContentServiceBlockingStub cryptoBlockingClient = ContentServiceGrpc.newBlockingStub(cryptoChannel); ContentServiceFutureStub cryptoFutureClient = ContentServiceGrpc.newFutureStub(cryptoChannel); @aiborisov @mykyta_p
  105. 105. Service Discovery & Load Balancing String host = System.getenv("crypto_host"); int post = Integer.valueOf(System.getenv("crypto_port")); ManagedChannel cryptoChannel = NettyChannelBuilder.forAddress(host, port).build(); @aiborisov @mykyta_p
  106. 106. Service Discovery & Load Balancing ManagedChannel cryptoChannel = NettyChannelBuilder.forAddress(host, port).build(); @aiborisov @mykyta_p
  107. 107. Service Discovery & Load Balancing ManagedChannel cryptoChannel = NettyChannelBuilder.forTarget("crypto") .build(); @aiborisov @mykyta_p
  108. 108. Service Discovery & Load Balancing ManagedChannel cryptoChannel = NettyChannelBuilder.forTarget("crypto") .nameResolverFactory(new DnsNameResolverProvider()) .loadBalancerFactory(RoundRobinLoadBalancerFactory.getInstance()) .build(); @aiborisov @mykyta_p
  109. 109. Service Discovery & Load Balancing ManagedChannel cryptoChannel = NettyChannelBuilder.forTarget("crypto") .nameResolverFactory(new MyCustomNameResolverProviderFactory()) .loadBalancerFactory(new MyMoonPhaseLoadBalancerFactory()) .build(); @aiborisov @mykyta_p
  110. 110. Netty ManagedChannel cryptoChannel = NettyChannelBuilder.forTarget("crypto") .nameResolverFactory(new MyCustomNameResolverProvider()) .loadBalancerFactory(new MyMoonPhaseLoadBalancerFactory()) .build(); @aiborisov @mykyta_p
  111. 111. Netty + HTTP/2 + Protobuf @aiborisov @mykyta_p
  112. 112. Netty + HTTP/2 + Protobuf = Performance http://www.grpc.io/docs/guides/benchmarking.html @aiborisov @mykyta_p 8 core VMs, streaming throughput
  113. 113. Netty + HTTP/2 + Protobuf = Performance http://www.grpc.io/docs/guides/benchmarking.html @aiborisov @mykyta_p 32 core VMs, streaming throughput
  114. 114. Client Latency ... 900 ms! @aiborisov @mykyta_p
  115. 115. Caching CDN 9 ms ... @aiborisov @mykyta_p
  116. 116. Serverless pay as you go Func Funcinput ... Func input ... input @aiborisov @mykyta_p
  117. 117. 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
  118. 118. Sample Problem Src #2 Src #1 ... Src #X Client Aggr @aiborisov @mykyta_p
  119. 119. Sample Problem: Voting Src #2 Src #1 ... Src #X Client Voting Aggr @aiborisov @mykyta_p
  120. 120. Sample Problem: Voting Src #2 Src #1 ... Src #X Client Voting Aggr @aiborisov @mykyta_p
  121. 121. Sample Problem: Voting Src #2 Src #1 ... Src #X Client Voting Aggr @aiborisov @mykyta_p
  122. 122. Sample Problem: Voting & Leaderboard Src #2 Src #1 ... Src #X Client Voting Aggr L-board @aiborisov @mykyta_p
  123. 123. Sample Problem: Voting & Leaderboard Src #2 Src #1 ... Src #X Client Voting Aggr L-board @aiborisov @mykyta_p
  124. 124. Sample Problem: Voting & Leaderboard Src #2 Src #1 ... Src #X Gateway Voting Aggr L-board @aiborisov @mykyta_p
  125. 125. Sample Problem Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  126. 126. Failing Leaderboard Src #2 Src #1 ... Src #X Gateway Voting Aggr @aiborisov @mykyta_p
  127. 127. Cascading Failure Src #2 Src #1 ... Src #X Gateway Voting Aggr @aiborisov @mykyta_p
  128. 128. Cascading Failure Src #2 Src #1 ... Src #X Gateway Voting Aggr @aiborisov @mykyta_p
  129. 129. Cascading Failure Src #2 Src #1 ... Src #X Gateway Voting Aggr @aiborisov @mykyta_p
  130. 130. Circuit Breaker Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  131. 131. Circuit Breaker Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  132. 132. Circuit Breaker Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  133. 133. Circuit Breaker Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  134. 134. Circuit Breaker Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  135. 135. Circuit Breaker Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  136. 136. Slow Services Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  137. 137. Timeouts? Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr 200 ms 2 sec @aiborisov @mykyta_p
  138. 138. Large Timeouts Gateway Voting L-Board 1,000 ms timeout 1,000 ms timeout 200 ms client timeout @aiborisov @mykyta_p
  139. 139. Large Timeouts Gateway Voting L-Board 1,000 ms timeout 1,000 ms timeout 200 ms client timeout 50 ms @aiborisov @mykyta_p
  140. 140. 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
  141. 141. 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
  142. 142. 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
  143. 143. Short Timeouts Gateway Voting L-Board 100 ms timeout 100 ms timeout @aiborisov @mykyta_p
  144. 144. Short Timeouts Gateway Voting L-Board 100 ms timeout 100 ms timeout 2,000 ms client timeout @aiborisov @mykyta_p
  145. 145. Short Timeouts Gateway Voting L-Board 100 ms timeout 100 ms timeout 2,000 ms client timeout 50 ms @aiborisov @mykyta_p
  146. 146. Short Timeouts Gateway Voting L-Board 100 ms timeout 100 ms timeout 2,000 ms client timeout 50 ms 400 ms @aiborisov @mykyta_p
  147. 147. Short Timeouts Gateway Voting L-Board 100 ms timeout 100 ms timeout 2,000 ms client timeout 50 ms 400 ms @aiborisov @mykyta_p
  148. 148. Short Timeouts Gateway Voting L-Board 100 ms timeout 100 ms timeout 2,000 ms client timeout 50 ms 400 ms @aiborisov @mykyta_p
  149. 149. gRPC Deadline Propagation Gateway Voting L-Board 200 ms client timeout @aiborisov @mykyta_p
  150. 150. gRPC Deadline Propagation Gateway Voting L-Board 200 ms client timeout 50 ms @aiborisov @mykyta_p
  151. 151. gRPC Deadline Propagation Gateway Voting L-Board 200 - 50 ms timeout 200 ms client timeout 50 ms @aiborisov @mykyta_p
  152. 152. gRPC Deadline Propagation Gateway Voting L-Board 200 - 50 ms timeout 200 ms client timeout 50 ms 400 ms @aiborisov @mykyta_p
  153. 153. 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
  154. 154. 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
  155. 155. 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
  156. 156. Investigation Src #2 Src #1 ... Src #X Gateway VotingL-board Aggr @aiborisov @mykyta_p
  157. 157. Gateway VotingL-board Aggr Investigation Src #2 Src #1 ... Src #X @aiborisov @mykyta_p
  158. 158. VotingL-board Aggr Investigation Src #2 Src #1 ... Src #X Gateway @aiborisov @mykyta_p
  159. 159. L-board Aggr Investigation Src #2 Src #1 ... Src #X Gateway Voting @aiborisov @mykyta_p
  160. 160. L-board Aggr Investigation Src #2 Src #1 ... Src #X Gateway Voting @aiborisov @mykyta_p
  161. 161. Aggr L-board Investigation Src #2 Src #1 ... Src #X Gateway Voting @aiborisov @mykyta_p
  162. 162. Aggr L-board Investigation Src #2 Src #1 ... Src #X Gateway Voting @aiborisov @mykyta_p
  163. 163. Zipkin: Traces and Latency @aiborisov @mykyta_p
  164. 164. 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
  165. 165. 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 cryptoChannel = NettyChannelBuilder.forAddress(cryptoHost, cryptoPort) .intercept(grpcTracing.newClientInterceptor()) .build(); Server grpcServer = NettyServerBuilder.forPort(8080) .addService(new AggregationService(asList(cryptoClient, pokemonClient))) .intercept(grpcTracing.newServerInterceptor()) .build().start(); @aiborisov @mykyta_p
  166. 166. 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 cryptoChannel = NettyChannelBuilder.forAddress(cryptoHost, cryptoPort) .intercept(grpcTracing.newClientInterceptor()) .build(); Server grpcServer = NettyServerBuilder.forPort(8080) .addService(new AggregationService(asList(cryptoClient, pokemonClient))) .intercept(grpcTracing.newServerInterceptor()) .build().start(); @aiborisov @mykyta_p
  167. 167. 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
  168. 168. Zipkin : REST and gRPC @aiborisov @mykyta_p
  169. 169. http://Oscon.GrpcVsRest.com @aiborisov @mykyta_p Crypto or Pokemon? iStock.com/RichVintage
  170. 170. Explore More? Demo: https://github.com/grpcvsrest @aiborisov @mykyta_p
  171. 171. Explore More? Demo: https://github.com/grpcvsrest http://grpc.io https://github.com/grpc http://www.grpc.io/docs/quickstart/java.html gRPC -Web: https://github.com/grpc/grpc-web gRPC Google group: grpc-io@googlegroups.com REST: http://google.com/search?q=rest @aiborisov @mykyta_p gRPC or REST? iStock.com/RichVintage
  172. 172. Demo UI is written by Yevgen Golubenko Software Engineer @ Anomali • Twitter: @HalloGene_ • github.com/HalloGene • linkedin.com/in/yevgen-golubenko @aiborisov @mykyta_p
  173. 173. REST gRPC @aiborisov @mykyta_p
  174. 174. 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
  175. 175. 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
  176. 176. Questions? @aiborisov @mykyta_p Image by https://www.flickr.com/photos/centralasian/. See slide #177 for details.
  177. 177. Images Used @aiborisov @mykyta_p Slides ##24, 25, 176: https://www.flickr.com/photos/centralasian/5229725173 ● licenced by CC BY 2.0: https://creativecommons.org/licenses/by/2.0/ ● changes were made Slides ##13, 43: https://www.flickr.com/photos/dan4th/2295925353/ ● licenced by CC BY 2.0: https://creativecommons.org/licenses/by/2.0/ ● no changes were made Slides ## 171,173: iStock.com/RichVintage ● https://www.istockphoto.com/legal/license-agreement ● no changes were made

×