Node中消息模式:发布者(pub)/订阅者(sub)模式、请求(rep)/响应(req)模式、推送(push)/拉取(pull)模式、ROUTER/DEALER模式。另外简单介绍Node集群

安装ZeroMQ

你可能会问,为什么不直接使用socket,而使用ØMQ呢?

因为Node.js社区信奉Unix哲学:一次只做好一件事

Node.js贡献者们尽量保持Node.js代码的轻量、简洁。把其他更上层的事情留给开发者去解决。

 

使用ØMQ的好处是:

  • 网络异常导致连接中断,ØMQ会自动新建连接

  • 保证发送完整消息,无需处理分块发送情况

  • 开销低却能包含很多必要细节,如把响应发送回正确的请求方

npm install --save --save-exact zeromq

如果你像我一样安装过程中遇到了未响应的“异常”:

Mac中npm安装zeromq时安装不成功,一直等待不结束(node scripts/prebuild-install.js || (node scripts/preinstall.js && no)

 请移步该问题的处理方法

现在安装好了,开始写代码吧!

各个模式

发布者(pub)/订阅者(sub)模式

其实就类似于广播电台,电台总部相当于发布者,负责向外发送数据,订阅者相当于FM收音机,设定固定频率收到广播信号。

Pub/Sub

This example demonstrates using zeromq in a classic Pub/Sub, Publisher/Subscriber, application.

Publisher: pubber.js

// pubber.js
var zmq = require("zeromq"),
  sock = zmq.socket("pub");

sock.bindSync("tcp://127.0.0.1:3000");
console.log("Publisher bound to port 3000");

setInterval(function() {
  console.log("sending a multipart message envelope");
  sock.send(["kitty cats", "meow!"]);
}, 500);

Subscriber: subber.js

// subber.js
var zmq = require("zeromq"),
  sock = zmq.socket("sub");

sock.connect("tcp://127.0.0.1:3000");
sock.subscribe("kitty cats");
console.log("Subscriber connected to port 3000");

sock.on("message", function(topic, message) {
  console.log(
    "received a message related to:",
    topic,
    "containing message:",
    message
  );
});

请求(rep)/响应(req)模式

先有请求进来,再有响应出去,一个接一个,如果有更多请求进来,就会进入到请求队列,由ZeroMQ依次处理。应用程序每次只处理一个请求。

每次结点只处理一个事件,没有并行处理的能力,因此这种模式不适合对性能要求较高的场景。

Rep/Req

rep.js

//rep.js
const zmq = require('zeromq');

const responder = zmq.socket('req');

responder.on('message',data=>{
   //接受请求的数据
    console.log(data);

    //向外响应数据
    responder.send('响应器的数据');
});

responder.bind('tcp://127.0.0.1:60401',error => {
    console.log('Listening for zmq requesters')
});

req.js 

//req.js
const zmq = require('zeromq');

const requester = zmq.socket('req');

requester.on('message',data=>{
   //处理响应的内容
    console.log(data);
});

requester.bind('tcp://127.0.0.1:60401');

requester.send('发送请求');

推送(push)/拉取(pull)模式

这个就相当于github上push和pull,你给我,或者我给你,并不返回数据。

但你有个任务队列,当你要把任务分给多个工作进程时,这个模式就非常适用。

Push/Pull

This example demonstrates how a producer pushes information onto a socket and how a worker pulls information from the socket.

producer.js

// producer.js
var zmq = require("zeromq"),
  sock = zmq.socket("push");

sock.bindSync("tcp://127.0.0.1:3000");
console.log("Producer bound to port 3000");

setInterval(function() {
  console.log("sending work");
  sock.send("some work");
}, 500);

worker.js

// worker.js
var zmq = require("zeromq"),
  sock = zmq.socket("pull");

sock.connect("tcp://127.0.0.1:3000");
console.log("Worker connected to port 3000");

sock.on("message", function(msg) {
  console.log("work: %s", msg.toString());
});

ROUTER/DEALER模式

ROUTER socket可以简单的理解为Rep socket并发版。

DEALER 可以理解为并行的req,可以并行发出多个请求。

const router = zmq .socket('router');
const dealer = zmq.socket('dealer');
router.on('message',(...frames)=>dealer.send(frames));
dealer.on('message',(...frames)=>router.send(frames));

这种方式,我们创建了一个传输管道,如图所示的消息传输架构。

ROUTER/DEALER架构

方框代表我们开发的Node.js程序。首先REQ socket连接到ROUTER,当REQ发出请求时,ROUTER把这个请求转发给DEALER,然后DEALER从它的连接的REP中选择一个,并把请求发送过去。

当REP产生响应信息时,则按照相反的路径把消息返回回去。当DEALER接收到应答消息时,把它转发给ROUTER,然后ROUTER根据消息的帧记录来源数据决定返回给哪个REQ。

Node.js集群

cluster模块

可以使用Node.js内置的cluster模块创建子进程,这个过程称为clustering,创建合适数量的Node.js进程可以充分利用多核CPU的资源。

引入cluster模块,可以通过fork()创建工作进程,通过一系列事件和主进程通信即可。

集群结构图

图片解释了集群中各个部分是如何分工的,中间方框表示 Node.js进程,椭圆形表示socket绑定的资源,连接线指明了各个socket与节点之间的连接关系。

简单来说,就是客户端访问服务器数据时,不再仅限一个服务器主进程,分发到了各个工作进程去处理事件,应用程序实现了多进程工作分配的功能,主进程也起到了负载均衡的作用。

发布了122 篇原创文章 · 获赞 25 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/HuoYiHengYuan/article/details/100976415