这是文章“ 我们正在通过RabbitMQ进行通信的Node.js上编写第一个微服务 ”的续篇,受到了Habr用户的好评。
在本文中,我将讨论如何在微服务之间正确通信,以使微服务保持隔离。
怎么不做
为什么需要在微服务之间进行通信? 使用一个数据库,从那里读取您想要的东西-做点事!
不,你不能那样做。 微服务的概念是它们彼此隔离,没有人了解任何人(实际上)。 将来很有可能,当系统开始增长时,您将需要扩展功能,并且需要在微服务之间进行通信:例如,用户购买了产品,因此您需要将有关销售的通知发送给卖方。
保温好处
可靠度
假设有一个单片应用程序,其中有多个控制器:
- 产品展示
- 打折
- 博客
- 用户数
好的一天,我们的数据库将要崩溃:现在我们找不到任何产品,没有折扣,没有博客文章,也没有用户。 该站点完全不可用,客户无法登录,业务损失了利润。
微服务架构会发生什么?
在另一个世界中,在用户微服务数据库崩溃的同一天,它变得不可访问:用户无法注销,注册和登录。 似乎一切都不好,企业也正在亏损,但是没有:潜在的买家可以查看可用的商品,阅读公司的博客并找到折扣。
由于每个微服务都有其自己的数据库,因此副作用要小得多。
这称为逐渐退化 。
抽象化
在大型应用程序中,很难集中精力完成一项任务,因为更改某些小型中间件可能会破坏某种控制器。 想要使用新客户端进行Redis-不,您不能,我们三年前编写的控制器使用版本0.1.0。 是否想最终利用Node.js 10的新功能? 还是12岁? 抱歉,但整体使用版本6。
如何沟通
由于我们已经开始讨论示例“用户购买了产品,因此我们向卖方发送了销售通知”,因此我们将其实施。
该方案如下:
- 用户向微服务市场发送请求以在链接/市场/购买/:id上购买商品
- 该标志写在销售产品的数据库中
- 从微服务市场,将请求发送到微服务通知,客户端通过WebSocket与之连接
- 微服务通知向卖家发送有关商品销售的消息
安装MicroMQ
$ npm i micromq@1 -S
编写网关
const Gateway = require('micromq/gateway');
我们的网关仅包含一个端点,但这足以作为示例和培训。
编写微服务通知
const MicroMQ = require('micromq'); const WebSocket = require('ws');
在这里,我们同时提高了Web套接字服务器和微服务,以接收对Web套接字和RabbitMQ的请求。
该方案如下:
- 用户连接到我们的Web套接字服务器
- 通过发送内部包含其userId的
authorize
事件来授权用户 - 我们保持用户的联系,以便您以后可以向他发送通知
- 事件到达RabbitMQ,您需要向用户发送通知
- 检查传入数据的有效性
- 获取用户连接
- 发送通知
编写微服务市场
const MicroMQ = require('micromq'); const { Items } = require('./api/mongodb');
该方案如下:
- 我们收到用户购买物品的请求
- 我们正在寻找具有正确ID的商品,并确保尚未出售
- 将商品标记为已出售
- 我们会在后台向卖家发送有关销售的通知
- 我们回应客户
检查一下
- 我们开始3个过程
- 我们将发送POST /市场/购买/ 1
- 我们得到了回应
{ ok: true }
- 卖家收到通知
$ PORT=9000 node ./src/gateway.js $ PORT=9001 node ./src/notifications.js $ MONGODB_URL=mongodb://localhost:27017/my-super-microservice node ./src/market.js
