通信间微服务 - 如何?

时间:2017-01-13 14:14:59

标签: node.js web-services rest rabbitmq microservices

我正在开展一个个人项目,即将单片Web应用程序转换为微服务(每个服务都有自己的数据库)。

此时单片后端由NodeJS制作,能够回复REST请求。 当我开始将应用程序拆分为多个服务时,我遇到了下一个问题:如何很好地进行它们之间的通信?

首先,我尝试在下一个示例中使用 REST调用: “注册服务”将有趣的东西插入其数据库,然后将用户信息转发(HTTP POST)到“用户服务”,以便将其保存到“用户”数据库中。 从这个例子中我们有2个服务,因此有2个数据库。

此时我意识到这不是一个好选择。因为我的“注册服务”取决于“用户服务”。它们是耦合的,这是微服务概念的反模式(从我读到的内容)。

第二个想法是使用像RabbitMQ这样的消息代理。 “注册服务”仍然将有趣的东西插入到自己的数据库中,并将用户信息作为数据发布到队列中。 “用户服务”使用此消息并将数据持久保存到其“用户”数据库中。通过使用这个概念,两种服务都是完全孤立的,可能是个好主意。

但是,发送给客户的响应如何(谁发出了“注册服务”请求)。根据第一个想法,我们可以发送“200,一切都好!”或400.这不是问题。根据第二个想法,我们不知道消费者(“用户服务”)是否持久保存用户数据,那么我需要回复客户端?

我对网络应用程序的商店方面存在同样的问题。客户将他想要购买的产品发布到“订购服务”。如果用户有足够的钱,这个需要检查他已经进入“用户服务”的虚拟货币然后将产品细节转发到“交付服务”。如何通过完全隔离的服务实现这一目标?

我不想使用客户端的http请求时间在消息代理上进行异步请求/回复。

我希望你们中的一些人能够启发我。

3 个答案:

答案 0 :(得分:1)

Tom建议pretty good link,其中推荐和解决方案的最高投票答案是您可以信赖的答案。您的具体问题可能源于注册服务和用户服务是分开的。也许他们不应该?

理想情况下,注册服务应该发布" UserRegistered"事件到公共汽车,返回200,仅此而已。它根本不应该关心(知道)该事件的任何订阅者。

答案 1 :(得分:1)

使用棚,它会摇晃!认真地。 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);
});

答案 2 :(得分:0)

感谢您提供此链接,

我的问题将我所拥有的架构转变为新的架构。对于那些遇到同样问题的人来说,由于这个链接我做了一些事情:

  • 将注册服务和用户服务结合在一起。为什么?因为这完全取决于用户信息(相同的数据库要求),这是Illiakaill给出的解决方案。

  • 将用户资金管理分为"电子钱包"只存在于"订购服务"。多亏了这一点,我们不需要在执行订单时检索用户信息,我们只需要检查钱包信息。 (当用户执行身份验证时,我在JWT中对用户名进行了编码。因此,我可以在我的钱包中使用用户名作为外键来识别正在提供或使用的钱包等。)

正如您所看到的,我不再使用消息经纪人了,因为现在我不需要消息经纪人。但我可以将邮件逻辑拆分成一个新的微服务,然后使用消息代理通过我所有的微服务发送邮件,如果需要的话。

告诉我,如果我错了,但这听起来不错。