Руководство о том, как выжить, когда разбитые машины захватывают мир

Вы когда-нибудь водили машину с ребенком на заднем сиденье?
Постоянные расспросы.

Мы уже на месте? Мы уже на месте? - надоедливые дети на заднем сиденье

Это могло свести людей с ума, и, вероятно, уже произошло.

Это странно, потому что, даже если мы знаем, насколько это неприятно, программное обеспечение имеет тенденцию разрабатываться именно таким образом. У вас есть интерфейс или служба, работающая как клиент, который загружает данные с сервера. Эта загрузка во многих случаях выполняется путем частого опроса новых данных. Представьте себе HTTP API с множеством клиентов, которые спрашивают вас: Эй, есть какие-нибудь новые блестящие данные для меня? каждые 10 секунд или около того. Этот шаблон часто называют опросом.

Опрос - это шаблон проектирования, показывающий, как клиент получает данные с сервера.

Я счастлив, что компьютеры еще не сформировали собственный ум, потому что когда они это делают, о боже, мы, разработчики программного обеспечения, облажались. Все эти серверы должны быть разочарованы. К счастью, вы читаете этот пост в блоге, который спасет вашу жизнь, когда машины захватят мир. Они могут даже избавить вас от необходимости изменить ваш шаблон общения после этого поста.

В этой статье мы рассмотрим потоковую архитектуру с использованием потоков gRPC. Существует множество современных решений для потоковой передачи данных, WebSocket, WebRTC. Причина, по которой я выбираю gRPC, заключается в том, что он позволяет нам также передавать данные между микросервисами, а не только веб-приложениями. (Также потому, что мне нравится работать с Go)
В этой статье мы создадим один сервер gRPC, написанный на Go, один клиент, написанный на Go, и один клиент на React. Однако вы увидите, как оба клиента используют один и тот же сервер.

В отличие от опроса, дизайн будет выглядеть как на картинке ниже. Мы установим соединение с одним запросом, а затем будем ждать данных с сервера. Таким образом, вместо того, чтобы клиент запрашивал новые данные, сервер отправляет новые данные клиентам, это называется потоковой передачей на стороне сервера.

Есть два других способа потоковой передачи данных с помощью gRPC, которые называются клиентская потоковая передача и двунаправленная потоковая передача. В этой статье мы будем использовать только потоковую передачу на стороне сервера.

Потоковая передача на стороне клиента - это когда клиент отправляет данные на сервер.

Двунаправленная потоковая передача - это когда и клиент, и сервер могут передавать данные друг другу.

Приступим к реализации дизайна в серверной части Go. Мы также реализуем клиента в приложении React. Итак, после этой статьи у вас должны быть сервер Go, клиент Go и клиент React, которые общаются с одним и тем же сервером.

Настройка проекта и необходимое программное обеспечение

Начнем с настройки структуры проекта. Я начал с создания папки для каждого из наших клиентов и внутреннего кода. В моем случае я назвал проект grpcstreams, и внутри него 3 пустые папки и 2 пустых файла .go. Полный пример кода можно найти здесь.

Если вы не знакомы с gRPC, я предлагаю сначала прочитать мою другую статью об этом. Если вы хотите продолжить без предварительного уведомления, вам необходимо установить Protoc. Protoc - это компилятор, используемый для сборки наших сервисов protobuf и gRPC в код Go.

Вам также понадобится плагин go gRPC, чтобы мы могли сгенерировать код gRPC для бэкэнда go. Его можно получить с помощью команды go get, если вам нужно установить (что я предполагаю) или пойти и получить.

go get -u google.golang.org/protobuf/cmd/protoc-gen-go
go install google.golang.org/protobuf/cmd/protoc-gen-go

go get -u google.golang.org/grpc/cmd/protoc-gen-go-grpc
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc

Еще одна вещь, прежде чем мы начнем, нам также нужно будет создать клиента для веб-приложения. Инструкцию по установке можно найти здесь.

Итак, чтобы убедиться, что у вас есть все, вот список того, что вам нужно.

  • Protoc
  • protoc-gen-go и protoc-gen-go-grpc
  • grpc-web

Настройка службы gRPC

Мы начнем с создания файла с именем service.proto, который будет находиться внутри папки proto. Этот файл является файлом protobuf, который определяет, как будет выглядеть наша внутренняя служба. Мы создадим службу мониторинга оборудования, которая будет публиковать статистику оборудования для клиентов.

В gRPC вы создаете свой файл protobuf и генерируете код на основе этого файла. Файл service.proto представляет собой шаблон того, как будет выглядеть сгенерированный код.

Мы создали службу HardwareMonitor, которая будет предоставлять один метод под названием Monitor. Метод Monitor вернет поток, как указано в (stream HardwareStats).

Давайте воспользуемся протоколом, чтобы сгенерировать необходимый код на основе service.proto.

protoc service.proto --js_out=import_style=commonjs,binary:. --grpc-web_out=import_style=commonjs,mode=grpcwebtext:. --go-grpc_out=. --go_out=.

