首页 > 系统相关 >4-3 基于缓存 + Node 多进程实现动态命令加载和执行

4-3 基于缓存 + Node 多进程实现动态命令加载和执行

时间:2022-11-25 15:25:02浏览次数:65  
标签:Node 缓存 const log process js child console 加载

1 node 多进程开发

1.1 进程(在操作系统中如何查看进程的嵌套关系)

1. 什么是进程(Process)

进程是计算现中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础

  • 进程的概念主要有两点
    1. 进程是一个实体, 每一个进程都有它自己的地址空间
    2. 进程是一个“执行中的程序”, 存在嵌套关系
  • child_process 中创建的进程就是 node.js 的子进程

1.2 child_process 用法

node 创建子进程的方法

  • 异步
    • exec
    • execFile
    • fork
    • spawn
  • 同步
    • execSync
    • execFileSync
    • spawnSync
// support.js
console.log("进程 " + process.argv + " 执行" );

1.3 child_process 异步方法

1. exec

  • child_process.exec(file[, args][, option][, callback])
  • 衍生 shell,然后在该 shell 中执行 command,缓冲任何生成的输出
cp.exec('node ' + path.resolve(__dirname, 'support.js'), {
  cwd: path.resolve('..') // 改变当前执行路径
}, (err, stdout, stderr) => {
  console.log('err', err);
  console.log('stdout', stdout);
  console.log('stderr', stderr);
})

2. execFile

  • child_process.execFile(command[, option][, callback])
  • 默认不衍生 shell, 指定的可执行文件 file 直接作为新进程衍生
cp.execFile(path.resolve(__dirname, 'support.js'), (err, stdout, stderr) => {
  console.log('err', err);
  console.log('stdout', stdout);
  console.log('stderr', stderr);
})

3. spawn

  • child_process.spawn(command[, args][, options])
  • 使用给定的 commandargs 中的命令行参数衍生新进程
const child = cp.spawn(path.resolve(__dirname, 'support.js'), ['-al', '-bl'], {
  cwd: path.resolve('..') // 改变当前执行路径
})
child.stdout.on('data', chunk => {
  console.log('stdout', chunk.toString());
})
child.stderr.on('data', chunk => {
  console.log('stderr', chunk.toString());
})
spawn 跟 exec/execFile 的区别
  • spawn: 耗时任务(比如 npm stall) 需要不断日志
  • exec/execFile:开销比较小的任务

4. fork

  • child_process.fork(modulePath[, args][, options])
  • 专门用于衍生新的 Node.js 进程

fork: Node(main) -> Node(child)

  1. child_process.spawn() 一样,返回 ChildProcess 对象
const child = cp.fork(path.resolve(__dirname, 'child.js'))
  1. 返回的 ChildProcess 将有额外的内置通信通道,允许消息在父进程和子进程之间来回传递
// index.js
child.send('hello child process', () => {
  // child.disconnect() // 结束等待状态
})
child.on('message', msg => {
  console.log('main msg', msg);
})
console.log('main pid:', process.pid);
// child.js
console.log('child pid:', process.pid);

process.on('message', msg => {
  console.log('child msg', msg);
})
process.send('hello main process')

1.4 child_process 同步方法

execSync | execFileSync | spawnSync

const res1 = cp.execSync('node ' + path.resolve(__dirname, 'support.js'))
const res2 = cp.execFileSync(path.resolve(__dirname, 'support.js'))
const res3 = cp.spawnSync(path.resolve(__dirname, 'support.js'))
console.log(res1.toString());
console.log(res2.toString());
console.log(res3.stdout.toString());

2 对 Node.js cluster 模块进行原理分析,说出你的理解

题目描述

  • 通过前面章节的学习,相信大家对 Node.js child_process 创建子进程的原理有了深入理解
  • 我们知道 Node.js 实例运行在单个线程中,为了充分利用多核 CPU 资源,有时需要启用一组 Node.js 讲程去外理负载任务
  • Node.js 为我们提供了 cluster 内置库去完成这项工作,而 cluster 创建子进程的方式就是利用 child_processfork 方法
  • 这里请大家学习 cluster 的使用方法,并尝试分析 cluster.fork 方法的源码

