node js 多线程

一、前提

我以前只认为node js 只能单线程,我自己用了一段时间electron 桌面开发,如果遇到CPU密集型业务怎么做呢?我不可能只靠一个CPU来搞业务啊,这个限制不是太大了?

二、解决方法

1:多进程

child_process

等模块创建多进程

这种打补丁方法不是很好,涉及进程通信,写代码效率不高,很容易出现bug。开发者很可能出现变量无法访问的问题,因为多个进程,变量没有共享。不过业务写很分开,也问题不大,多进程资源比较大。

2:多线程

worker_threads

真正用的是多线程,我自己写代码测试,不停创建worker_threads..

测试代码

const { Worker, isMainThread, parentPort } = require('worker_threads');
console.log("hello world:" + isMainThread)

/*if (isMainThread) {
  // This code is executed in the main thread and not in the worker.
  
  // Create the worker.
  const worker = new Worker(__filename);
  // Listen for messages from the worker and print them.
  worker.on('message', (msg) => { 
      console.log(msg); 
    });
} else {
  // This code is executed in the worker and not in the main thread.
  
  // Send a message to the main thread.
  parentPort.postMessage('Hello world!');
}*/

function test(){
    if(isMainThread){
      console.log("自动线程哦");
      const worker = new Worker("./work.js");
    }
   
}

setInterval(() => {
  test();
}, 1000);

通过定时器不停创建工程线程。

work.js

const { isMainThread, parentPort,Worker, threadId } = require('worker_threads');



const min = 2
const max = 1e7

function generatePrimes(start, range) {
    let primes = []
    let isPrime = true
    let end = start + range
    for (let i = start; i < end; i++) {
      for (let j = min; j < Math.sqrt(end); j++) {
        if (i !== j && i%j === 0) {
          isPrime = false
          break
        }
      }
      if (isPrime) {
        primes.push(i)
      }
      isPrime = true
    }
    return primes
 }


console.log("线程id:" + threadId)
generatePrimes(1, 10000000)
console.log("线程id:" + threadId + " 完成")

可以通过资源管理器查看线程【默认不显示,自己设置一下】,线程数不停增加

可以不停增加,因为我这个写法,会很快把cpu吃死。。。。如果像以前nodejs 普通写法,最多只能吃一个CPU..


注意在线程里面不要直接访问对象,毕竟node js 模式就是异步+主线程,引入多线程导致更多问题,多线程仅仅执行,然后丢回主线程即可。

node request 设置代理

一、背景

自己用node request 请求 http 发现请求无法正确应答,我用fidder抓包没有抓对应数据包,因为默认node 不会走 windows 默认代理。

二、解决过程

在request 构建增加参数 proxy: 'http://127.0.0.1:8888'

这个设置代理到fidder里面去,如果非HTTPS 可以直接用wireshark来抓包。

三、补充

如果是第三方程序,如果不会默认走代理,可以用proxifier, 这个软件出来很多年,自己可以百度下载,官方可以试用30天。

proxifier过滤指定进程名字,然后转发443 80 端口数据包到fiddler上面,这样子就可以抓任何程序的包,无论他支不支持代理。

java 压缩的二进制数据传递给node js处理问题

一, 背景

自己压缩android 截图数据压缩然后网络传递给我node程序,然后发现node 无法解压。

二,排错过程

打印java 压缩的二进制数据数组,打印node收到 buffer,发送java数组函数负数,而node 得到没有负数

三,思考

看到这个2边数据不一样,我就想起来是什么导致。java byte 是 -128~127,node byte是 0~255. 这样子导致数据对不上,我要说一点二进制数据是一样的。这个只是node 读同样的二进制,解析数据0~255范围[byte],java虚拟机解析~128-127。这个就跟我们传送数据,会出现大端和小端问题一样,必须保证2边一致。。。。

四,解决

我直接在NODE 处理每个字节 var c = buffer[i] & 0xff 即可