相互通信的微服务 - 如何?
Posted
技术标签:
【中文标题】相互通信的微服务 - 如何?【英文标题】:Inter-communication microservices - How? 【发布时间】:2017-05-28 22:34:54 【问题描述】:我正在从事一个个人项目,该项目是将单体 Web 应用程序转换为微服务(每个服务都有自己的数据库)。
此时,单体后端是用 NodeJS 制作的,并且能够回复 REST 请求。 当我开始将应用程序拆分为多个服务时,我面临下一个问题:如何使它们之间的通信良好?
首先我尝试在下一个示例中使用 REST 调用: “注册服务”将有趣的东西插入其数据库,然后将用户信息转发(HTTP POST)到“用户服务”,以便将其持久化到“用户”数据库中。 在此示例中,我们有 2 个服务,因此有 2 个数据库。
此时我意识到这不是一个好的选择。因为我的“注册服务”依赖于“用户服务”。它们有点耦合,这是微服务概念的反模式(从我读到的内容)。
第二个想法是使用像 RabbitMQ 这样的消息代理。 “注册服务”仍然在自己的数据库中插入有趣的东西,并以用户信息作为数据在队列中发布消息。 “用户服务”使用此消息并将数据保存到其“用户”数据库中。通过使用这个概念,这两个服务都是完全隔离的,这可能是一个好主意。
但是,如何将响应发送给客户端(向“注册服务”发出请求)。有了第一个想法,我们可以发送“200,一切都好!”或400。这不是问题。有了第二种思路,我们不知道消费者(“用户服务”)是否持久化了用户数据,那我需要回复客户端什么呢?
我在 Web 应用程序的商店方面遇到了同样的问题。客户将他要购买的产品发布到“订单服务”。这个人需要在“用户服务”中检查他拥有的虚拟货币,然后如果用户有足够的钱,则将产品详细信息转发给“交付服务”。如何使用完全隔离的服务来做到这一点?
我不想使用来自客户端的 http 请求时间在消息代理上发出异步请求/回复。
希望大家多多指教。
【问题讨论】:
阅读:***.com/questions/30213456/… 【参考方案1】:Tom 建议了pretty good link,其中推理和解决方案获得最高票数的答案是您可以信赖的答案。您的具体问题可能源于注册服务和用户服务是分开的。也许他们不应该?
理想情况下,注册服务应该将“UserRegistered”事件发布到总线并返回 200,仅此而已。它根本不应该关心(知道)该事件的任何订阅者。
【讨论】:
【参考方案2】:感谢您提供此链接,
我的问题将我拥有的架构变成了一个新架构。对于那些和我有同样问题的人,我通过这个链接做了一些事情:
将注册服务和用户服务结合在一起。为什么 ?因为这一切都取决于用户信息(相同的数据库要求)这就是 Illiakaill 我给出的解决方案。
将用户资金的管理分离到一个只存在于“订单服务”中的“钱包”中。因此,我们在执行订单时不需要检索用户信息,我们只需要检查钱包信息即可。 (当用户执行身份验证时,我将用户名编码在 JWT 中。因此我可以在我的钱包中使用用户名作为外键来识别正在提供或使用哪个钱包等)
如您所见,我不再使用消息代理,因为目前我不需要。但我可以将邮件逻辑拆分成一个新的微服务,然后在需要时使用消息代理通过我的所有微服务发送邮件。
如果我错了,请告诉我,但这对我来说听起来很棒。
【讨论】:
把它们放在一起?那么让我们再次将所有内容整合到 Monolithic 中......【参考方案3】:使用 cote,它会摇滚!严重地。 https://github.com/dashersw/cote
在 time-service.js 中...
const cote = require('cote');
const timeService = new cote.Responder( name: 'Time Service' );
timeService.on('time', (req, cb) =>
cb(new Date());
);
在client.js中...
const cote = require('cote');
const client = new cote.Requester( name: 'Client' );
client.send( type: 'time' , (time) =>
console.log(time);
);
【讨论】:
以上是关于相互通信的微服务 - 如何?的主要内容,如果未能解决你的问题,请参考以下文章