天天看点

Note.js框架中的cluster集群和断言测试的实战剖析

Cluster

节点。Js在单个线程中运行单个实例。为了使用当前的多核系统,用户(开发人员)有时会使用一个Node字符串。js进程来处理加载任务。

集群模块允许轻松创建共享服务器端口的子进程。

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  console.log(`主进程 ${process.pid} 正在运行`);

  // 衍生工作进程。
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`工作进程 ${worker.process.pid} 已退出`);
  });
} else {
  // 工作进程可以共享任何 TCP 连接。
  // 在本例子中,共享的是一个 HTTP 服务器。
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('你好世界\n');
  }).listen(8000);

  console.log(`工作进程 ${process.pid} 已启动`);
}
           

第一种方法(也是除Windows以外的所有平台的默认方法)是循环方法。主进程负责侦听端口,并在接收到新连接后将连接循环分发给工作进程。发行版中使用了一些内置技术,以防止工作进程过载。

第二种方法是主进程创建侦听套接字并将其发送给感兴趣的工作进程。工作进程负责直接接收连接。

理论上,第二种方法应该是最有效的,但在实践中,由于操作系统的不可预测的调度机制,分配将变得不稳定。我们遇到过这种情况:8个进程中有2个共享70%的负载。

worker.send

向工作进程或主进程发送消息,或发送句柄。

当主进程调用此方法时,它将向特定的工作进程发送消息。另一种等效方法是ChildProcess。

当工作进程调用此方法时,它将向主进程发送消息。另一种等效方法是过程。

工作进程将回显主进程发送的消息。

if (cluster.isMaster) {
  const worker = cluster.fork();
  worker.send('hi there');

} else if (cluster.isWorker) {
  process.on('message', (msg) => {
    process.send(msg);
  });
}
           

assert 断言测试

测试实际参数是否等于预期深度参数。使用相等运算符(==)比较原始值。

只测试可枚举自身属性,而不测试对象的原型、连接器或不可枚举属性(在这些情况下使用assert.deepStrictEqual())。例如,以下示例不会引发AssertionError,因为RegExp对象的属性不可枚举:

assert.deepEqual(/a/gi, new Date());
           

映射和集合中包含的子项也将进行测试。

还将测试子对象的可枚举属性:

const assert = require('assert');

const obj1 = {
  a: {
    b: 1
  }
};
const obj2 = {
  a: {
    b: 2
  }
};
const obj3 = {
  a: {
    b: 1
  }
};
const obj4 = Object.create(obj1);

assert.deepEqual(obj1, obj1);

assert.deepEqual(obj1, obj2);

assert.deepEqual(obj1, obj3);
assert.deepEqual(obj1, obj4);
           

测试通过,两个对象相等。

Buffer (缓冲)

在ECMAScript 2015(ES6)引入TypedArray之前,JavaScript语言没有读取或操作二进制数据流的机制。Buffer类作为Node Js API引入,使其能够在TCP流或文件系统操作等场景中处理二进制数据流。

TypedArray已添加到ES6中。Buffer类更优化,更适合Node。js用例的方法实现了Uint8Array API。

Buffer类的实例类似于整数数组,但Buffer的大小是固定的,物理内存分配在V8堆之外。缓冲区的大小在创建时确定,无法调整。

Buffer类位于节点J中。它是一个全局变量,因此不需要使用require('Buffer')。缓冲器

创建一个长度为 10、且用 0x1 填充的 Buffer。

const buf1 = Buffer.alloc(10);
const buf2 = Buffer.alloc(10, 1);
const buf3 = Buffer.allocUnsafe(10);

const buf4 = Buffer.from([1, 2, 3]);

const buf5 = Buffer.from('tést');
const buf6 = Buffer.from('tést', 'latin1');
           

创建一个长度为 10、且未初始化的 Buffer。

这个方法比调用 Buffer.alloc() 更快,

但返回的 Buffer 实例可能包含旧数据,

因此需要使用 fill() 或 write() 重写。

命令行选项

$ node --zero-fill-buffers
> Buffer.allocUnsafe(5);
<Buffer 00 00 00 00 00>
           
const buf1 = new Buffer('buffer');
const buf2 = new Buffer(buf1);

buf1[0] = 0x61;
console.log(buf1.toString());

console.log(buf2.toString());
           

new Buffer

const buf = new Buffer(10);
           
const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64');
           

继续阅读