• x6_365323
  • 12.3KB
  • zip
  • 0
  • VIP专享
  • 0
  • 2022-06-14 04:35
节点分布式监控器 描述 Node.js中分布式监视器的实现。 通讯层正在使用 。 这个怎么运作 Monitor子类的所有方法都包装在关键部分和共享buffer字段中,该字段可以包含任何类型的字段,但必须字符串化为JSON。 每个进程都以发布者和订阅者的身份打开套接字,然后他们彼此倾听。 有三种类型的消息。 首先是关键部分的请求,该部分将广播到所有过程。 如果不需要访问关键部分,则每个人都会发送第二种消息。 在其他情况下,将比较其请求的时间戳。 稍后发送请求的进程将被保存到更快进程的队列中并给予许可。 从所有进程收集权限后,将授予关键节访问权限。 离开关键部分后,进程将权限发送给所有保存在队列中的人。 具有权限的消息还包含缓冲区版本号,如果该版本比接收者的版本新,则将其覆盖。 这就是进程共享缓冲区对象的方式。 在关键部分的处理过程中,可以通过wait方法来停止过程。 该方法需要一个可以称为条
  • node-distributed-monitor-master
  • yarn.lock
  • src
  • ProducerConsumerMonitor.js
  • Monitor.js
  • ZeroMQ.js
  • .gitignore
  • index.js
  • package.json
# node-distributed-monitor ## Description Implementation of Distributed Monitor in Node.js. Communication layer is using [ZeroMQ.node]( ### How it works `Monitor` child classes have all methods wrapped into critical section and share `buffer` field, which could contain any type of field, but have to be stringified into JSON. Each process open socket as a publisher and subscriber, then they listen to each other. There are three types of messages. First is request for critical section, which is broadcast to all process. Every of them send second type of message if it doesn't need access to critical section. In other case, timestamps of their request are compared. Process which send request later, is saved into queue of faster process and give it permission. After collecting permissions from all processes, critical section access is granted. After leaving critical section, process send permissions to all saved in queue. Message with permission contains also buffer version number and if is newer than receiver has, overrides it. That's how processes share buffer object. During processing in critical section process could be stopped by `wait` method. That method required string which could be called conditional variable. Stopped process is waiting for third type of message, which could be send by other process invoking `signal` method, which has same parameter string as `wait` those. ### Summary This project was especially interesting because of single thread and asynchronous nature of JavaScript. It is probably the only one public implementation of distributed monitor written in Node.js. The only way to stop processing in the middle of critical section was using async/await statement and probably many bad JavaScript programming practices like collecting promise resolvers. Because of C++ bindings of ZeroMQ.node, this project can't be run directly in browsers, but ZeroMQ could be replaces by WebSocket technology, which could make it even more powerful. Created as a project for Tools of Distributed Systems classes at [Poznań University of Technology]( ## Requirements ### Linux - Node.js 8.11.1 or higher - Python 2.7 - make - C/C++ compiler ### MacOS - Node.js 8.11.1 or higher - Python 2.7 - Xcode Command Line Tools (MacOS) - Can be installed with `xcode-select --install` ### Windows - Node.js 8.11.1 or higher - Windows Build Tools - Can be installed with `npm install -g windows-build-tools` #### Ubuntu 16.04 - Node installation ``` cd ~ curl -sL -o sudo bash sudo apt-get install nodejs -y nodejs -v git clone cd node-distributed-monitor ``` ## Usage Before first launch install dependencies via `npm` or `yarn` ``` npm install ``` Create child class of [Monitor.js]( For example: ```js const Monitor = require('./Monitor'); class ProducerConsumerMonitor extends Monitor { constructor(config) { super(config); this.buffer = { ...this.buffer } } async produce(sth) { while(this.buffer.n > 5) await this.wait('full storage'); this.buffer.n += 1; this.log(`Producing... n = ${this.buffer.n} bufforVersion=${this.buffer._version}`); if(this.buffer.n === 1) this.signal('empty storage'); } async consume(sth) { while(this.buffer.n === 0) await this.wait('empty storage'); this.buffer.n -= 1; this.log(`Consuming... n = ${this.buffer.n} bufforVersion=${this.buffer._version}`); if(this.buffer.n === 5) await this.signal('full storage'); } } module.exports = ProducerConsumerMonitor; ``` Create starting script: ```js const ProducerConsumerMonitor = require('./src/ProducerConsumerMonitor'); const monitor = new ProducerConsumerMonitor({ peers: [ // List of peers 'tcp://', 'tcp://', 'tcp://', 'tcp://', 'tcp://', 'tcp://' ], port: process.argv[3] }); = process.argv[3] % 2 ? 'producer' : 'consumer'; async function start() { let i; for (i = 0; i < 10; i++) { await new Promise((resolve, reject) => { setTimeout(() => { monitor.produce('a').then(() => resolve()); // or monitor.consume('a').then(() => resolve()); }, Math.random() * 500 + 600); }); } } start(); ``` ### Starting ``` node index.js {ip} {port} ``` ## Development To run concurrently many process on single device, add script into package.json like this: ``` "local": "concurrently \"node index.js 9312\" \"node index.js 9313\" \"node index.js 9314\" \"node index.js 9315\" \"node index.js 9316\" \"node index.js 9317\"", ``` then run it ``` npm run local ``` It's useful for development and testing.