rest - 我们的微服务设计错了吗?
问题描述
在我们的项目中,我们使用的是微服务,每个微服务都在对同一个第三方服务进行休息调用。据我所知,我们应该像ms1 -> ms2
, where那样进行休息调用ms2 -> 3rd party api
,而不是直接从ms1 -> 3rd party api
.
那么,我们做错了吗?还是我的假设是错误的?
我们所有的微服务都在使用相同的 3rd 方 api。您认为我们可以在这种情况下应用事件溯源和 cqrs 的概念吗?或者您认为我们可以在这种情况下应用消息系统概念来改进架构吗?
你对架构有什么建议?
编辑:
3)我在上面问过 bcoz 的原因是,我的大多数微服务都使用 for 循环并在每个 for 循环内对 3rd 方 api 进行休息调用,这意味着性能会降低。我在想,如果我们的每个微服务中都有一些数据库,那么每当我们进行任何 GET 3rd 方休息 api 调用时,我们就可以将该响应保存在数据库本身中。稍后在进一步请求时,将首先检查 db 中是否存在数据,如果存在,则从 db 中返回数据,否则进行 rest 调用并再次将新数据保存到相应的微服务 db 中。我的想法错了吗?
4)让休息调用更快还是从数据库中检索数据更快?对不起,如果它是一个愚蠢的查询..
解决方案
虽然我不认为您所做的事情本质上是错误的,但您需要考虑许多事情:
- 时间耦合/可用性:如果在单个过程中多次重复调用第三方服务,则存在不可用性增加的风险
- 服务边界:如果一个服务需要来自另一个服务的数据,那么数据所有权真的正确吗?保存数据的服务需要,还是使用所有数据,还是只使用一小部分数据?
我建议您阅读微服务应该是自治的,它更详细地涵盖了上述几点。
至于消息传递,我强烈推荐那些可用性非常重要的消息。使用异步通信将解决时间耦合问题(一个服务无法实现其功能,而另一个服务没有响应),这会立即提高可用性,但代价是更高的窗口不一致或响应陈旧数据。处理稍微陈旧的数据的实际业务影响(根据经验)不存在,但您需要了解这一事实以避免意外。
事件溯源是我在某些情况下强烈推荐的一种方法,但它确实是有代价的,并且有很多陷阱,所以我不推荐它作为默认方法。它可以产生令人惊讶的准确结果,启动后出现极少数错误,但您需要:
- 直接联系领域专家,他们乐于与开发团队合作
- 一个乐于与领域专家并肩工作的开发团队
- 在使用普通表单存储或文档存储时,我们对数据的看法发生了转变
- 虽然 DDD 不是必需的,但它确实使发现过程更加容易和安全,所以我强烈建议您至少了解它。
更新(地址编辑)
关于您的第 4 点:这取决于您的设计\架构,但很可能,访问本地数据库而不是进行远程调用会更快。您可以使用相同的缓存策略来访问两个微服务中的数据(如果性能需要的话),但是您需要通过额外的网络调用来访问删除微服务。
关于您的第 3 点:我已经建议的内容没有任何变化。调用远程服务的次数越多,时间耦合的影响就越大,因此将数据保留在服务之外会使情况变得更糟。边界论点再次适用于类似的程度:如果您需要另一个服务中的数据,也许您应该考虑数据需要属于使用它的第二个微服务的可能性,或者 部分数据属于一个微服务和一些其他部分属于其他部分。
总的来说,我曾经(现在仍然)建议您保留执行操作所需的数据子集的本地副本,尤其是在这是一种常见操作的情况下。
推荐阅读
- vue.js - Vue 的仅运行时构建到底是什么,它与编译器构建有何不同?
- c# - Razor Pages .Net Core - 从 Javascript / AJax 调用 C# 方法
- html - 如何防止网格与页面标题重叠并在调整视口大小时避免滚动条?
- c - 错误:非 void 函数不会在所有控制路径中返回值
- python - 在 Python 中获取 Unix 时间
- usb - 使用 Pi Zero W 模拟 HID 键盘和鼠标
- css - 调整浏览器大小时,在页面上反应侧边栏导航重叠信息
- json - NPM 命令返回错误:package.json 必须是实际的 JSON,而不仅仅是 JavaScript
- reactjs - 在 REACT 中下拉 Gitlab Repo 信息
- bash - Osascript 自定义函数无法正确解释命令字符串