关键提炼

  1. Node.js 内置库 cluster

  2. cluster.fork 源码

  3. cluster.fork 源码实现关键是通过 createWorkerProcess 方法创建子进程,并通过 EventEmitter 完成父子进程通信

  4. 第二周中我们讨论过 Node.js 事件循环 process.nextTick 方法的应用,cluster.fork 方法中就有且体实践,[源码](httns://aithub com/nodeis/node/blob/v14 15 4/lib/
    nternal/cluster/masteris#1225)

3. Node 多进程实现动态命令加载和执行

3.1 利用 Node 多进程动态执行命令(stdio的inherit属性讲解)

  • core>exec>lib>index.js
const cp = require('child_process')
async function exec() {
  // ...
  const rootFile = pkg.getRootFilePath()
  if(rootFile) {
    // requie() -> node 子进程中调用
    try {
      const code = ''
      const child = cp.spawn('node', ['-e', code], {
        cwd: process.cwd(),
        stdio: 'inherit' // 打印动画信息
      })
      child.on('error', e => {
        log.error(e.message);
        process.exit(1)
      })
      child.on('exit', e => {
        log.verbose('命令执行成功:' + e) // 0 表示命令成功退出
        process.exit(e)
      })
    } catch(e) {
      log.error(e.message)
    }
  }
}

3.2 生成Node 多进程动态执行代码

  • core>exec>lib>index.js
const cp = require('child_process')
async function exec() {
  // ...
  const rootFile = pkg.getRootFilePath()
  if(rootFile) {
    try {
      const args = Array.from(arguments)
      const cmd = args[args.length - 1]
      const o = Object.create(null) // 对cmd 进行瘦身
      Object.keys(cmd).forEach(key => {
        if(cmd.hasOwnProperty(key) && 
           !key.startsWith('_') &&
           key !== 'parent') {
          o[key] = cmd[key]
        }
      })
      args[args.length - 1] = o
      const code = require(rootFile).call(null, JSON.stringify(args))
      // ...
    } catch(e) {
      log.error(e.message)
    }
  }
}
  • commands>init>lib>index.js
class InitCommand extends Command {
  init() {
    this.projectName = this._argv[0] || ''
    this.force = !!this._argv[1].force
    log.verbose('projectName', this.projectName);
    log.verbose('force', this.force);
  }
  exec() {
    console.log('init 的业务逻辑');
  }
}

3.3 windows 操作系统 spawn 执行命令兼容

  • core>exec>lib>index.js
function spawn(command, args, options) {
  const win32 = process.platform === 'win32'
  const cmd = win32 ? 'cmd' : command
  const cmdArgs = win32 ? ['/c'].concat(command, args) : args
  return cp.spawn(cmd, cmdArgs, options || {})
}

标签:Node,缓存,const,log,process,js,child,console,加载
From: https://www.cnblogs.com/pleaseAnswer/p/16925263.html

相关文章

  • 【iOS-Cocos2d游戏开发之九】讲解CCSpriteBatchNode与TP工具的
    ​​ 李华明Himi ​​​原创,转载务必在明显处注明       前几节由于时间紧张,只是将一些遇到的问题拿出来进行分享经验,那么今天抽空写一篇常用的精灵以及精......
  • [node]把静态html挂到node接口下
    主要适用于同网段下不同设备查看同一html。来自知乎。需要先安装一个node,安装过程不表。 新建文件:nodeServer.jsvarexpress=require('express');varapp=expr......
  • ARP 缓存
    我们知道,网络层使用的是IP地址,而在实际网络的链路上传送数据帧时,最终还是必须使用链路层的MAC地址。所以,在链路上传送数据帧时只知道IP地址是不够的,我们还需要知道主......
  • 数据库和缓存的一致性如何保证
    最近帮组里做讲座预约系统,虽然使用人数不多,但终于还是遇到了一些系统经典问题,比如数据库与缓存的一致性问题,很有意思,好记性不如烂笔头,学习了一些思路以后决定记录下来与大......
  • 怎么保证缓存与数据库的双写一致性?
    分布式缓存是现在很多分布式应用中必不可少的组件,但是用到了分布式缓存,就可能会涉及到缓存与数据库双存储双写,你只要是双写,就一定会有数据一致性的问题,那么如何解决一致性问......
  • 【Vue】vue | node | 获取配置文件的变量 | 获取VUE_APP_BASE_API | 获取.env.develop
    一、说明        1、vue页面中有时候需要获取后端的服务地址        2、后端地址一般通过配置文件区分环境,不同的环境地址不同(变量名相同)        3......
  • vue无限滚动加载
    vue无限滚动加载1、使用防抖完成无限加载exportdefault{data(){return{menuList:{},time:null,page:1,loading:true,......
  • Go加载依赖包命令
     gopath环境变量修改有时默认gopath可能在C盘,重装系统后,下载的包会丢失,这时我们执行命令,修改到其它盘即可setgopath=D:\code\go创建项目时,最好将项目放......
  • CDN加速WordPress触发CORS导致跨域加载失败
    这两天折腾​​CDN加速​​​来提升自己博客的访问速度,用的阿里云​​CDN加速​​方案;使用的时候发现一个问题,部分资源CDN加速失败,原因是触发了CORS,因为CDN加速网址与博客......
  • 管理node版本工具 n
    安装sudonpmi-gn查看本地使用n安装的node版本nls查看本地所有node版本nls-remotelts查看远程最近20个版本nls-remote查看全部版本nls-remote-......