Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JUGNsk Meetup#9. Дмитрий Пышкин: "Почему именно сейчас gRPC"

JUGNsk Meetup#9. Дмитрий Пышкин: "Почему именно сейчас gRPC"

Доклад об альтернативах RESTу, о проблемах встраивания gRPC в типовую микросервисную архитектуру, об изменении подхода передачи данных поверх TCP/IP и что если копнуть глубже, то можно наткнуться на IDL.

jugnsk

June 13, 2019
Tweet

More Decks by jugnsk

Other Decks in Programming

Transcript

  1. О КОМПАНИИ 3 Брокер №1 в рейтинге Московской Биржи. В

    1995 году мы были одними из первых, кто начал оказывать брокерские услуги в России. Уже больше 20 лет мы каждый день работаем над тем, чтобы вам было проще и удобнее управлять своими финансами. БКС Брокер
  2. О СЕБЕ 4 Работаю в IT более 10 лет; Java

    занимаюсь с 2013 года; В БКС Брокере занимаюсь разработкой высоконагруженных микросервисов, связанных с онлайн торговлей.
  3. ЦЕЛЬ ДОКЛАДА 5 Рассказать, о проблемах использования gRPC, с которыми

    столкнулись, и путях их решения; Пробудить желание использовать данную технологию :-)
  4. Итоги и вывод: 3 минуты Опыт использования: 20 минут gRPC

    и как это (не) связано с микросервисами: 5 минут Кратко о технологии: 5 минут СТРУКТУРА ДОКЛАДА 6
  5. Кратко о технологии Список поддерживаемых платформ 9 Go Node.js Java

    Ruby Python Rust Haskell Erlang Elixir Elm Scala Dart Kotlin Go TypeScript C#
  6. Кратко о технологии Абстракция: message message SearchRequest{} Версия: proto3 syntax

    = “proto3”; Протокол: protobuf Тип Java тип double double float float int32 int int64 long uint32 int uint64 long sint32 int sint64 long fixed32 int fixed64 long sfixed32 int sfixed64 long bool boolean string String bytes ByteString Массивы : repeated message SearchRequests{ repeated string requests = 1; } Перечисления : enum message SearchRequest { enum Corpus { WEB = 1; NEWS = 2; } Corpus corpus = 2; } One of message SearchRequest { oneof request { WebReq webreq = 1; NewsReq newsreq = 2; } } message WebReq { string request = 1; } message NewsReq { string request = 1; } Maps message SearchRequest { string request = 1; map<string, string> headers = 2; } protobuf Обертки: wrappers import “google/protobuf/wrappers.proto”; 11
  7. Кратко о технологии gRPC представляет собой бинарные данные в protobuf,

    передаваемые по протоколу http/2 с поддержкой дуплексных rpc вызовов для всех основных платформ 12
  8. Кратко о технологии Способы передачи данных protobuf генерация server/client (IDL)

    Sync / Async interaction Termination / Deadlines / Cancelling Unary RPC service HelloService { rpc SayHello (HelloRequest) returns (HelloResponse); } message HelloRequest { string greeting = 1; } message HelloResponse { string reply = 1; } Server streaming RPC service HelloService { rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){ } message HelloRequest { string greeting = 1; } message HelloResponse { string reply = 1; } Client streaming RPC service HelloService { rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse){ } message HelloRequest { string greeting = 1; } message HelloResponse { string reply = 1; } Bidirectional streaming RPC service HelloService { rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){ } message HelloRequest { string greeting = 1; } message HelloResponse { string reply = 1; } 13
  9. gRPC и как это (не) связано с микросервисами "Микросервисы построены

    вокруг одной бизнес- функции и могут быть развернуты независимо с помощью автоматизированного механизма деплоя. Существует минимальный уровень централизованного управления микросервисами, которые могут быть написаны на разных языках программирования и использовать разные технологии хранения данных." М. Фаулер 15
  10. gRPC и как это (не) связано с микросервисами Client LOG

    ANALYSIS ELK SYSTEM MONITOR GRAFANA DISCOVERY Spring cloud Eureka / CONSUL CONFIG SERVICE Spring cloud config AUTH SERVICE Keycloak Quotes stream Kubernetes (OpenShift) Quotes store 16 http(REST) API GATEWAY ZUUL gRPC
  11. gRPC и как это (не) связано с микросервисами Взаимодействие с

    AUTH SERVICE ? 17 Организация подписок Взаимодействие с DISCOVERY Взаимодействие REST и gRPC
  12. Опыт использования Взаимодействие с AUTH SERVICE ? 19 Организация подписок

    Взаимодействие с DISCOVERY Взаимодействие REST и gRPC
  13. Опыт использования 20 Client Open ID Connect Provider (KEYCLOAK) API

    Gateway Аутинтификация (получение токена) Верификация токена Backend (наличие токена + необязательная верификация)
  14. Опыт использования Запуск и работа сервера ServerBuilder NettyServerProvider Загрузка конфигурации

    21 NettyServerBuilder Инициализация builder ServerImpl Вставка сгенерированного сервиса в stubs и его регистрация в service registry NettyServer Старт HTTP/2 сервера и обработка входящих запросов
  15. Опыт использования new ServerInterceptor() { @Override public <ReqT, RespT> ServerCall.Listener<ReqT>

    interceptCall( ServerCall<ReqT, RespT> call , Metadata headers , ServerCallHandler<ReqT, RespT> next) { return Contexts.interceptCall( Context.current().withValue("token_key", "token_value") , call , headers , next ); } } Код сервера: 22 ServerBuilder.forPort( port ) .addService( ServerInterceptors.intercept( ourService, new ServerInterceptor() { … } ) ) .build(); +
  16. Опыт использования new CallCredentials() { @Override public void applyRequestMetadata( MethodDescriptor

    method , Attributes attributes , Executor appExecutor , MetadataApplier applier) { final Metadata headers = new Metadata(); headers.put("token_key", "token_value"); applier.apply(headers); } @Override public void thisUsesUnstableApi() {} } Код клиента: 23
  17. Взаимодействие с AUTH SERVICE ? 24 Организация подписок Взаимодействие с

    DISCOVERY Взаимодействие REST и gRPC Опыт использования
  18. Опыт использования Обработка запросов и передачу сообщений сервером Http2ConnectionHandler Десериализация

    и вызов handler NioByteUnsafe Чтение бинарных данных из сокета NioEventLoop Получение данных по каналу через сокет run() 26 Http2ConnectionHandler FrameListener Сериализация и создание HTTP/2 заголовков и тела для отправки в сеть ServiceHandler Обработка запроса
  19. Взаимодействие с AUTH SERVICE ? 28 Организация подписок Взаимодействие с

    DISCOVERY Взаимодействие REST и gRPC Опыт использования
  20. Опыт использования Создание запроса клиентом 30 Client RPC вызов через

    stub. Резолв хоста через DnsNameResolver и через LoadBalancer выбор одного из доступных gRPC серверов Netty Transport Base HTTP/2 Сериализация protobuf и наполнение HTTP/2 сообщения для отправки в стрим gRPC серверу Network Protobuf Marshaller Отправка данных в сеть
  21. Опыт использования final Application application = new DiscoveryClient(appManager, clientConfig).getApplication(serviceName); Код

    клиента: 31 final List<EquivalentAddressGroup> resolvedServerInfos = application.getInstances().stream() .map((instanceInfo) -> { int port; if (this.portMetaData != null) { port = Integer.parseInt(instanceInfo.getMetadata().get(this.portMetaData)); } else { port = instanceInfo.getPort(); } return new EquivalentAddressGroup( new InetSocketAddress(instanceInfo.getHostName(), port) , Attributes.EMPTY); }).collect(Collectors.toList()); + new NameResolverListenerImpl(helper).onAddresses(resolvedServerInfos, Attributes.EMPTY); +
  22. Взаимодействие с AUTH SERVICE ? 32 Организация подписок Взаимодействие с

    DISCOVERY Взаимодействие REST и gRPC Опыт использования
  23. Опыт использования Плагин в плагин - GRPC REST Gateway import

    "google/api/annotations.proto"; service LibraryService { rpc AddBook(AddBookRequest) returns (AddBookResponse) { option (google.api.http) = { post: “/v1/book” body: “*” }; } } 33
  24. Опыт использования Handling aspect Interface CallCredentials Authentication aspect Interface ServerInterceptor

    final class Metadata Interface NameResolver DNS aspect Interface NameResolverProvider Abstract class GeneratedMessageV3 Interface Message Data transfer aspect Interface StreamObserver Interface Stream Abstract class Channel ? 34
  25. Итоги 2) хорошо подходит для использования в микросервисной архитектуре. 1)

    производительный и достаточно гибкий; + 1) генерация большого количества клиентского / серверного кода для stubs; 2) приходится сталкиваться с проблемами при встраивании в существующую архитектуру. —