Пишем блог на микросервисах – часть 1 «Общее описание»

в 17:01, , рубрики: Go, golang, grpc, grpc-gateway, proto3, rest, X5RetailGroup, микросервисы

В этой статье хочу поделится нашими c SergeyMaslov наработками решения типовых задач с использованием микросервисной архитектуры на примере задачи «создание блога» (в надежде, что читатель представляет как устроен блог и это не должно вызывать вопросов по функциональности:)

Итак, наш блог будет состоять из 5 микросервисов, написанных на golang:

  • API Gateway (api-gw) – отвечает за маршрутищацию, аутентификацию, логирование и трасировку запросов
  • Пользователи (user) – регистрация/аутентификация пользователей, логирование, трасировка запросов
  • Статьи (post) – создание/чтение/изменение/удаление статей (CRUD), логирование, трасировка и авторизация запросов
  • Комментарии (comment) – создание/чтение/изменение/удаление комментариев (CRUD), логирование, трасировка и авторизация запросов
  • Категории (category) – создание/чтение/изменение/удаление категорий (CRUD), логирование, трасировка и авторизация запросов

Клиентское приложение (web/frontend) будет реализован на vue.js и будет взаимодействовать с микросервисами через REST API, а сами микросервисы будут взаимодействовать друг с другом по gRPC.

В качестве хранилища мы будем использовать MongoDB.

Отдельной вишенкой на торте покажем, как с минимальными трудозатратами поддерживать документацию API (в формате swagger) в актуальном состоянии в активно развивающемся проекте.

Компонентная схема блога

image

Каждый микросервис будет реализован в отдельном Docker контейнере, а запуск проекта будет осуществляться с помощью docker-compose.

Сразу оговорюсь в примере, для упрощения процесса разработки, буду использовать два допущения, которые не следует использовать в продакшене.

  • База данных развернута в Docker контейнере. Такой подход снижает надежность хранилища (за исключением схемы, о которой говорилось на HighLoad 2018).
  • Весь проект размещен в одном git-репозитории. Этот подход противоречит одному из основных принципов микросервисной архитектуры — изолированность, и увеличивает вероятность появления межкомпонентной связанности.

Демо проекта можно посмотреть здесь, а исходный код здесь.

Структура проекта

Пишем блог на микросервисах – часть 1 «Общее описание» - 2

Как будет построен процесса разработки

Как я уже ранее говорил, взаимодействие между микросервисами будет построено на основе gRPC. В двух словах gRPC это высокопроизводительный фреймворк, разработанный компанией Google, для вызова удаленных процедур (RPC) — работает поверх HTTP/2. В основе gRPC лежит так называемый протофайл (см. пример ниже), основная задача которого в компактной форме задекларировать две вещи:

  • дать полный перечень интерфейсов сервиса (аналог API интерфейсов);
  • описать что подается на вход каждого интерфейса и что получаем на выходе.

Ниже, в качестве примера, приведен протофайла сервис Category.

syntax = "proto3";
package protobuf; 
import "google/api/annotations.proto";

//Описание интерфейсов сервиса Category
service CategoryService {
 
  //Создание записи
  rpc Create (CreateCategoryRequest) returns (CreateCategoryResponse) {
    option (google.api.http) = {
      post: "/api/v1/category"
    };
  }              

  //Обновление записи
  rpc Update (UpdateCategoryRequest) returns (UpdateCategoryResponse) {
    option (google.api.http) = {
      post: "/api/v1/category/{Slug}"
    };
  }     

  //Удаление записи
  rpc Delete (DeleteCategoryRequest) returns (DeleteCategoryResponse) {
    option (google.api.http) = {
      delete: "/api/v1/category/{Slug}"
    };
  }     

  //Возвращает запись по SLUG
  rpc Get (GetCategoryRequest) returns (GetCategoryResponse) {
    option (google.api.http) = {
      get: "/api/v1/category/{Slug}"
    };
  }     

  //Писк
  rpc Find (FindCategoryRequest) returns (FindCategoryResponse) {
    option (google.api.http) = {
      get: "/api/v1/category"
    };
  }                    

}

//------------------------------------------
//  CREATE
//------------------------------------------
message CreateCategoryRequest {
  string ParentId = 1;
  string Name = 2;
  string Path = 3;
}
message CreateCategoryResponse {
  Category Category = 1;
}

//------------------------------------------
//  UPDATE
//------------------------------------------
message UpdateCategoryRequest {
  string Slug = 1;
  string ParentId = 2;
  string Name = 4;
  string Path = 5;
  int32 Status = 6;
}
message UpdateCategoryResponse {
  int32 Status =1;
}

//------------------------------------------
//  DELETE
//------------------------------------------
message DeleteCategoryRequest {
  string Slug = 1;
}
message DeleteCategoryResponse {
  int32 Status =1;
}

//------------------------------------------
//  GET
//------------------------------------------
message GetCategoryRequest {
  string Slug = 1;
}
message GetCategoryResponse {
  Category Category = 1;
}

//------------------------------------------
//  FIND
//------------------------------------------
message FindCategoryRequest {
  string Slug = 1;
}
message FindCategoryResponse {
  repeated Category Categories = 1;
}


//------------------------------------------
//  CATEGORY
//------------------------------------------
message Category {
  string Slug = 1;
  string ParentId = 2;
  string Path = 3;
  string Name = 4;
  int32 Status = 5;
}

Теперь, когда мы в общих чертах разобрались зачем нужен протофайл, посмотрим как будет выглядеть процесс разработки наших микросервисов:

  1. Описываем структуру сервис в протофайле;
  2. Запускаем генератор кода (./bin/protogen.sh), он сгенерит нам основную часть серверного кода + создаст клиентский код, например, для API Gateway + создаст актуальную документацию в формате swagger;
  3. Все что нам останется сделать своими руками, это написать код реализацию интерфейсов в специальном файле /protobuf/functions.go.

Далее, если мы захоти внести изменения в один из наших микросервисов, действуем по вышеописанному алгоритму: правим протофайл, запускаем protogen, правим реализацию в functions.go, а в документацию и к клиентам изменения “уедут” автоматически.

Продолжение в статье «Пишем блог на микросервисах часть 2 API Gateway».

Автор: Ptimofeev

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js