编写微服务博客-第1部分“概述”

在本文中,我想与SergeyMaslov分享我们的经验,以“创建博客”任务为例,使用微服务架构解决典型问题(希望读者可以想象博客的排列方式,而这不应引起功能性问题:)

因此,我们的博客将包含5个用golang编写的微服务:

  • 网关API(api-gw)-负责请求的路由,身份验证,日志记录和跟踪
  • 用户(用户)-用户的注册/身份验证,日志记录,请求跟踪
  • 文章(发布)-创建/读取/修改/删除文章(CRUD),记录,跟踪和授权请求
  • 评论-创建/读取/修改/删除评论(CRUD),记录,跟踪和授权请求
  • 类别(类别)-创建/读取/更改/删除类别(CRUD),记录,跟踪和授权请求

客户端应用程序(Web /前端)将在vue.js上实现,并将通过REST API与微服务交互,而微服务本身将通过gRPC相互交互。

作为存储,我们将使用MongoDB。

我们将在蛋糕上另辟show径,展示如何在积极开发的项目中以最少的工作量使API文档(大写格式)保持最新。

博客组件图


图片

每个微服务都将在单独的Docker容器中实现,并且将使用docker-compose启动该项目。

立即在示例中进行保留,以简化开发过程,我将使用两个不应在生产中使用的假设。

  • 该数据库部署在Docker容器中。 这种方法降低了存储可靠性(HighLoad 2018讨论的方案除外)。
  • 整个项目托管在一个git存储库中。 这种方法与微服务体系结构的基本原理之一(隔离)相矛盾,并增加了组件间连接的可能性。

您可以在此处查看项目的演示,并在此处查看源代码。

项目结构




如何建立开发流程


如前所述,微服务之间的交互将基于gRPC。 简而言之,gRPC是Google为调用远程过程(RPC)而开发的高性能框架-它可在HTTP / 2上运行。 GRPC基于所谓的原型文件(请参见下面的示例),其主要任务是以紧凑形式声明两件事:

  • 提供服务接口的完整列表(API接口的类似物);
  • 描述什么被馈送到每个接口的输入以及我们在输出中得到什么。

下面作为示例,给出了类别服务的原型。

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创建+将以不拘一格的格式创建最新文档;
  3. 我们所要做的只是在特殊文件/protobuf/functions.go中编写用于实现接口的代码。

此外,如果我们要更改我们的微服务之一,请按照上述算法进行操作:编辑原型文件,运行原型,然后在functions.go中编辑实现,更改将自动“保留”给文档和客户。

续上文章“在微服务上写博客,网关API的第2部分”。

Source: https://habr.com/ru/post/zh-CN473514/


All Articles