architecture - 微服务架构 - 每个服务是否需要 API
问题描述
我一直在探索微服务架构,尽管我使用的技术是在 Microsoft Domain 中,但问题是通用的。
我得到了 API Gateway esp 的想法,比如身份验证。我大致遵循的模式是基于 CQRS + Event Sourcing
请求-> 命令##CommandBus##->CommandHandler -> 更改聚合状态-> 存储事件-> PublishDomainEvents -> 发布集成事件##Event Bus## -----> 更新读取模型
很多时候,初始命令将由 ProcessManager(消费者)处理以编排工作流。
所有微服务应用层都使用来自总线的命令并致力于更改聚合状态。完成后,读取模型存储被更新。目前,只有一个读取数据库被更新
当我开始使用命令总线时,每个微服务的 REST API 主要用于获取请求(读取),它会像所有其他服务一样进入同一个读取数据库,并休息以接受来自网关的命令。
根据我当前的场景,每个微服务都有 REST API 是否有逻辑?我知道我们可以使用 Rest API 进行异步来推送命令,但是当我已经在使用总线时有什么意义。
但现在我想的不是每个服务都有 API,而是基于使用情况的 API。它不仅限于单个网关,而是少数网关 API 项目。
这种方法有什么缺点/陷阱吗?
编辑 2 - **如果给出上下文,则尝试改写 ** 我的微服务结构非常相似(与 @mrdnk 评论的内容非常相似)。正如你在我将介绍技术以使其更加清晰。我使用 RabbitMQ 上的公共交通进行服务间通信。
到目前为止,我有客户端应用程序使用的 API 网关,然后它将调用适当的微服务 API 来推送命令对象。API 方法本身充当命令处理程序(充当应用程序层)调用聚合并使其进行更改。基于更改的领域事件使用 Mediatr 在流程中发布。外部(微服务)世界需要知道的任何事件都会在总线上发布。我开始查看通讯并对自己说,为什么不将总线也用于命令(作为命令总线)。这样我就可以有更多的弹性和异步过程。
应用层将监听命令并进行适当的处理。这样我觉得服务更加封装。在 API 方面(个人微服务)我不需要公开任何休息 api 供网关使用。Gateway 中的 API 将监听请求并创建命令对象。这将排队到公共汽车。Microservice 上的 Consumer(命令处理程序)会消费 Command 等。
目前所有的写入都是事件源的(mongodb)。读取到 SQL Server。我可以为读取端的查询创建 API。根本不再需要来自微服务的 Http API。
我知道从技术上讲它会起作用,但不知道是否有任何陷阱。
问候, 三月
解决方案
我认为让微服务彼此异步通信是个好主意,在实践中,我也会根据用例将这种方法与编排和编排结合使用。
关于您通过 Internet 向您的客户(例如 Web 客户)公开的公共 API,它实际上取决于您所获得的决定因素和选项。如果您的客户需要基于 REST 的通信,我建议通过提供它通过 Ok 和某种唯一 ID 的信息来同步地向客户提供快速响应。
因此,如果您考虑在线商店的订单请求,API 网关会将请求转发到订单微服务(通过 REST 或在您的情况下通过消息传递以及在 API 网关层从异步响应到同步响应的一些转换)。无论如何,订单服务可以提供对客户端的某种即时响应,该响应可以简单地包含新订单的 id。处理订单的其他一切都将完全通过基于事件的编排(由 OrderRequestReceived 事件或任何适合领域语言的名称开始)或通过订单服务编排的某种工作流(但仍然使用异步消息传递)异步发生.
然后,客户端可以始终使用订单 ID 来查询您将根据您正在构建的读取模型提供的订单的当前状态。
如果您可以自由地以希望的方式实现客户端,您还可以查看 WebSockets,使用 HTTP/2 来允许推送状态更改,而不是要求客户端轮询当前状态。或者你甚至可以研究 gRPC ......
推荐阅读
- tsql - 根据与列名具有相同值的字段更新一个语句中的多个列
- .net - WebRequest 默认使用哪个端口?
- android - 使用 uri 将图像存储到 Firebase 存储中
- c# - 需要帮助为 UWP 创建登录系统
- c++ - 将 Ref 对象作为类成员
- php - 保持在循环中减去值得到mysql结果php
- ruby-on-rails - 如何仅将 link_to 应用于 content_tag 中的部分文本?
- task - 气流任务失败,没有空日志并且不发送电子邮件
- qt - 如何在可执行文件附近安装 qt 库
- javascript - 从 angularjs 控制器替换 url 栏中的现有 url