Эта команда может показаться пугающей, но она довольно проста. Что мы делаем, так это вызываем протокол protoc в нашем service.proto. Затем мы добавляем флаги (js_out, grpc-web_out, go-grpc_out, go_out), которые являются генераторами кода, которые мы установили. Затем мы говорим =. что означает вывод кода в текущий каталог. Это означает, что protoc сгенерирует для нас четыре файла. Скоро мы ими воспользуемся. Поэтому, если вы хотите добавить другой тип клиента, например Java-клиент, вы должны добавить опцию java_out.

Перейти на сервер gRPC

Если мы посмотрим на файл service_grpc.pb.go, созданный из протокола, мы обнаружим, что он создал для нас интерфейс. Он сгенерировал для нас много кода, но он не может знать, что будет делать метод Monitor, поэтому это зависит от разработчиков. Сгенерированный код предназначен для установки соединения и всего, что необходимо для работы gRPC, это то, что мы оставим как есть.

Если вы не очень знакомы с интерфейсами, можете прочитать о них мою статью. Сгенерированный интерфейс выглядит следующим образом.

Нам нужно открыть server.go и отредактировать его, чтобы он стал частью интерфейса HardwareMonitorServer. Это означает, что нам нужно реализовать метод Monitor.

Когда установлен server.go, нам также нужен способ запустить сервер. Это делается в main.go. Главный будет просто прослушивать TCP-соединения с портом 7777 и размещать на этом порту наш сервер мониторинга оборудования gRPC. Это позволит клиентам из веб-клиента или клиента go выполнять метод Monitor. Помните, что это RPC, поэтому любые запросы - это просто инструкции по выполнению метода на сервере. По этой причине у нас могут быть клиенты на многих языках. Обратите внимание, что этот gRPC API будет работать при небезопасном соединении. В производстве вам следует добавить TLS, см. Мою статью о gRPC и TLS.

Клиент в Go

Теперь, когда сервер запущен и работает, нам нужно создать клиента для его тестирования. Я собираюсь начать с клиента, написанного на Go.

Клиент будет очень простым, он подключится к серверу gRPC, настроит поток и будет слушать в течение 7 секунд, а затем завершит работу.

Когда вы заполнили client.go, пора попробовать. Просто запустите go run на сервере, а затем на клиенте.

Клиент в веб-приложении

Для веб-приложения я буду использовать react и create-react-app.

Так что для создания веб-приложения потребуется дополнительная установка программного обеспечения, извините! :)

Мы будем использовать NPM, так что начните с этого.

Нам также понадобятся библиотеки protobuf и gRPC, чтобы мы могли использовать клиент.

npm install -g npx
npm install grpc-web
npm install google-protobuf

Мы создадим приложение реагирования под названием hwmonitor. Итак, прежде всего вам нужно войти в папку webapp и выполнить следующие команды, чтобы сгенерировать приложение для реагирования.

npx create-react-app hwmonitor

После завершения выполнения команды нам нужно будет создать новый каталог и скопировать в него наши сгенерированные файлы protobuf. Я создам папку proto внутри grpcstreams / webapp / hwmonitor / src / proto.

Не забудьте скопировать service_pb.js и service_grpc_web_pb.js в новую папку proto.

Самое время открыть service_pb.js. В этом файле мы видим сгенерированный объект protobuf, что важно, когда мы хотим получить доступ к данным.

Мы видим, что объект содержит 3 поля: cpu, memoryFree, memoryUsed. Итак, наши поля в нижнем регистре. Это полезно знать, поскольку нам нужны эти поля для отображения данных.

Затем мы откроем файл App.js в приложении реакции и изменим его. Он будет таким же, как и клиент на ходу, он запустит поток и распечатает данные.

После изменения вашего App.js с помощью приведенного выше кода выполните команду npm run build для сборки приложения.

npm run build

Если ваша сборка не удалась из-за того, что PROTO неизвестен, посетите эту статью, где я описываю, как исправить это в нижней части статьи.



Если ваша команда сборки NPM сработала, вы должны увидеть новый каталог с именем build. Нам нужно будет обновить main.go, чтобы разместить этот каталог в качестве файлового сервера, а также обновить его для размещения API gRPC через HTTP.

Обновление main.go

Мы обновим main.go для размещения gRPC и приложения React. Мы добавим код, который обслуживает приложение реагирования по HTTP, а также мультиплексирует gRPC в этом HTTP-соединении.

Теперь мы размещаем API как для клиента golang, так и для веб-клиента. Посетите localhost: 8080, и вы должны увидеть статистику оборудования сервера.

Об этом в этой статье. Вы узнали, как сделать свой сервер более счастливым, позволив ему передавать данные клиентам. Вместо того, чтобы все эти клиенты часто запрашивали обновления у вашего сервера. Просто надейтесь, что машин достаточно, чтобы пощадить вашу жизнь, когда они правят.

Не стесняйтесь обращаться ко мне с любыми идеями, вопросами, критикой или отзывами.

И не забудьте Следите за потоком.